spelling: fix misspellings
[gpgme.git] / lang / python / doc / texinfo / gpgme-python-howto.texi
1 \input texinfo    @c -*- texinfo -*-
2 @c %**start of header
3 @setfilename gpgme-python-howto.info
4 @settitle GNU Privacy Guard (GnuPG) Made Easy Python Bindings HOWTO (English)
5 @documentencoding UTF-8
6 @documentlanguage en
7 @c %**end of header
8
9 @finalout
10 @titlepage
11 @title GNU Privacy Guard (GnuPG) Made Easy Python Bindings HOWTO (English)
12 @author Ben McGinnes
13 @end titlepage
14
15 @contents
16
17 @ifnottex
18 @node Top
19 @top GNU Privacy Guard (GnuPG) Made Easy Python Bindings HOWTO (English)
20 @end ifnottex
21
22 @menu
23 * Introduction::
24 * GPGME Concepts::
25 * GPGME Python bindings installation::
26 * Fundamentals::
27 * Working with keys::
28 * Basic Functions::
29 * Creating keys and subkeys::
30 * Advanced or Experimental Use Cases::
31 * Miscellaneous extras and work-arounds::
32 * Copyright and Licensing::
33
34 @detailmenu
35 --- The Detailed Node Listing ---
36
37 Introduction
38
39 * Python 2 versus Python 3::
40 * Examples::
41 * Unofficial Drafts::
42 * What's New::
43
44 What's New
45
46 * New in GPGME 1·13·0::
47 * New in GPGME 1·12·0::
48
49 GPGME Concepts
50
51 * A C API::
52 * Python bindings::
53 * Difference between the Python bindings and other GnuPG Python packages::
54
55 Difference between the Python bindings and other GnuPG Python packages
56
57 * The python-gnupg package maintained by Vinay Sajip::
58 * The gnupg package created and maintained by Isis Lovecruft::
59 * The PyME package maintained by Martin Albrecht::
60
61 GPGME Python bindings installation
62
63 * No PyPI::
64 * Requirements::
65 * Installation::
66 * Known Issues::
67
68 Requirements
69
70 * Recommended Additions::
71
72 Installation
73
74 * Installing GPGME::
75
76 Known Issues
77
78 * Breaking Builds::
79 * Reinstalling Responsibly::
80 * Multiple installations::
81 * Won't Work With Windows::
82 * CFFI is the Best™ and GPGME should use it instead of SWIG::
83 * Virtualised Environments::
84
85 Fundamentals
86
87 * No REST::
88 * Context::
89
90 Working with keys
91
92 * Key selection::
93 * Get key::
94 * Importing keys::
95 * Exporting keys::
96
97 Key selection
98
99 * Counting keys::
100
101 Importing keys
102
103 * Working with ProtonMail::
104 * Importing with HKP for Python::
105 * Importing from ProtonMail with HKP for Python::
106
107 Exporting keys
108
109 * Exporting public keys::
110 * Exporting secret keys::
111 * Sending public keys to the SKS Keyservers::
112
113 Basic Functions
114
115 * Encryption::
116 * Decryption::
117 * Signing text and files::
118 * Signature verification::
119
120 Encryption
121
122 * Encrypting to one key::
123 * Encrypting to multiple keys::
124
125 Signing text and files
126
127 * Signing key selection::
128 * Normal or default signing messages or files::
129 * Detached signing messages and files::
130 * Clearsigning messages or text::
131
132 Creating keys and subkeys
133
134 * Primary key::
135 * Subkeys::
136 * User IDs::
137 * Key certification::
138
139 User IDs
140
141 * Adding User IDs::
142 * Revoking User IDs::
143
144 Advanced or Experimental Use Cases
145
146 * C plus Python plus SWIG plus Cython::
147
148 Miscellaneous extras and work-arounds
149
150 * Group lines::
151 * Keyserver access for Python::
152
153 Keyserver access for Python
154
155 * Key import format::
156
157 Copyright and Licensing
158
159 * Copyright::
160 * Draft Editions of this HOWTO::
161 * License GPL compatible::
162
163 @end detailmenu
164 @end menu
165
166 @node Introduction
167 @chapter Introduction
168
169 @multitable {aaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}
170 @item Version:
171 @tab 0.1.4
172 @item GPGME Version:
173 @tab 1.12.0
174 @item Author:
175 @tab @uref{https://gnupg.org/people/index.html#sec-1-5, Ben McGinnes} <ben@@gnupg.org>
176 @item Author GPG Key:
177 @tab DB4724E6FA4286C92B4E55C4321E4E2373590E5D
178 @item Language:
179 @tab Australian English, British English
180 @item xml:lang:
181 @tab en-AU, en-GB, en
182 @end multitable
183
184 This document provides basic instruction in how to use the GPGME
185 Python bindings to programmatically leverage the GPGME library.
186
187 @menu
188 * Python 2 versus Python 3::
189 * Examples::
190 * Unofficial Drafts::
191 * What's New::
192 @end menu
193
194 @node Python 2 versus Python 3
195 @section Python 2 versus Python 3
196
197 Though the GPGME Python bindings themselves provide support for both
198 Python 2 and 3, the focus is unequivocally on Python 3 and
199 specifically from Python 3.4 and above.  As a consequence all the
200 examples and instructions in this guide use Python 3 code.
201
202 Much of it will work with Python 2, but much of it also deals with
203 Python 3 byte literals, particularly when reading and writing data.
204 Developers concentrating on Python 2.7, and possibly even 2.6, will
205 need to make the appropriate modifications to support the older string
206 and unicode types as opposed to bytes.
207
208 There are multiple reasons for concentrating on Python 3; some of
209 which relate to the immediate integration of these bindings, some of
210 which relate to longer term plans for both GPGME and the python
211 bindings and some of which relate to the impending EOL period for
212 Python 2.7.  Essentially, though, there is little value in tying the
213 bindings to a version of the language which is a dead end and the
214 advantages offered by Python 3 over Python 2 make handling the data
215 types with which GPGME deals considerably easier.
216
217 @node Examples
218 @section Examples
219
220 All of the examples found in this document can be found as Python 3
221 scripts in the @samp{lang/python/examples/howto} directory.
222
223 @node Unofficial Drafts
224 @section Unofficial Drafts
225
226 In addition to shipping with each release of GPGME, there is a section
227 on locations to read or download @ref{Draft Editions of this HOWTO, , draft editions} of this document from
228 at the end of it.  These are unofficial versions produced in between
229 major releases.
230
231 @node What's New
232 @section What's New
233
234 Full details of what is new are now available in the @uref{what-is-new.org, What's New} file
235 and archives of the preceding @emph{What's New} sections are available in
236 the @uref{what-was-new, What Was New} file.
237
238 @menu
239 * New in GPGME 1·13·0::
240 * New in GPGME 1·12·0::
241 @end menu
242
243 @node New in GPGME 1·13·0
244 @subsection New in GPGME 1·13·0
245
246 See the @uref{what-is-new#new-stuff-1-13-0, What's New} document for what is new in version 1.13.0.
247
248 @node New in GPGME 1·12·0
249 @subsection New in GPGME 1·12·0
250
251 See the @uref{what-was-new#new-stuff-1-12-0, What Was New} document for what was new in version 1.12.0.
252
253 @node GPGME Concepts
254 @chapter GPGME Concepts
255
256 @menu
257 * A C API::
258 * Python bindings::
259 * Difference between the Python bindings and other GnuPG Python packages::
260 @end menu
261
262 @node A C API
263 @section A C API
264
265 Unlike many modern APIs with which programmers will be more familiar
266 with these days, the GPGME API is a C API.  The API is intended for
267 use by C coders who would be able to access its features by including
268 the @samp{gpgme.h} header file with their own C source code and then access
269 its functions just as they would any other C headers.
270
271 This is a very effective method of gaining complete access to the API
272 and in the most efficient manner possible.  It does, however, have the
273 drawback that it cannot be directly used by other languages without
274 some means of providing an interface to those languages.  This is
275 where the need for bindings in various languages stems.
276
277 @node Python bindings
278 @section Python bindings
279
280 The Python bindings for GPGME provide a higher level means of
281 accessing the complete feature set of GPGME itself.  It also provides
282 a more pythonic means of calling these API functions.
283
284 The bindings are generated dynamically with SWIG and the copy of
285 @samp{gpgme.h} generated when GPGME is compiled.
286
287 This means that a version of the Python bindings is fundamentally tied
288 to the exact same version of GPGME used to generate that copy of
289 @samp{gpgme.h}.
290
291 @node Difference between the Python bindings and other GnuPG Python packages
292 @section Difference between the Python bindings and other GnuPG Python packages
293
294 There have been numerous attempts to add GnuPG support to Python over
295 the years.  Some of the most well known are listed here, along with
296 what differentiates them.
297
298 @menu
299 * The python-gnupg package maintained by Vinay Sajip::
300 * The gnupg package created and maintained by Isis Lovecruft::
301 * The PyME package maintained by Martin Albrecht::
302 @end menu
303
304 @node The python-gnupg package maintained by Vinay Sajip
305 @subsection The python-gnupg package maintained by Vinay Sajip
306
307 This is arguably the most popular means of integrating GPG with
308 Python.  The package utilises the @samp{subprocess} module to implement
309 wrappers for the @samp{gpg} and @samp{gpg2} executables normally invoked on the
310 command line (@samp{gpg.exe} and @samp{gpg2.exe} on Windows).
311
312 The popularity of this package stemmed from its ease of use and
313 capability in providing the most commonly required features.
314
315 Unfortunately it has been beset by a number of security issues in the
316 past; most of which stemmed from using unsafe methods of accessing the
317 command line via the @samp{subprocess} calls.  While some effort has been
318 made over the last two to three years (as of 2018) to mitigate this,
319 particularly by no longer providing shell access through those
320 subprocess calls, the wrapper is still somewhat limited in the scope
321 of its GnuPG features coverage.
322
323 The python-gnupg package is available under the MIT license.
324
325 @node The gnupg package created and maintained by Isis Lovecruft
326 @subsection The gnupg package created and maintained by Isis Lovecruft
327
328 In 2015 Isis Lovecruft from the Tor Project forked and then
329 re-implemented the python-gnupg package as just gnupg.  This new
330 package also relied on subprocess to call the @samp{gpg} or @samp{gpg2}
331 binaries, but did so somewhat more securely.
332
333 The naming and version numbering selected for this package, however,
334 resulted in conflicts with the original python-gnupg and since its
335 functions were called in a different manner to python-gnupg, the
336 release of this package also resulted in a great deal of consternation
337 when people installed what they thought was an upgrade that
338 subsequently broke the code relying on it.
339
340 The gnupg package is available under the GNU General Public License
341 version 3.0 (or any later version).
342
343 @node The PyME package maintained by Martin Albrecht
344 @subsection The PyME package maintained by Martin Albrecht
345
346 This package is the origin of these bindings, though they are somewhat
347 different now.  For details of when and how the PyME package was
348 folded back into GPGME itself see the @uref{short-history.org, Short History} document.@footnote{@samp{short-history} and/or @samp{short-history.html}.}
349
350 The PyME package was first released in 2002 and was also the first
351 attempt to implement a low level binding to GPGME.  In doing so it
352 provided access to considerably more functionality than either the
353 @samp{python-gnupg} or @samp{gnupg} packages.
354
355 The PyME package is only available for Python 2.6 and 2.7.
356
357 Porting the PyME package to Python 3.4 in 2015 is what resulted in it
358 being folded into the GPGME project and the current bindings are the
359 end result of that effort.
360
361 The PyME package is available under the same dual licensing as GPGME
362 itself: the GNU General Public License version 2.0 (or any later
363 version) and the GNU Lesser General Public License version 2.1 (or any
364 later version).
365
366 @node GPGME Python bindings installation
367 @chapter GPGME Python bindings installation
368
369 @menu
370 * No PyPI::
371 * Requirements::
372 * Installation::
373 * Known Issues::
374 @end menu
375
376 @node No PyPI
377 @section No PyPI
378
379 Most third-party Python packages and modules are available and
380 distributed through the Python Package Installer, known as PyPI.
381
382 Due to the nature of what these bindings are and how they work, it is
383 infeasible to install the GPGME Python bindings in the same way.
384
385 This is because the bindings use SWIG to dynamically generate C
386 bindings against @samp{gpgme.h} and @samp{gpgme.h} is generated from
387 @samp{gpgme.h.in} at compile time when GPGME is built from source.  Thus to
388 include a package in PyPI which actually built correctly would require
389 either statically built libraries for every architecture bundled with
390 it or a full implementation of C for each architecture.
391
392 See the additional notes regarding @ref{CFFI is the Best™ and GPGME should use it instead of SWIG, , CFFI and SWIG} at the end of this
393 section for further details.
394
395 @node Requirements
396 @section Requirements
397
398 The GPGME Python bindings only have three requirements:
399
400 @enumerate
401 @item
402 A suitable version of Python 2 or Python 3.  With Python 2 that
403 means CPython 2.7 and with Python 3 that means CPython 3.4 or
404 higher.
405 @item
406 @uref{https://www.swig.org, SWIG}.
407 @item
408 GPGME itself.  Which also means that all of GPGME's dependencies
409 must be installed too.
410 @end enumerate
411
412 @menu
413 * Recommended Additions::
414 @end menu
415
416 @node Recommended Additions
417 @subsection Recommended Additions
418
419 Though none of the following are absolute requirements, they are all
420 recommended for use with the Python bindings.  In some cases these
421 recommendations refer to which version(s) of CPython to use the
422 bindings with, while others refer to third party modules which provide
423 a significant advantage in some way.
424
425 @enumerate
426 @item
427 If possible, use Python 3 instead of 2.
428 @item
429 Favour a more recent version of Python since even 3.4 is due to
430 reach EOL soon.  In production systems and services, Python 3.6
431 should be robust enough to be relied on.
432 @item
433 If possible add the following Python modules which are not part of
434 the standard library: @uref{http://docs.python-requests.org/en/latest/index.html, Requests}, @uref{https://cython.org/, Cython} and @uref{https://github.com/Selfnet/hkp4py, hkp4py}.  Chances are
435 quite high that at least the first one and maybe two of those will
436 already be installed.
437 @end enumerate
438
439 Note that, as with Cython, some of the planned additions to the
440 @ref{Advanced or Experimental Use Cases, , Advanced} section, will bring with them additional requirements.  Most
441 of these will be fairly well known and commonly installed ones,
442 however, which are in many cases likely to have already been installed
443 on many systems or be familiar to Python programmers.
444
445 @node Installation
446 @section Installation
447
448 Installing the Python bindings is effectively achieved by compiling
449 and installing GPGME itself.
450
451 Once SWIG is installed with Python and all the dependencies for GPGME
452 are installed you only need to confirm that the version(s) of Python
453 you want the bindings installed for are in your @samp{$PATH}.
454
455 By default GPGME will attempt to install the bindings for the most
456 recent or highest version number of Python 2 and Python 3 it detects
457 in @samp{$PATH}.  It specifically checks for the @samp{python} and @samp{python3}
458 executables first and then checks for specific version numbers.
459
460 For Python 2 it checks for these executables in this order: @samp{python},
461 @samp{python2} and @samp{python2.7}.
462
463 For Python 3 it checks for these executables in this order: @samp{python3},
464  @samp{python3.7}, @samp{python3.6}, @samp{python3.5} and @samp{python3.4}.@footnote{With no issues reported specific to Python 3.7, the release of
465 Python 3.7.1 at around the same time as GPGME 1.12.0 and the testing
466 with Python 3.7.1rc1, there is no reason to delay moving 3.7 ahead of
467 3.6 now.  Production environments with more conservative requirements
468 will always enforce their own policies anyway and installation to each
469 supported minor release is quite possible too.}
470
471 On systems where @samp{python} is actually @samp{python3} and not @samp{python2} it
472 may be possible that @samp{python2} may be overlooked, but there have been
473 no reports of that actually occurring as yet.
474
475 In the three months or so since the release of Python 3.7.0 there has
476 been extensive testing and work with these bindings with no issues
477 specifically relating to the new version of Python or any of the new
478 features of either the language or the bindings.  This has also been
479 the case with Python 3.7.1rc1.  With that in mind and given the
480 release of Python 3.7.1 is scheduled for around the same time as GPGME
481 1.12.0, the order of preferred Python versions has been changed to
482 move Python 3.7 ahead of Python 3.6.
483
484 @menu
485 * Installing GPGME::
486 @end menu
487
488 @node Installing GPGME
489 @subsection Installing GPGME
490
491 See the GPGME @samp{README} file for details of how to install GPGME from
492 source.
493
494 @node Known Issues
495 @section Known Issues
496
497 There are a few known issues with the current build process and the
498 Python bindings.  For the most part these are easily addressed should
499 they be encountered.
500
501 @menu
502 * Breaking Builds::
503 * Reinstalling Responsibly::
504 * Multiple installations::
505 * Won't Work With Windows::
506 * CFFI is the Best™ and GPGME should use it instead of SWIG::
507 * Virtualised Environments::
508 @end menu
509
510 @node Breaking Builds
511 @subsection Breaking Builds
512
513 Occasionally when installing GPGME with the Python bindings included
514 it may be observed that the @samp{make} portion of that process induces a
515 large very number of warnings and, eventually errors which end that
516 part of the build process.  Yet following that with @samp{make check} and
517 @samp{make install} appears to work seamlessly.
518
519 The cause of this is related to the way SWIG needs to be called to
520 dynamically generate the C bindings for GPGME in the first place.  So
521 the entire process will always produce @samp{lang/python/python2-gpg/} and
522 @samp{lang/python/python3-gpg/} directories.  These should contain the
523 build output generated during compilation, including the complete
524 bindings and module installed into @samp{site-packages}.
525
526 Occasionally the errors in the early part or some other conflict
527 (e.g. not installing as @strong{@emph{root}} or @strong{@emph{su}}) may result in nothing
528 being installed to the relevant @samp{site-packages} directory and the
529 build directory missing a lot of expected files.  Even when this
530 occurs, the solution is actually quite simple and will always work.
531
532 That solution is simply to run the following commands as either the
533 @strong{root} user or prepended with @samp{sudo -H}@footnote{Yes, even if you use virtualenv with everything you do in
534 Python.  If you want to install this module as just your user account
535 then you will need to manually configure, compile and install the
536 @emph{entire} GnuPG stack as that user as well.  This includes libraries
537 which are not often installed that way.  It can be done and there are
538 circumstances under which it is worthwhile, but generally only on
539 POSIX systems which utilise single user mode (some even require it).} in the @samp{lang/python/}
540 directory:
541
542 @example
543 /path/to/pythonX.Y setup.py build
544 /path/to/pythonX.Y setup.py build
545 /path/to/pythonX.Y setup.py install
546 @end example
547
548 Yes, the build command does need to be run twice.  Yes, you still need
549 to run the potentially failing or incomplete steps during the
550 @samp{configure}, @samp{make} and @samp{make install} steps with installing GPGME.
551 This is because those steps generate a lot of essential files needed,
552 both by and in order to create, the bindings (including both the
553 @samp{setup.py} and @samp{gpgme.h} files).
554
555 @enumerate
556 @item
557 IMPORTANT Note
558
559
560 If specifying a selected number of languages to create bindings for,
561 try to leave Python last.  Currently the majority of the other
562 language bindings are also preceding Python of either version when
563 listed alphabetically and so that just happens by default currently.
564
565 If Python is set to precede one of the other languages then it is
566 possible that the errors described here may interrupt the build
567 process before generating bindings for those other languages.  In
568 these cases it may be preferable to configure all preferred language
569 bindings separately with alternative @samp{configure} steps for GPGME using
570 the @samp{--enable-languages=$LANGUAGE} option.
571 @end enumerate
572
573 @node Reinstalling Responsibly
574 @subsection Reinstalling Responsibly
575
576 Regardless of whether you're installing for one version of Python or
577 several, there will come a point where reinstallation is required.
578 With most Python module installations, the installed files go into the
579 relevant site-packages directory and are then forgotten about.  Then
580 the module is upgraded, the new files are copied over the old and
581 that's the end of the matter.
582
583 While the same is true of these bindings, there have been intermittent
584 issues observed on some platforms which have benefited significantly
585 from removing all the previous installations of the bindings before
586 installing the updated versions.
587
588 Removing the previous version(s) is simply a matter of changing to the
589 relevant @samp{site-packages} directory for the version of Python in
590 question and removing the @samp{gpg/} directory and any accompanying
591 egg-info files for that module.
592
593 In most cases this will require root or administration privileges on
594 the system, but the same is true of installing the module in the first
595 place.
596
597 @node Multiple installations
598 @subsection Multiple installations
599
600 For a variety of reasons it may be either necessary or just preferable
601 to install the bindings to alternative installed Python versions which
602 meet the requirements of these bindings.
603
604 On POSIX systems this will generally be most simply achieved by
605 running the manual installation commands (build, build, install) as
606 described in the previous section for each Python installation the
607 bindings need to be installed to.
608
609 As per the SWIG documentation: the compilers, libraries and runtime
610 used to build GPGME and the Python Bindings @strong{must} match those used to
611 compile Python itself, including the version number(s) (at least going
612 by major version numbers and probably minor numbers too).
613
614 On most POSIX systems, including OS X, this will very likely be the
615 case in most, if not all, cases.
616
617 Note that from GPGME @uref{https://dev.gnupg.org/rMff6ff616aea6f59b7f2ce1176492850ecdf3851e, 1.12.1} the default installation installs to each
618 version of Python it can find first.  That is that it will currently
619 install for the first copies of Python versions 2.7, 3.4, 3.5, 3.6,
620 3.7 and 3.8 (dev branch) that it finds.  Usually this will be in the
621 same prefix as GPGME itself, but is dictated by the @samp{$PATH} when the
622 installation is performed.  The above instructions can still be
623 performed on other python installations which the installer does not
624 find, including alternative prefixes.
625
626 @node Won't Work With Windows
627 @subsection Won't Work With Windows
628
629 There are semi-regular reports of Windows users having considerable
630 difficulty in installing and using the Python bindings at all.  Very
631 often, possibly even always, these reports come from Cygwin users
632 and/or MinGW users and/or Msys2 users.  Though not all of them have
633 been confirmed, it appears that these reports have also come from
634 people who installed Python using the Windows installer files from the
635 @uref{https://python.org, Python website} (i.e. mostly MSI installers, sometimes self-extracting
636 @samp{.exe} files).
637
638 The Windows versions of Python are not built using Cygwin, MinGW or
639 Msys2; they're built using Microsoft Visual Studio.  Furthermore the
640 version used is @emph{considerably} more advanced than the version which
641 MinGW obtained a small number of files from many years ago in order to
642 be able to compile anything at all.  Not only that, but there are
643 changes to the version of Visual Studio between some micro releases,
644 though that is is particularly the case with Python 2.7, since it has
645 been kept around far longer than it should have been.
646
647 There are two theoretical solutions to this issue:
648
649 @enumerate
650 @item
651 Compile and install the GnuPG stack, including GPGME and the
652 Python bibdings using the same version of Microsoft Visual Studio
653 used by the Python Foundation to compile the version of Python
654 installed.
655
656 If there are multiple versions of Python then this will need to be
657 done with each different version of Visual Studio used.
658
659 @item
660 Compile and install Python using the same tools used by choice,
661 such as MinGW or Msys2.
662 @end enumerate
663
664 Do @strong{not} use the official Windows installer for Python unless
665 following the first method.
666
667 In this type of situation it may even be for the best to accept that
668 there are less limitations on permissive software than free software
669 and simply opt to use a recent version of the Community Edition of
670 Microsoft Visual Studio to compile and build all of it, no matter
671 what.
672
673 Investigations into the extent or the limitations of this issue are
674 ongoing.
675
676 @node CFFI is the Best™ and GPGME should use it instead of SWIG
677 @subsection CFFI is the Best™ and GPGME should use it instead of SWIG
678
679 There are many reasons for favouring @uref{https://cffi.readthedocs.io/en/latest/overview.html, CFFI} and proponents of it are
680 quite happy to repeat these things as if all it would take to switch
681 from SWIG to CFFI is repeating that list as if it were a new concept.
682
683 The fact is that there are things which Python's CFFI implementation
684 cannot handle in the GPGME C code.  Beyond that there are features of
685 SWIG which are simply not available with CFFI at all.  SWIG generates
686 the bindings to Python using the @samp{gpgme.h} file, but that file is not
687 a single version shipped with each release, it too is generated when
688 GPGME is compiled.
689
690 CFFI is currently unable to adapt to such a potentially mutable
691 codebase.  If there were some means of applying SWIG's dynamic code
692 generation to produce the Python/CFFI API modes of accessing the GPGME
693 libraries (or the source source code directly), but such a thing does
694 not exist yet either and it currently appears that work is needed in
695 at least one of CFFI's dependencies before any of this can be
696 addressed.
697
698 So if you're a massive fan of CFFI; that's great, but if you want this
699 project to switch to CFFI then rather than just insisting that it
700 should, I'd suggest you volunteer to bring CFFI up to the level this
701 project needs.
702
703 If you're actually seriously considering doing so, then I'd suggest
704 taking the @samp{gpgme-tool.c} file in the GPGME @samp{src/} directory and
705 getting that to work with any of the CFFI API methods (not the ABI
706 methods, they'll work with pretty much anything).  When you start
707 running into trouble with "ifdefs" then you'll know what sort of
708 things are lacking.  That doesn't even take into account the amount of
709 work saved via SWIG's code generation techniques either.
710
711 @node Virtualised Environments
712 @subsection Virtualised Environments
713
714 It is fairly common practice amongst Python developers to, as much as
715 possible, use packages like virtualenv to keep various things that are
716 to be installed from interfering with each other.  Given how much of
717 the GPGME bindings is often at odds with the usual pythonic way of
718 doing things, it stands to reason that this would be called into
719 question too.
720
721 As it happens the answer as to whether or not the bindings can be used
722 with virtualenv, the answer is both yes and no.
723
724 In general we recommend installing to the relevant path and matching
725 prefix of GPGME itself.  Which means that when GPGME, and ideally the
726 rest of the GnuPG stack, is installed to a prefix like @samp{/usr/local} or
727 @samp{/opt/local} then the bindings would need to be installed to the main
728 Python installation and not a virtualised abstraction.  Attempts to
729 separate the two in the past have been known to cause weird and
730 intermittent errors ranging from minor annoyances to complete failures
731 in the build process.
732
733 As a consequence we only recommend building with and installing to the
734 main Python installations within the same prefix as GPGME is installed
735 to or which are found by GPGME's configuration stage immediately prior
736 to running the make commands.  Which is exactly what the compiling and
737 installing process of GPGME does by default.
738
739 Once that is done, however, it appears that a copy of the compiled
740 module may be installed into a virtualenv of the same major and minor
741 version matching the build.  Alternatively it is possible to utilise a
742 @samp{sites.pth} file in the @samp{site-packages/} directory of a virtualenv
743 installation, which links back to the system installations
744 corresponding directory in order to import anything installed system
745 wide.  This may or may not be appropriate on a case by case basis.
746
747 Though extensive testing of either of these options is not yet
748 complete, preliminary testing of them indicates that both are viable
749 as long as the main installation is complete.  Which means that
750 certain other options normally restricted to virtual environments are
751 also available, including integration with pythonic test suites
752 (e.g. @uref{https://docs.pytest.org/en/latest/index.html, pytest}) and other large projects.
753
754 That said, it is worth reiterating the warning regarding non-standard
755 installations.  If one were to attempt to install the bindings only to
756 a virtual environment without somehow also including the full GnuPG
757 stack (or enough of it as to include GPGME) then it is highly likely
758 that errors would be encountered at some point and more than a little
759 likely that the build process itself would break.
760
761 If a degree of separation from the main operating system is still
762 required in spite of these warnings, then consider other forms of
763 virtualisation.  Either a virtual machine (e.g. @uref{https://www.virtualbox.org/, VirtualBox}), a
764 hardware emulation layer (e.g. @uref{https://www.qemu.org/, QEMU}) or an application container
765 (e.g. @uref{https://www.docker.com/why-docker, Docker}).
766
767 Finally it should be noted that the limited tests conducted thus far
768 have been using the @samp{virtualenv} command in a new directory to create
769 the virtual python environment.  As opposed to the standard @samp{python3
770 -m venv} and it is possible that this will make a difference depending
771 on the system and version of Python in use.  Another option is to run
772 the command @samp{python3 -m virtualenv /path/to/install/virtual/thingy}
773 instead.
774
775 @node Fundamentals
776 @chapter Fundamentals
777
778 Before we can get to the fun stuff, there are a few matters regarding
779 GPGME's design which hold true whether you're dealing with the C code
780 directly or these Python bindings.
781
782 @menu
783 * No REST::
784 * Context::
785 @end menu
786
787 @node No REST
788 @section No REST
789
790 The first part of which is or will be fairly blatantly obvious upon
791 viewing the first example, but it's worth reiterating anyway.  That
792 being that this API is @emph{@strong{not}} a REST API.  Nor indeed could it ever
793 be one.
794
795 Most, if not all, Python programmers (and not just Python programmers)
796 know how easy it is to work with a RESTful API.  In fact they've
797 become so popular that many other APIs attempt to emulate REST-like
798 behaviour as much as they are able.  Right down to the use of JSON
799 formatted output to facilitate the use of their API without having to
800 retrain developers.
801
802 This API does not do that.  It would not be able to do that and also
803 provide access to the entire C API on which it's built.  It does,
804 however, provide a very pythonic interface on top of the direct
805 bindings and it's this pythonic layer that this HOWTO deals with.
806
807 @node Context
808 @section Context
809
810 One of the reasons which prevents this API from being RESTful is that
811 most operations require more than one instruction to the API to
812 perform the task.  Sure, there are certain functions which can be
813 performed simultaneously, particularly if the result known or strongly
814 anticipated (e.g. selecting and encrypting to a key known to be in the
815 public keybox).
816
817 There are many more, however, which cannot be manipulated so readily:
818 they must be performed in a specific sequence and the result of one
819 operation has a direct bearing on the outcome of subsequent
820 operations.  Not merely by generating an error either.
821
822 When dealing with this type of persistent state on the web, full of
823 both the RESTful and REST-like, it's most commonly referred to as a
824 session.  In GPGME, however, it is called a context and every
825 operation type has one.
826
827 @node Working with keys
828 @chapter Working with keys
829
830 @menu
831 * Key selection::
832 * Get key::
833 * Importing keys::
834 * Exporting keys::
835 @end menu
836
837 @node Key selection
838 @section Key selection
839
840 Selecting keys to encrypt to or to sign with will be a common
841 occurrence when working with GPGMe and the means available for doing
842 so are quite simple.
843
844 They do depend on utilising a Context; however once the data is
845 recorded in another variable, that Context does not need to be the
846 same one which subsequent operations are performed.
847
848 The easiest way to select a specific key is by searching for that
849 key's key ID or fingerprint, preferably the full fingerprint without
850 any spaces in it.  A long key ID will probably be okay, but is not
851 advised and short key IDs are already a problem with some being
852 generated to match specific patterns.  It does not matter whether the
853 pattern is upper or lower case.
854
855 So this is the best method:
856
857 @example
858 import gpg
859
860 k = gpg.Context().keylist(pattern="258E88DCBD3CD44D8E7AB43F6ECB6AF0DEADBEEF")
861 keys = list(k)
862 @end example
863
864 This is passable and very likely to be common:
865
866 @example
867 import gpg
868
869 k = gpg.Context().keylist(pattern="0x6ECB6AF0DEADBEEF")
870 keys = list(k)
871 @end example
872
873 And this is a really bad idea:
874
875 @example
876 import gpg
877
878 k = gpg.Context().keylist(pattern="0xDEADBEEF")
879 keys = list(k)
880 @end example
881
882 Alternatively it may be that the intention is to create a list of keys
883 which all match a particular search string.  For instance all the
884 addresses at a particular domain, like this:
885
886 @example
887 import gpg
888
889 ncsc = gpg.Context().keylist(pattern="ncsc.mil")
890 nsa = list(ncsc)
891 @end example
892
893 @menu
894 * Counting keys::
895 @end menu
896
897 @node Counting keys
898 @subsection Counting keys
899
900 Counting the number of keys in your public keybox (@samp{pubring.kbx}), the
901 format which has superseded the old keyring format (@samp{pubring.gpg} and
902 @samp{secring.gpg}), or the number of secret keys is a very simple task.
903
904 @example
905 import gpg
906
907 c = gpg.Context()
908 seckeys = c.keylist(pattern=None, secret=True)
909 pubkeys = c.keylist(pattern=None, secret=False)
910
911 seclist = list(seckeys)
912 secnum = len(seclist)
913
914 publist = list(pubkeys)
915 pubnum = len(publist)
916
917 print("""
918   Number of secret keys:  @{0@}
919   Number of public keys:  @{1@}
920 """.format(secnum, pubnum))
921 @end example
922
923 NOTE: The @ref{C plus Python plus SWIG plus Cython, , Cython} introduction in the @ref{Advanced or Experimental Use Cases, , Advanced and Experimental}
924 section uses this same key counting code with Cython to demonstrate
925 some areas where Cython can improve performance even with the
926 bindings.  Users with large public keyrings or keyboxes, for instance,
927 should consider these options if they are comfortable with using
928 Cython.
929
930 @node Get key
931 @section Get key
932
933 An alternative method of getting a single key via its fingerprint is
934 available directly within a Context with @samp{Context().get_key}.  This is
935 the preferred method of selecting a key in order to modify it, sign or
936 certify it and for obtaining relevant data about a single key as a
937 part of other functions; when verifying a signature made by that key,
938 for instance.
939
940 By default this method will select public keys, but it can select
941 secret keys as well.
942
943 This first example demonstrates selecting the current key of Werner
944 Koch, which is due to expire at the end of 2018:
945
946 @example
947 import gpg
948
949 fingerprint = "80615870F5BAD690333686D0F2AD85AC1E42B367"
950 key = gpg.Context().get_key(fingerprint)
951 @end example
952
953 Whereas this example demonstrates selecting the author's current key
954 with the @samp{secret} key word argument set to @samp{True}:
955
956 @example
957 import gpg
958
959 fingerprint = "DB4724E6FA4286C92B4E55C4321E4E2373590E5D"
960 key = gpg.Context().get_key(fingerprint, secret=True)
961 @end example
962
963 It is, of course, quite possible to select expired, disabled and
964 revoked keys with this function, but only to effectively display
965 information about those keys.
966
967 It is also possible to use both unicode or string literals and byte
968 literals with the fingerprint when getting a key in this way.
969
970 @node Importing keys
971 @section Importing keys
972
973 Importing keys is possible with the @samp{key_import()} method and takes
974 one argument which is a bytes literal object containing either the
975 binary or ASCII armoured key data for one or more keys.
976
977 The following example retrieves one or more keys from the SKS
978 keyservers via the web using the requests module.  Since requests
979 returns the content as a bytes literal object, we can then use that
980 directly to import the resulting data into our keybox.
981
982 @example
983 import gpg
984 import os.path
985 import requests
986
987 c = gpg.Context()
988 url = "https://sks-keyservers.net/pks/lookup"
989 pattern = input("Enter the pattern to search for key or user IDs: ")
990 payload = @{"op": "get", "search": pattern@}
991
992 r = requests.get(url, verify=True, params=payload)
993 result = c.key_import(r.content)
994
995 if result is not None and hasattr(result, "considered") is False:
996     print(result)
997 elif result is not None and hasattr(result, "considered") is True:
998     num_keys = len(result.imports)
999     new_revs = result.new_revocations
1000     new_sigs = result.new_signatures
1001     new_subs = result.new_sub_keys
1002     new_uids = result.new_user_ids
1003     new_scrt = result.secret_imported
1004     nochange = result.unchanged
1005     print("""
1006   The total number of keys considered for import was:  @{0@}
1007
1008      Number of keys revoked:  @{1@}
1009    Number of new signatures:  @{2@}
1010       Number of new subkeys:  @{3@}
1011      Number of new user IDs:  @{4@}
1012   Number of new secret keys:  @{5@}
1013    Number of unchanged keys:  @{6@}
1014
1015   The key IDs for all considered keys were:
1016 """.format(num_keys, new_revs, new_sigs, new_subs, new_uids, new_scrt,
1017            nochange))
1018     for i in range(num_keys):
1019         print("@{0@}\n".format(result.imports[i].fpr))
1020 else:
1021     pass
1022 @end example
1023
1024 NOTE: When searching for a key ID of any length or a fingerprint
1025 (without spaces), the SKS servers require the the leading @samp{0x}
1026 indicative of hexadecimal be included.  Also note that the old short
1027 key IDs (e.g. @samp{0xDEADBEEF}) should no longer be used due to the
1028 relative ease by which such key IDs can be reproduced, as demonstrated
1029 by the Evil32 Project in 2014 (which was subsequently exploited in
1030 2016).
1031
1032 @menu
1033 * Working with ProtonMail::
1034 * Importing with HKP for Python::
1035 * Importing from ProtonMail with HKP for Python::
1036 @end menu
1037
1038 @node Working with ProtonMail
1039 @subsection Working with ProtonMail
1040
1041 Here is a variation on the example above which checks the constrained
1042 ProtonMail keyserver for ProtonMail public keys.
1043
1044 @example
1045 import gpg
1046 import requests
1047 import sys
1048
1049 print("""
1050 This script searches the ProtonMail key server for the specified key and
1051 imports it.
1052 """)
1053
1054 c = gpg.Context(armor=True)
1055 url = "https://api.protonmail.ch/pks/lookup"
1056 ksearch = []
1057
1058 if len(sys.argv) >= 2:
1059     keyterm = sys.argv[1]
1060 else:
1061     keyterm = input("Enter the key ID, UID or search string: ")
1062
1063 if keyterm.count("@@") == 2 and keyterm.startswith("@@") is True:
1064     ksearch.append(keyterm[1:])
1065     ksearch.append(keyterm[1:])
1066     ksearch.append(keyterm[1:])
1067 elif keyterm.count("@@") == 1 and keyterm.startswith("@@") is True:
1068     ksearch.append("@{0@}@@protonmail.com".format(keyterm[1:]))
1069     ksearch.append("@{0@}@@protonmail.ch".format(keyterm[1:]))
1070     ksearch.append("@{0@}@@pm.me".format(keyterm[1:]))
1071 elif keyterm.count("@@") == 0:
1072     ksearch.append("@{0@}@@protonmail.com".format(keyterm))
1073     ksearch.append("@{0@}@@protonmail.ch".format(keyterm))
1074     ksearch.append("@{0@}@@pm.me".format(keyterm))
1075 elif keyterm.count("@@") == 2 and keyterm.startswith("@@") is False:
1076     uidlist = keyterm.split("@@")
1077     for uid in uidlist:
1078         ksearch.append("@{0@}@@protonmail.com".format(uid))
1079         ksearch.append("@{0@}@@protonmail.ch".format(uid))
1080         ksearch.append("@{0@}@@pm.me".format(uid))
1081 elif keyterm.count("@@") > 2:
1082     uidlist = keyterm.split("@@")
1083     for uid in uidlist:
1084         ksearch.append("@{0@}@@protonmail.com".format(uid))
1085         ksearch.append("@{0@}@@protonmail.ch".format(uid))
1086         ksearch.append("@{0@}@@pm.me".format(uid))
1087 else:
1088     ksearch.append(keyterm)
1089
1090 for k in ksearch:
1091     payload = @{"op": "get", "search": k@}
1092     try:
1093         r = requests.get(url, verify=True, params=payload)
1094         if r.ok is True:
1095             result = c.key_import(r.content)
1096         elif r.ok is False:
1097             result = r.content
1098     except Exception as e:
1099         result = None
1100
1101     if result is not None and hasattr(result, "considered") is False:
1102         print("@{0@} for @{1@}".format(result.decode(), k))
1103     elif result is not None and hasattr(result, "considered") is True:
1104         num_keys = len(result.imports)
1105         new_revs = result.new_revocations
1106         new_sigs = result.new_signatures
1107         new_subs = result.new_sub_keys
1108         new_uids = result.new_user_ids
1109         new_scrt = result.secret_imported
1110         nochange = result.unchanged
1111         print("""
1112 The total number of keys considered for import was:  @{0@}
1113
1114 With UIDs wholely or partially matching the following string:
1115
1116         @{1@}
1117
1118    Number of keys revoked:  @{2@}
1119  Number of new signatures:  @{3@}
1120     Number of new subkeys:  @{4@}
1121    Number of new user IDs:  @{5@}
1122 Number of new secret keys:  @{6@}
1123  Number of unchanged keys:  @{7@}
1124
1125 The key IDs for all considered keys were:
1126 """.format(num_keys, k, new_revs, new_sigs, new_subs, new_uids, new_scrt,
1127            nochange))
1128         for i in range(num_keys):
1129             print(result.imports[i].fpr)
1130         print("")
1131     elif result is None:
1132         print(e)
1133 @end example
1134
1135 Both the above example, @uref{../examples/howto/pmkey-import.py, pmkey-import.py}, and a version which prompts
1136 for an alternative GnuPG home directory, @uref{../examples/howto/pmkey-import-alt.py, pmkey-import-alt.py}, are
1137 available with the other examples and are executable scripts.
1138
1139 Note that while the ProtonMail servers are based on the SKS servers,
1140 their server is related more to their API and is not feature complete
1141 by comparison to the servers in the SKS pool.  One notable difference
1142 being that the ProtonMail server does not permit non ProtonMail users
1143 to update their own keys, which could be a vector for attacking
1144 ProtonMail users who may not receive a key's revocation if it had been
1145 compromised.
1146
1147 @node Importing with HKP for Python
1148 @subsection Importing with HKP for Python
1149
1150 Performing the same tasks with the @uref{https://github.com/Selfnet/hkp4py, hkp4py module} (available via PyPI)
1151 is not too much different, but does provide a number of options of
1152 benefit to end users.  Not least of which being the ability to perform
1153 some checks on a key before importing it or not.  For instance it may
1154 be the policy of a site or project to only import keys which have not
1155 been revoked.  The hkp4py module permits such checks prior to the
1156 importing of the keys found.
1157
1158 @example
1159 import gpg
1160 import hkp4py
1161 import sys
1162
1163 c = gpg.Context()
1164 server = hkp4py.KeyServer("hkps://hkps.pool.sks-keyservers.net")
1165 results = []
1166
1167 if len(sys.argv) > 2:
1168     pattern = " ".join(sys.argv[1:])
1169 elif len(sys.argv) == 2:
1170     pattern = sys.argv[1]
1171 else:
1172     pattern = input("Enter the pattern to search for keys or user IDs: ")
1173
1174 try:
1175     keys = server.search(pattern)
1176     print("Found @{0@} key(s).".format(len(keys)))
1177 except Exception as e:
1178     keys = []
1179     for logrus in pattern.split():
1180         if logrus.startswith("0x") is True:
1181             key = server.search(logrus)
1182         else:
1183             key = server.search("0x@{0@}".format(logrus))
1184         keys.append(key[0])
1185     print("Found @{0@} key(s).".format(len(keys)))
1186
1187 for key in keys:
1188     import_result = c.key_import(key.key_blob)
1189     results.append(import_result)
1190
1191 for result in results:
1192     if result is not None and hasattr(result, "considered") is False:
1193         print(result)
1194     elif result is not None and hasattr(result, "considered") is True:
1195         num_keys = len(result.imports)
1196         new_revs = result.new_revocations
1197         new_sigs = result.new_signatures
1198         new_subs = result.new_sub_keys
1199         new_uids = result.new_user_ids
1200         new_scrt = result.secret_imported
1201         nochange = result.unchanged
1202         print("""
1203 The total number of keys considered for import was:  @{0@}
1204
1205    Number of keys revoked:  @{1@}
1206  Number of new signatures:  @{2@}
1207     Number of new subkeys:  @{3@}
1208    Number of new user IDs:  @{4@}
1209 Number of new secret keys:  @{5@}
1210  Number of unchanged keys:  @{6@}
1211
1212 The key IDs for all considered keys were:
1213 """.format(num_keys, new_revs, new_sigs, new_subs, new_uids, new_scrt,
1214            nochange))
1215         for i in range(num_keys):
1216             print(result.imports[i].fpr)
1217         print("")
1218     else:
1219         pass
1220 @end example
1221
1222 Since the hkp4py module handles multiple keys just as effectively as
1223 one (@samp{keys} is a list of responses per matching key), the example
1224 above is able to do a little bit more with the returned data before
1225 anything is actually imported.
1226
1227 @node Importing from ProtonMail with HKP for Python
1228 @subsection Importing from ProtonMail with HKP for Python
1229
1230 Though this can provide certain benefits even when working with
1231 ProtonMail, the scope is somewhat constrained there due to the
1232 limitations of the ProtonMail keyserver.
1233
1234 For instance, searching the SKS keyserver pool for the term "gnupg"
1235 produces hundreds of results from any time the word appears in any
1236 part of a user ID.  Performing the same search on the ProtonMail
1237 keyserver returns zero results, even though there are at least two
1238 test accounts which include it as part of the username.
1239
1240 The cause of this discrepancy is the deliberate configuration of that
1241 server by ProtonMail to require an exact match of the full email
1242 address of the ProtonMail user whose key is being requested.
1243 Presumably this is intended to reduce breaches of privacy of their
1244 users as an email address must already be known before a key for that
1245 address can be obtained.
1246
1247 @enumerate
1248 @item
1249 Import from ProtonMail via HKP for Python Example no. 1
1250
1251
1252 The following script is available with the rest of the examples under
1253 the somewhat less than original name, @samp{pmkey-import-hkp.py}.
1254
1255 @example
1256 import gpg
1257 import hkp4py
1258 import os.path
1259 import sys
1260
1261 print("""
1262 This script searches the ProtonMail key server for the specified key and
1263 imports it.
1264
1265 Usage:  pmkey-import-hkp.py [search strings]
1266 """)
1267
1268 c = gpg.Context(armor=True)
1269 server = hkp4py.KeyServer("hkps://api.protonmail.ch")
1270 keyterms = []
1271 ksearch = []
1272 allkeys = []
1273 results = []
1274 paradox = []
1275 homeless = None
1276
1277 if len(sys.argv) > 2:
1278     keyterms = sys.argv[1:]
1279 elif len(sys.argv) == 2:
1280     keyterm = sys.argv[1]
1281     keyterms.append(keyterm)
1282 else:
1283     key_term = input("Enter the key ID, UID or search string: ")
1284     keyterms = key_term.split()
1285
1286 for keyterm in keyterms:
1287     if keyterm.count("@@") == 2 and keyterm.startswith("@@") is True:
1288         ksearch.append(keyterm[1:])
1289         ksearch.append(keyterm[1:])
1290         ksearch.append(keyterm[1:])
1291     elif keyterm.count("@@") == 1 and keyterm.startswith("@@") is True:
1292         ksearch.append("@{0@}@@protonmail.com".format(keyterm[1:]))
1293         ksearch.append("@{0@}@@protonmail.ch".format(keyterm[1:]))
1294         ksearch.append("@{0@}@@pm.me".format(keyterm[1:]))
1295     elif keyterm.count("@@") == 0:
1296         ksearch.append("@{0@}@@protonmail.com".format(keyterm))
1297         ksearch.append("@{0@}@@protonmail.ch".format(keyterm))
1298         ksearch.append("@{0@}@@pm.me".format(keyterm))
1299     elif keyterm.count("@@") == 2 and keyterm.startswith("@@") is False:
1300         uidlist = keyterm.split("@@")
1301         for uid in uidlist:
1302             ksearch.append("@{0@}@@protonmail.com".format(uid))
1303             ksearch.append("@{0@}@@protonmail.ch".format(uid))
1304             ksearch.append("@{0@}@@pm.me".format(uid))
1305     elif keyterm.count("@@") > 2:
1306         uidlist = keyterm.split("@@")
1307         for uid in uidlist:
1308             ksearch.append("@{0@}@@protonmail.com".format(uid))
1309             ksearch.append("@{0@}@@protonmail.ch".format(uid))
1310             ksearch.append("@{0@}@@pm.me".format(uid))
1311     else:
1312         ksearch.append(keyterm)
1313
1314 for k in ksearch:
1315     print("Checking for key for: @{0@}".format(k))
1316     try:
1317         keys = server.search(k)
1318         if isinstance(keys, list) is True:
1319             for key in keys:
1320                 allkeys.append(key)
1321                 try:
1322                     import_result = c.key_import(key.key_blob)
1323                 except Exception as e:
1324                     import_result = c.key_import(key.key)
1325         else:
1326             paradox.append(keys)
1327             import_result = None
1328     except Exception as e:
1329         import_result = None
1330     results.append(import_result)
1331
1332 for result in results:
1333     if result is not None and hasattr(result, "considered") is False:
1334         print("@{0@} for @{1@}".format(result.decode(), k))
1335     elif result is not None and hasattr(result, "considered") is True:
1336         num_keys = len(result.imports)
1337         new_revs = result.new_revocations
1338         new_sigs = result.new_signatures
1339         new_subs = result.new_sub_keys
1340         new_uids = result.new_user_ids
1341         new_scrt = result.secret_imported
1342         nochange = result.unchanged
1343         print("""
1344 The total number of keys considered for import was:  @{0@}
1345
1346 With UIDs wholely or partially matching the following string:
1347
1348         @{1@}
1349
1350    Number of keys revoked:  @{2@}
1351  Number of new signatures:  @{3@}
1352     Number of new subkeys:  @{4@}
1353    Number of new user IDs:  @{5@}
1354 Number of new secret keys:  @{6@}
1355  Number of unchanged keys:  @{7@}
1356
1357 The key IDs for all considered keys were:
1358 """.format(num_keys, k, new_revs, new_sigs, new_subs, new_uids, new_scrt,
1359            nochange))
1360         for i in range(num_keys):
1361             print(result.imports[i].fpr)
1362         print("")
1363     elif result is None:
1364         pass
1365 @end example
1366
1367 @item
1368 Import from ProtonMail via HKP for Python Example no. 2
1369
1370
1371 Like its counterpart above, this script can also be found with the
1372 rest of the examples, by the name pmkey-import-hkp-alt.py.
1373
1374 With this script a modicum of effort has been made to treat anything
1375 passed as a @samp{homedir} which either does not exist or which is not a
1376 directory, as also being a pssible user ID to check for.  It's not
1377 guaranteed to pick up on all such cases, but it should cover most of
1378 them.
1379
1380 @example
1381 import gpg
1382 import hkp4py
1383 import os.path
1384 import sys
1385
1386 print("""
1387 This script searches the ProtonMail key server for the specified key and
1388 imports it.  Optionally enables specifying a different GnuPG home directory.
1389
1390 Usage:  pmkey-import-hkp.py [homedir] [search string]
1391    or:  pmkey-import-hkp.py [search string]
1392 """)
1393
1394 c = gpg.Context(armor=True)
1395 server = hkp4py.KeyServer("hkps://api.protonmail.ch")
1396 keyterms = []
1397 ksearch = []
1398 allkeys = []
1399 results = []
1400 paradox = []
1401 homeless = None
1402
1403 if len(sys.argv) > 3:
1404     homedir = sys.argv[1]
1405     keyterms = sys.argv[2:]
1406 elif len(sys.argv) == 3:
1407     homedir = sys.argv[1]
1408     keyterm = sys.argv[2]
1409     keyterms.append(keyterm)
1410 elif len(sys.argv) == 2:
1411     homedir = ""
1412     keyterm = sys.argv[1]
1413     keyterms.append(keyterm)
1414 else:
1415     keyterm = input("Enter the key ID, UID or search string: ")
1416     homedir = input("Enter the GPG configuration directory path (optional): ")
1417     keyterms.append(keyterm)
1418
1419 if len(homedir) == 0:
1420     homedir = None
1421     homeless = False
1422
1423 if homedir is not None:
1424     if homedir.startswith("~"):
1425         if os.path.exists(os.path.expanduser(homedir)) is True:
1426             if os.path.isdir(os.path.expanduser(homedir)) is True:
1427                 c.home_dir = os.path.realpath(os.path.expanduser(homedir))
1428             else:
1429                 homeless = True
1430         else:
1431             homeless = True
1432     elif os.path.exists(os.path.realpath(homedir)) is True:
1433         if os.path.isdir(os.path.realpath(homedir)) is True:
1434             c.home_dir = os.path.realpath(homedir)
1435         else:
1436             homeless = True
1437     else:
1438         homeless = True
1439
1440 # First check to see if the homedir really is a homedir and if not, treat it as
1441 # a search string.
1442 if homeless is True:
1443     keyterms.append(homedir)
1444     c.home_dir = None
1445 else:
1446     pass
1447
1448 for keyterm in keyterms:
1449     if keyterm.count("@@") == 2 and keyterm.startswith("@@") is True:
1450         ksearch.append(keyterm[1:])
1451         ksearch.append(keyterm[1:])
1452         ksearch.append(keyterm[1:])
1453     elif keyterm.count("@@") == 1 and keyterm.startswith("@@") is True:
1454         ksearch.append("@{0@}@@protonmail.com".format(keyterm[1:]))
1455         ksearch.append("@{0@}@@protonmail.ch".format(keyterm[1:]))
1456         ksearch.append("@{0@}@@pm.me".format(keyterm[1:]))
1457     elif keyterm.count("@@") == 0:
1458         ksearch.append("@{0@}@@protonmail.com".format(keyterm))
1459         ksearch.append("@{0@}@@protonmail.ch".format(keyterm))
1460         ksearch.append("@{0@}@@pm.me".format(keyterm))
1461     elif keyterm.count("@@") == 2 and keyterm.startswith("@@") is False:
1462         uidlist = keyterm.split("@@")
1463         for uid in uidlist:
1464             ksearch.append("@{0@}@@protonmail.com".format(uid))
1465             ksearch.append("@{0@}@@protonmail.ch".format(uid))
1466             ksearch.append("@{0@}@@pm.me".format(uid))
1467     elif keyterm.count("@@") > 2:
1468         uidlist = keyterm.split("@@")
1469         for uid in uidlist:
1470             ksearch.append("@{0@}@@protonmail.com".format(uid))
1471             ksearch.append("@{0@}@@protonmail.ch".format(uid))
1472             ksearch.append("@{0@}@@pm.me".format(uid))
1473     else:
1474         ksearch.append(keyterm)
1475
1476 for k in ksearch:
1477     print("Checking for key for: @{0@}".format(k))
1478     try:
1479         keys = server.search(k)
1480         if isinstance(keys, list) is True:
1481             for key in keys:
1482                 allkeys.append(key)
1483                 try:
1484                     import_result = c.key_import(key.key_blob)
1485                 except Exception as e:
1486                     import_result = c.key_import(key.key)
1487         else:
1488             paradox.append(keys)
1489             import_result = None
1490     except Exception as e:
1491         import_result = None
1492     results.append(import_result)
1493
1494 for result in results:
1495     if result is not None and hasattr(result, "considered") is False:
1496         print("@{0@} for @{1@}".format(result.decode(), k))
1497     elif result is not None and hasattr(result, "considered") is True:
1498         num_keys = len(result.imports)
1499         new_revs = result.new_revocations
1500         new_sigs = result.new_signatures
1501         new_subs = result.new_sub_keys
1502         new_uids = result.new_user_ids
1503         new_scrt = result.secret_imported
1504         nochange = result.unchanged
1505         print("""
1506 The total number of keys considered for import was:  @{0@}
1507
1508 With UIDs wholely or partially matching the following string:
1509
1510         @{1@}
1511
1512    Number of keys revoked:  @{2@}
1513  Number of new signatures:  @{3@}
1514     Number of new subkeys:  @{4@}
1515    Number of new user IDs:  @{5@}
1516 Number of new secret keys:  @{6@}
1517  Number of unchanged keys:  @{7@}
1518
1519 The key IDs for all considered keys were:
1520 """.format(num_keys, k, new_revs, new_sigs, new_subs, new_uids, new_scrt,
1521            nochange))
1522         for i in range(num_keys):
1523             print(result.imports[i].fpr)
1524         print("")
1525     elif result is None:
1526         pass
1527 @end example
1528 @end enumerate
1529
1530 @node Exporting keys
1531 @section Exporting keys
1532
1533 Exporting keys remains a reasonably simple task, but has been
1534 separated into three different functions for the OpenPGP cryptographic
1535 engine.  Two of those functions are for exporting public keys and the
1536 third is for exporting secret keys.
1537
1538 @menu
1539 * Exporting public keys::
1540 * Exporting secret keys::
1541 * Sending public keys to the SKS Keyservers::
1542 @end menu
1543
1544 @node Exporting public keys
1545 @subsection Exporting public keys
1546
1547 There are two methods of exporting public keys, both of which are very
1548 similar to the other.  The default method, @samp{key_export()}, will export
1549 a public key or keys matching a specified pattern as normal.  The
1550 alternative, the @samp{key_export_minimal()} method, will do the same thing
1551 except producing a minimised output with extra signatures and third
1552 party signatures or certifications removed.
1553
1554 @example
1555 import gpg
1556 import os.path
1557 import sys
1558
1559 print("""
1560 This script exports one or more public keys.
1561 """)
1562
1563 c = gpg.Context(armor=True)
1564
1565 if len(sys.argv) >= 4:
1566     keyfile = sys.argv[1]
1567     logrus = sys.argv[2]
1568     homedir = sys.argv[3]
1569 elif len(sys.argv) == 3:
1570     keyfile = sys.argv[1]
1571     logrus = sys.argv[2]
1572     homedir = input("Enter the GPG configuration directory path (optional): ")
1573 elif len(sys.argv) == 2:
1574     keyfile = sys.argv[1]
1575     logrus = input("Enter the UID matching the key(s) to export: ")
1576     homedir = input("Enter the GPG configuration directory path (optional): ")
1577 else:
1578     keyfile = input("Enter the path and filename to save the secret key to: ")
1579     logrus = input("Enter the UID matching the key(s) to export: ")
1580     homedir = input("Enter the GPG configuration directory path (optional): ")
1581
1582 if homedir.startswith("~"):
1583     if os.path.exists(os.path.expanduser(homedir)) is True:
1584         c.home_dir = os.path.expanduser(homedir)
1585     else:
1586         pass
1587 elif os.path.exists(homedir) is True:
1588     c.home_dir = homedir
1589 else:
1590     pass
1591
1592 try:
1593     result = c.key_export(pattern=logrus)
1594 except:
1595     result = c.key_export(pattern=None)
1596
1597 if result is not None:
1598     with open(keyfile, "wb") as f:
1599         f.write(result)
1600 else:
1601     pass
1602 @end example
1603
1604 It should be noted that the result will only return @samp{None} when a
1605 search pattern has been entered, but has not matched any keys.  When
1606 the search pattern itself is set to @samp{None} this triggers the exporting
1607 of the entire public keybox.
1608
1609 @example
1610 import gpg
1611 import os.path
1612 import sys
1613
1614 print("""
1615 This script exports one or more public keys in minimised form.
1616 """)
1617
1618 c = gpg.Context(armor=True)
1619
1620 if len(sys.argv) >= 4:
1621     keyfile = sys.argv[1]
1622     logrus = sys.argv[2]
1623     homedir = sys.argv[3]
1624 elif len(sys.argv) == 3:
1625     keyfile = sys.argv[1]
1626     logrus = sys.argv[2]
1627     homedir = input("Enter the GPG configuration directory path (optional): ")
1628 elif len(sys.argv) == 2:
1629     keyfile = sys.argv[1]
1630     logrus = input("Enter the UID matching the key(s) to export: ")
1631     homedir = input("Enter the GPG configuration directory path (optional): ")
1632 else:
1633     keyfile = input("Enter the path and filename to save the secret key to: ")
1634     logrus = input("Enter the UID matching the key(s) to export: ")
1635     homedir = input("Enter the GPG configuration directory path (optional): ")
1636
1637 if homedir.startswith("~"):
1638     if os.path.exists(os.path.expanduser(homedir)) is True:
1639         c.home_dir = os.path.expanduser(homedir)
1640     else:
1641         pass
1642 elif os.path.exists(homedir) is True:
1643     c.home_dir = homedir
1644 else:
1645     pass
1646
1647 try:
1648     result = c.key_export_minimal(pattern=logrus)
1649 except:
1650     result = c.key_export_minimal(pattern=None)
1651
1652 if result is not None:
1653     with open(keyfile, "wb") as f:
1654         f.write(result)
1655 else:
1656     pass
1657 @end example
1658
1659 @node Exporting secret keys
1660 @subsection Exporting secret keys
1661
1662 Exporting secret keys is, functionally, very similar to exporting
1663 public keys; save for the invocation of @samp{pinentry} via @samp{gpg-agent} in
1664 order to securely enter the key's passphrase and authorise the export.
1665
1666 The following example exports the secret key to a file which is then
1667 set with the same permissions as the output files created by the
1668 command line secret key export options.
1669
1670 @example
1671 import gpg
1672 import os
1673 import os.path
1674 import sys
1675
1676 print("""
1677 This script exports one or more secret keys.
1678
1679 The gpg-agent and pinentry are invoked to authorise the export.
1680 """)
1681
1682 c = gpg.Context(armor=True)
1683
1684 if len(sys.argv) >= 4:
1685     keyfile = sys.argv[1]
1686     logrus = sys.argv[2]
1687     homedir = sys.argv[3]
1688 elif len(sys.argv) == 3:
1689     keyfile = sys.argv[1]
1690     logrus = sys.argv[2]
1691     homedir = input("Enter the GPG configuration directory path (optional): ")
1692 elif len(sys.argv) == 2:
1693     keyfile = sys.argv[1]
1694     logrus = input("Enter the UID matching the secret key(s) to export: ")
1695     homedir = input("Enter the GPG configuration directory path (optional): ")
1696 else:
1697     keyfile = input("Enter the path and filename to save the secret key to: ")
1698     logrus = input("Enter the UID matching the secret key(s) to export: ")
1699     homedir = input("Enter the GPG configuration directory path (optional): ")
1700
1701 if len(homedir) == 0:
1702     homedir = None
1703 elif homedir.startswith("~"):
1704     userdir = os.path.expanduser(homedir)
1705     if os.path.exists(userdir) is True:
1706         homedir = os.path.realpath(userdir)
1707     else:
1708         homedir = None
1709 else:
1710     homedir = os.path.realpath(homedir)
1711
1712 if os.path.exists(homedir) is False:
1713     homedir = None
1714 else:
1715     if os.path.isdir(homedir) is False:
1716         homedir = None
1717     else:
1718         pass
1719
1720 if homedir is not None:
1721     c.home_dir = homedir
1722 else:
1723     pass
1724
1725 try:
1726     result = c.key_export_secret(pattern=logrus)
1727 except:
1728     result = c.key_export_secret(pattern=None)
1729
1730 if result is not None:
1731     with open(keyfile, "wb") as f:
1732         f.write(result)
1733     os.chmod(keyfile, 0o600)
1734 else:
1735     pass
1736 @end example
1737
1738 Alternatively the approach of the following script can be used.  This
1739 longer example saves the exported secret key(s) in files in the GnuPG
1740 home directory, in addition to setting the file permissions as only
1741 readable and writable by the user.  It also exports the secret key(s)
1742 twice in order to output both GPG binary (@samp{.gpg}) and ASCII armoured
1743 (@samp{.asc}) files.
1744
1745 @example
1746 import gpg
1747 import os
1748 import os.path
1749 import subprocess
1750 import sys
1751
1752 print("""
1753 This script exports one or more secret keys as both ASCII armored and binary
1754 file formats, saved in files within the user's GPG home directory.
1755
1756 The gpg-agent and pinentry are invoked to authorise the export.
1757 """)
1758
1759 if sys.platform == "win32":
1760     gpgconfcmd = "gpgconf.exe --list-dirs homedir"
1761 else:
1762     gpgconfcmd = "gpgconf --list-dirs homedir"
1763
1764 a = gpg.Context(armor=True)
1765 b = gpg.Context()
1766 c = gpg.Context()
1767
1768 if len(sys.argv) >= 4:
1769     keyfile = sys.argv[1]
1770     logrus = sys.argv[2]
1771     homedir = sys.argv[3]
1772 elif len(sys.argv) == 3:
1773     keyfile = sys.argv[1]
1774     logrus = sys.argv[2]
1775     homedir = input("Enter the GPG configuration directory path (optional): ")
1776 elif len(sys.argv) == 2:
1777     keyfile = sys.argv[1]
1778     logrus = input("Enter the UID matching the secret key(s) to export: ")
1779     homedir = input("Enter the GPG configuration directory path (optional): ")
1780 else:
1781     keyfile = input("Enter the filename to save the secret key to: ")
1782     logrus = input("Enter the UID matching the secret key(s) to export: ")
1783     homedir = input("Enter the GPG configuration directory path (optional): ")
1784
1785 if len(homedir) == 0:
1786     homedir = None
1787 elif homedir.startswith("~"):
1788     userdir = os.path.expanduser(homedir)
1789     if os.path.exists(userdir) is True:
1790         homedir = os.path.realpath(userdir)
1791     else:
1792         homedir = None
1793 else:
1794     homedir = os.path.realpath(homedir)
1795
1796 if os.path.exists(homedir) is False:
1797     homedir = None
1798 else:
1799     if os.path.isdir(homedir) is False:
1800         homedir = None
1801     else:
1802         pass
1803
1804 if homedir is not None:
1805     c.home_dir = homedir
1806 else:
1807     pass
1808
1809 if c.home_dir is not None:
1810     if c.home_dir.endswith("/"):
1811         gpgfile = "@{0@}@{1@}.gpg".format(c.home_dir, keyfile)
1812         ascfile = "@{0@}@{1@}.asc".format(c.home_dir, keyfile)
1813     else:
1814         gpgfile = "@{0@}/@{1@}.gpg".format(c.home_dir, keyfile)
1815         ascfile = "@{0@}/@{1@}.asc".format(c.home_dir, keyfile)
1816 else:
1817     if os.path.exists(os.environ["GNUPGHOME"]) is True:
1818         hd = os.environ["GNUPGHOME"]
1819     else:
1820         try:
1821             hd = subprocess.getoutput(gpgconfcmd)
1822         except:
1823             process = subprocess.Popen(gpgconfcmd.split(),
1824                                        stdout=subprocess.PIPE)
1825             procom = process.communicate()
1826             if sys.version_info[0] == 2:
1827                 hd = procom[0].strip()
1828             else:
1829                 hd = procom[0].decode().strip()
1830     gpgfile = "@{0@}/@{1@}.gpg".format(hd, keyfile)
1831     ascfile = "@{0@}/@{1@}.asc".format(hd, keyfile)
1832
1833 try:
1834     a_result = a.key_export_secret(pattern=logrus)
1835     b_result = b.key_export_secret(pattern=logrus)
1836 except:
1837     a_result = a.key_export_secret(pattern=None)
1838     b_result = b.key_export_secret(pattern=None)
1839
1840 if a_result is not None:
1841     with open(ascfile, "wb") as f:
1842         f.write(a_result)
1843     os.chmod(ascfile, 0o600)
1844 else:
1845     pass
1846
1847 if b_result is not None:
1848     with open(gpgfile, "wb") as f:
1849         f.write(b_result)
1850     os.chmod(gpgfile, 0o600)
1851 else:
1852     pass
1853 @end example
1854
1855 @node Sending public keys to the SKS Keyservers
1856 @subsection Sending public keys to the SKS Keyservers
1857
1858 As with the previous section on importing keys, the @samp{hkp4py} module
1859 adds another option with exporting keys in order to send them to the
1860 public keyservers.
1861
1862 The following example demonstrates how this may be done.
1863
1864 @example
1865 import gpg
1866 import hkp4py
1867 import os.path
1868 import sys
1869
1870 print("""
1871 This script sends one or more public keys to the SKS keyservers and is
1872 essentially a slight variation on the export-key.py script.
1873 """)
1874
1875 c = gpg.Context(armor=True)
1876 server = hkp4py.KeyServer("hkps://hkps.pool.sks-keyservers.net")
1877
1878 if len(sys.argv) > 2:
1879     logrus = " ".join(sys.argv[1:])
1880 elif len(sys.argv) == 2:
1881     logrus = sys.argv[1]
1882 else:
1883     logrus = input("Enter the UID matching the key(s) to send: ")
1884
1885 if len(logrus) > 0:
1886     try:
1887         export_result = c.key_export(pattern=logrus)
1888     except Exception as e:
1889         print(e)
1890         export_result = None
1891 else:
1892     export_result = c.key_export(pattern=None)
1893
1894 if export_result is not None:
1895     try:
1896         try:
1897             send_result = server.add(export_result)
1898         except:
1899             send_result = server.add(export_result.decode())
1900         if send_result is not None:
1901             print(send_result)
1902         else:
1903             pass
1904     except Exception as e:
1905         print(e)
1906 else:
1907     pass
1908 @end example
1909
1910 An expanded version of this script with additional functions for
1911 specifying an alternative homedir location is in the examples
1912 directory as @samp{send-key-to-keyserver.py}.
1913
1914 The @samp{hkp4py} module appears to handle both string and byte literal text
1915 data equally well, but the GPGME bindings deal primarily with byte
1916 literal data only and so this script sends in that format first, then
1917 tries the string literal form.
1918
1919 @node Basic Functions
1920 @chapter Basic Functions
1921
1922 The most frequently called features of any cryptographic library will
1923 be the most fundamental tasks for encryption software.  In this
1924 section we will look at how to programmatically encrypt data, decrypt
1925 it, sign it and verify signatures.
1926
1927 @menu
1928 * Encryption::
1929 * Decryption::
1930 * Signing text and files::
1931 * Signature verification::
1932 @end menu
1933
1934 @node Encryption
1935 @section Encryption
1936
1937 Encrypting is very straight forward.  In the first example below the
1938 message, @samp{text}, is encrypted to a single recipient's key.  In the
1939 second example the message will be encrypted to multiple recipients.
1940
1941 @menu
1942 * Encrypting to one key::
1943 * Encrypting to multiple keys::
1944 @end menu
1945
1946 @node Encrypting to one key
1947 @subsection Encrypting to one key
1948
1949 Once the the Context is set the main issues with encrypting data is
1950 essentially reduced to key selection and the keyword arguments
1951 specified in the @samp{gpg.Context().encrypt()} method.
1952
1953 Those keyword arguments are: @samp{recipients}, a list of keys encrypted to
1954 (covered in greater detail in the following section); @samp{sign}, whether
1955 or not to sign the plaintext data, see subsequent sections on signing
1956 and verifying signatures below (defaults to @samp{True}); @samp{sink}, to write
1957 results or partial results to a secure sink instead of returning it
1958 (defaults to @samp{None}); @samp{passphrase}, only used when utilising symmetric
1959 encryption (defaults to @samp{None}); @samp{always_trust}, used to override the
1960 trust model settings for recipient keys (defaults to @samp{False});
1961 @samp{add_encrypt_to}, utilises any preconfigured @samp{encrypt-to} or
1962 @samp{default-key} settings in the user's @samp{gpg.conf} file (defaults to
1963 @samp{False}); @samp{prepare}, prepare for encryption (defaults to @samp{False});
1964 @samp{expect_sign}, prepare for signing (defaults to @samp{False}); @samp{compress},
1965 compresses the plaintext prior to encryption (defaults to @samp{True}).
1966
1967 @example
1968 import gpg
1969
1970 a_key = "0x12345678DEADBEEF"
1971 text = b"""Some text to test with.
1972
1973 Since the text in this case must be bytes, it is most likely that
1974 the input form will be a separate file which is opened with "rb"
1975 as this is the simplest method of obtaining the correct data format.
1976 """
1977
1978 c = gpg.Context(armor=True)
1979 rkey = list(c.keylist(pattern=a_key, secret=False))
1980 ciphertext, result, sign_result = c.encrypt(text, recipients=rkey, sign=False)
1981
1982 with open("secret_plans.txt.asc", "wb") as afile:
1983     afile.write(ciphertext)
1984 @end example
1985
1986 Though this is even more likely to be used like this; with the
1987 plaintext input read from a file, the recipient keys used for
1988 encryption regardless of key trust status and the encrypted output
1989 also encrypted to any preconfigured keys set in the @samp{gpg.conf} file:
1990
1991 @example
1992 import gpg
1993
1994 a_key = "0x12345678DEADBEEF"
1995
1996 with open("secret_plans.txt", "rb") as afile:
1997     text = afile.read()
1998
1999 c = gpg.Context(armor=True)
2000 rkey = list(c.keylist(pattern=a_key, secret=False))
2001 ciphertext, result, sign_result = c.encrypt(text, recipients=rkey, sign=True,
2002                                             always_trust=True,
2003                                             add_encrypt_to=True)
2004
2005 with open("secret_plans.txt.asc", "wb") as afile:
2006     afile.write(ciphertext)
2007 @end example
2008
2009 If the @samp{recipients} parameter is empty then the plaintext is encrypted
2010 symmetrically.  If no @samp{passphrase} is supplied as a parameter or via a
2011 callback registered with the @samp{Context()} then an out-of-band prompt
2012 for the passphrase via pinentry will be invoked.
2013
2014 @node Encrypting to multiple keys
2015 @subsection Encrypting to multiple keys
2016
2017 Encrypting to multiple keys essentially just expands upon the key
2018 selection process and the recipients from the previous examples.
2019
2020 The following example encrypts a message (@samp{text}) to everyone with an
2021 email address on the @samp{gnupg.org} domain,@footnote{You probably don't really want to do this.  Searching the
2022 keyservers for "gnupg.org" produces over 400 results, the majority of
2023 which aren't actually at the gnupg.org domain, but just included a
2024 comment regarding the project in their key somewhere.} but does @emph{not} encrypt
2025 to a default key or other key which is configured to normally encrypt
2026 to.
2027
2028 @example
2029 import gpg
2030
2031 text = b"""Oh look, another test message.
2032
2033 The same rules apply as with the previous example and more likely
2034 than not, the message will actually be drawn from reading the
2035 contents of a file or, maybe, from entering data at an input()
2036 prompt.
2037
2038 Since the text in this case must be bytes, it is most likely that
2039 the input form will be a separate file which is opened with "rb"
2040 as this is the simplest method of obtaining the correct data
2041 format.
2042 """
2043
2044 c = gpg.Context(armor=True)
2045 rpattern = list(c.keylist(pattern="@@gnupg.org", secret=False))
2046 logrus = []
2047
2048 for i in range(len(rpattern)):
2049     if rpattern[i].can_encrypt == 1:
2050         logrus.append(rpattern[i])
2051
2052 ciphertext, result, sign_result = c.encrypt(text, recipients=logrus,
2053                                             sign=False, always_trust=True)
2054
2055 with open("secret_plans.txt.asc", "wb") as afile:
2056     afile.write(ciphertext)
2057 @end example
2058
2059 All it would take to change the above example to sign the message
2060 and also encrypt the message to any configured default keys would
2061 be to change the @samp{c.encrypt} line to this:
2062
2063 @example
2064 ciphertext, result, sign_result = c.encrypt(text, recipients=logrus,
2065                                             always_trust=True,
2066                                             add_encrypt_to=True)
2067 @end example
2068
2069 The only keyword arguments requiring modification are those for which
2070 the default values are changing.  The default value of @samp{sign} is
2071 @samp{True}, the default of @samp{always_trust} is @samp{False}, the default of
2072 @samp{add_encrypt_to} is @samp{False}.
2073
2074 If @samp{always_trust} is not set to @samp{True} and any of the recipient keys
2075 are not trusted (e.g. not signed or locally signed) then the
2076 encryption will raise an error.  It is possible to mitigate this
2077 somewhat with something more like this:
2078
2079 @example
2080 import gpg
2081
2082 with open("secret_plans.txt.asc", "rb") as afile:
2083     text = afile.read()
2084
2085 c = gpg.Context(armor=True)
2086 rpattern = list(c.keylist(pattern="@@gnupg.org", secret=False))
2087 logrus = []
2088
2089 for i in range(len(rpattern)):
2090     if rpattern[i].can_encrypt == 1:
2091         logrus.append(rpattern[i])
2092
2093     try:
2094         ciphertext, result, sign_result = c.encrypt(text, recipients=logrus,
2095                                                     add_encrypt_to=True)
2096     except gpg.errors.InvalidRecipients as e:
2097         for i in range(len(e.recipients)):
2098             for n in range(len(logrus)):
2099                 if logrus[n].fpr == e.recipients[i].fpr:
2100                     logrus.remove(logrus[n])
2101                 else:
2102                     pass
2103         try:
2104             ciphertext, result, sign_result = c.encrypt(text,
2105                                                         recipients=logrus,
2106                                                         add_encrypt_to=True)
2107             with open("secret_plans.txt.asc", "wb") as afile:
2108                 afile.write(ciphertext)
2109         except:
2110             pass
2111 @end example
2112
2113 This will attempt to encrypt to all the keys searched for, then remove
2114 invalid recipients if it fails and try again.
2115
2116 @node Decryption
2117 @section Decryption
2118
2119 Decrypting something encrypted to a key in one's secret keyring is
2120 fairly straight forward.
2121
2122 In this example code, however, preconfiguring either @samp{gpg.Context()}
2123 or @samp{gpg.core.Context()} as @samp{c} is unnecessary because there is no need
2124 to modify the Context prior to conducting the decryption and since the
2125 Context is only used once, setting it to @samp{c} simply adds lines for no
2126 gain.
2127
2128 @example
2129 import gpg
2130
2131 ciphertext = input("Enter path and filename of encrypted file: ")
2132 newfile = input("Enter path and filename of file to save decrypted data to: ")
2133
2134 with open(ciphertext, "rb") as cfile:
2135     try:
2136         plaintext, result, verify_result = gpg.Context().decrypt(cfile)
2137     except gpg.errors.GPGMEError as e:
2138         plaintext = None
2139         print(e)
2140
2141 if plaintext is not None:
2142     with open(newfile, "wb") as nfile:
2143             nfile.write(plaintext)
2144     else:
2145         pass
2146 @end example
2147
2148 The data available in @samp{plaintext} in this example is the decrypted
2149 content as a byte object, the recipient key IDs and algorithms in
2150 @samp{result} and the results of verifying any signatures of the data in
2151 @samp{verify_result}.
2152
2153 @node Signing text and files
2154 @section Signing text and files
2155
2156 The following sections demonstrate how to specify keys to sign with.
2157
2158 @menu
2159 * Signing key selection::
2160 * Normal or default signing messages or files::
2161 * Detached signing messages and files::
2162 * Clearsigning messages or text::
2163 @end menu
2164
2165 @node Signing key selection
2166 @subsection Signing key selection
2167
2168 By default GPGME and the Python bindings will use the default key
2169 configured for the user invoking the GPGME API.  If there is no
2170 default key specified and there is more than one secret key available
2171 it may be necessary to specify the key or keys with which to sign
2172 messages and files.
2173
2174 @example
2175 import gpg
2176
2177 logrus = input("Enter the email address or string to match signing keys to: ")
2178 hancock = gpg.Context().keylist(pattern=logrus, secret=True)
2179 sig_src = list(hancock)
2180 @end example
2181
2182 The signing examples in the following sections include the explicitly
2183 designated @samp{signers} parameter in two of the five examples; once where
2184 the resulting signature would be ASCII armoured and once where it
2185 would not be armoured.
2186
2187 While it would be possible to enter a key ID or fingerprint here to
2188 match a specific key, it is not possible to enter two fingerprints and
2189 match two keys since the patten expects a string, bytes or None and
2190 not a list.  A string with two fingerprints won't match any single
2191 key.
2192
2193 @node Normal or default signing messages or files
2194 @subsection Normal or default signing messages or files
2195
2196 The normal or default signing process is essentially the same as is
2197 most often invoked when also encrypting a message or file.  So when
2198 the encryption component is not utilised, the result is to produce an
2199 encoded and signed output which may or may not be ASCII armoured and
2200 which may or may not also be compressed.
2201
2202 By default compression will be used unless GnuPG detects that the
2203 plaintext is already compressed.  ASCII armouring will be determined
2204 according to the value of @samp{gpg.Context().armor}.
2205
2206 The compression algorithm is selected in much the same way as the
2207 symmetric encryption algorithm or the hash digest algorithm is when
2208 multiple keys are involved; from the preferences saved into the key
2209 itself or by comparison with the preferences with all other keys
2210 involved.
2211
2212 @example
2213 import gpg
2214
2215 text0 = """Declaration of ... something.
2216
2217 """
2218 text = text0.encode()
2219
2220 c = gpg.Context(armor=True, signers=sig_src)
2221 signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.NORMAL)
2222
2223 with open("/path/to/statement.txt.asc", "w") as afile:
2224     afile.write(signed_data.decode())
2225 @end example
2226
2227 Though everything in this example is accurate, it is more likely that
2228 reading the input data from another file and writing the result to a
2229 new file will be performed more like the way it is done in the next
2230 example.  Even if the output format is ASCII armoured.
2231
2232 @example
2233 import gpg
2234
2235 with open("/path/to/statement.txt", "rb") as tfile:
2236     text = tfile.read()
2237
2238 c = gpg.Context()
2239 signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.NORMAL)
2240
2241 with open("/path/to/statement.txt.sig", "wb") as afile:
2242     afile.write(signed_data)
2243 @end example
2244
2245 @node Detached signing messages and files
2246 @subsection Detached signing messages and files
2247
2248 Detached signatures will often be needed in programmatic uses of
2249 GPGME, either for signing files (e.g. tarballs of code releases) or as
2250 a component of message signing (e.g. PGP/MIME encoded email).
2251
2252 @example
2253 import gpg
2254
2255 text0 = """Declaration of ... something.
2256
2257 """
2258 text = text0.encode()
2259
2260 c = gpg.Context(armor=True)
2261 signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.DETACH)
2262
2263 with open("/path/to/statement.txt.asc", "w") as afile:
2264     afile.write(signed_data.decode())
2265 @end example
2266
2267 As with normal signatures, detached signatures are best handled as
2268 byte literals, even when the output is ASCII armoured.
2269
2270 @example
2271 import gpg
2272
2273 with open("/path/to/statement.txt", "rb") as tfile:
2274     text = tfile.read()
2275
2276 c = gpg.Context(signers=sig_src)
2277 signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.DETACH)
2278
2279 with open("/path/to/statement.txt.sig", "wb") as afile:
2280     afile.write(signed_data)
2281 @end example
2282
2283 @node Clearsigning messages or text
2284 @subsection Clearsigning messages or text
2285
2286 Though PGP/in-line messages are no longer encouraged in favour of
2287 PGP/MIME, there is still sometimes value in utilising in-line
2288 signatures.  This is where clear-signed messages or text is of value.
2289
2290 @example
2291 import gpg
2292
2293 text0 = """Declaration of ... something.
2294
2295 """
2296 text = text0.encode()
2297
2298 c = gpg.Context()
2299 signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.CLEAR)
2300
2301 with open("/path/to/statement.txt.asc", "w") as afile:
2302     afile.write(signed_data.decode())
2303 @end example
2304
2305 In spite of the appearance of a clear-signed message, the data handled
2306 by GPGME in signing it must still be byte literals.
2307
2308 @example
2309 import gpg
2310
2311 with open("/path/to/statement.txt", "rb") as tfile:
2312     text = tfile.read()
2313
2314 c = gpg.Context()
2315 signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.CLEAR)
2316
2317 with open("/path/to/statement.txt.asc", "wb") as afile:
2318     afile.write(signed_data)
2319 @end example
2320
2321 @node Signature verification
2322 @section Signature verification
2323
2324 Essentially there are two principal methods of verification of a
2325 signature.  The first of these is for use with the normal or default
2326 signing method and for clear-signed messages.  The second is for use
2327 with files and data with detached signatures.
2328
2329 The following example is intended for use with the default signing
2330 method where the file was not ASCII armoured:
2331
2332 @example
2333 import gpg
2334 import time
2335
2336 filename = "statement.txt"
2337 gpg_file = "statement.txt.gpg"
2338
2339 c = gpg.Context()
2340
2341 try:
2342     data, result = c.verify(open(gpg_file))
2343     verified = True
2344 except gpg.errors.BadSignatures as e:
2345     verified = False
2346     print(e)
2347
2348 if verified is True:
2349     for i in range(len(result.signatures)):
2350         sign = result.signatures[i]
2351         print("""Good signature from:
2352 @{0@}
2353 with key @{1@}
2354 made at @{2@}
2355 """.format(c.get_key(sign.fpr).uids[0].uid, sign.fpr,
2356            time.ctime(sign.timestamp)))
2357 else:
2358     pass
2359 @end example
2360
2361 Whereas this next example, which is almost identical would work with
2362 normal ASCII armoured files and with clear-signed files:
2363
2364 @example
2365 import gpg
2366 import time
2367
2368 filename = "statement.txt"
2369 asc_file = "statement.txt.asc"
2370
2371 c = gpg.Context()
2372
2373 try:
2374     data, result = c.verify(open(asc_file))
2375     verified = True
2376 except gpg.errors.BadSignatures as e:
2377     verified = False
2378     print(e)
2379
2380 if verified is True:
2381     for i in range(len(result.signatures)):
2382         sign = result.signatures[i]
2383         print("""Good signature from:
2384 @{0@}
2385 with key @{1@}
2386 made at @{2@}
2387 """.format(c.get_key(sign.fpr).uids[0].uid, sign.fpr,
2388            time.ctime(sign.timestamp)))
2389 else:
2390     pass
2391 @end example
2392
2393 In both of the previous examples it is also possible to compare the
2394 original data that was signed against the signed data in @samp{data} to see
2395 if it matches with something like this:
2396
2397 @example
2398 with open(filename, "rb") as afile:
2399     text = afile.read()
2400
2401 if text == data:
2402     print("Good signature.")
2403 else:
2404     pass
2405 @end example
2406
2407 The following two examples, however, deal with detached signatures.
2408 With his method of verification the data that was signed does not get
2409 returned since it is already being explicitly referenced in the first
2410 argument of @samp{c.verify}.  So @samp{data} is @samp{None} and only the information
2411 in @samp{result} is available.
2412
2413 @example
2414 import gpg
2415 import time
2416
2417 filename = "statement.txt"
2418 sig_file = "statement.txt.sig"
2419
2420 c = gpg.Context()
2421
2422 try:
2423     data, result = c.verify(open(filename), open(sig_file))
2424     verified = True
2425 except gpg.errors.BadSignatures as e:
2426     verified = False
2427     print(e)
2428
2429 if verified is True:
2430     for i in range(len(result.signatures)):
2431         sign = result.signatures[i]
2432         print("""Good signature from:
2433 @{0@}
2434 with key @{1@}
2435 made at @{2@}
2436 """.format(c.get_key(sign.fpr).uids[0].uid, sign.fpr,
2437            time.ctime(sign.timestamp)))
2438 else:
2439     pass
2440 @end example
2441
2442 @example
2443 import gpg
2444 import time
2445
2446 filename = "statement.txt"
2447 asc_file = "statement.txt.asc"
2448
2449 c = gpg.Context()
2450
2451 try:
2452     data, result = c.verify(open(filename), open(asc_file))
2453     verified = True
2454 except gpg.errors.BadSignatures as e:
2455     verified = False
2456     print(e)
2457
2458 if verified is True:
2459     for i in range(len(result.signatures)):
2460         sign = result.signatures[i]
2461         print("""Good signature from:
2462 @{0@}
2463 with key @{1@}
2464 made at @{2@}
2465 """.format(c.get_key(sign.fpr).uids[0].uid, sign.fpr,
2466            time.ctime(sign.timestamp)))
2467 else:
2468     pass
2469 @end example
2470
2471 @node Creating keys and subkeys
2472 @chapter Creating keys and subkeys
2473
2474 The one thing, aside from GnuPG itself, that GPGME depends on, of
2475 course, is the keys themselves.  So it is necessary to be able to
2476 generate them and modify them by adding subkeys, revoking or disabling
2477 them, sometimes deleting them and doing the same for user IDs.
2478
2479 In the following examples a key will be created for the world's
2480 greatest secret agent, Danger Mouse.  Since Danger Mouse is a secret
2481 agent he needs to be able to protect information to @samp{SECRET} level
2482 clearance, so his keys will be 3072-bit keys.
2483
2484 The pre-configured @samp{gpg.conf} file which sets cipher, digest and other
2485 preferences contains the following configuration parameters:
2486
2487 @example
2488 expert
2489 allow-freeform-uid
2490 allow-secret-key-import
2491 trust-model tofu+pgp
2492 tofu-default-policy unknown
2493 enable-large-rsa
2494 enable-dsa2
2495 cert-digest-algo SHA512
2496 default-preference-list TWOFISH CAMELLIA256 AES256 CAMELLIA192 AES192 CAMELLIA128 AES BLOWFISH IDEA CAST5 3DES SHA512 SHA384 SHA256 SHA224 RIPEMD160 SHA1 ZLIB BZIP2 ZIP Uncompressed
2497 personal-cipher-preferences TWOFISH CAMELLIA256 AES256 CAMELLIA192 AES192 CAMELLIA128 AES BLOWFISH IDEA CAST5 3DES
2498 personal-digest-preferences SHA512 SHA384 SHA256 SHA224 RIPEMD160 SHA1
2499 personal-compress-preferences ZLIB BZIP2 ZIP Uncompressed
2500 @end example
2501
2502 @menu
2503 * Primary key::
2504 * Subkeys::
2505 * User IDs::
2506 * Key certification::
2507 @end menu
2508
2509 @node Primary key
2510 @section Primary key
2511
2512 Generating a primary key uses the @samp{create_key} method in a Context.
2513 It contains multiple arguments and keyword arguments, including:
2514 @samp{userid}, @samp{algorithm}, @samp{expires_in}, @samp{expires}, @samp{sign}, @samp{encrypt},
2515 @samp{certify}, @samp{authenticate}, @samp{passphrase} and @samp{force}.  The defaults for
2516 all of those except @samp{userid}, @samp{algorithm}, @samp{expires_in}, @samp{expires} and
2517 @samp{passphrase} is @samp{False}.  The defaults for @samp{algorithm} and
2518 @samp{passphrase} is @samp{None}.  The default for @samp{expires_in} is @samp{0}.  The
2519 default for @samp{expires} is @samp{True}.  There is no default for @samp{userid}.
2520
2521 If @samp{passphrase} is left as @samp{None} then the key will not be generated
2522 with a passphrase, if @samp{passphrase} is set to a string then that will
2523 be the passphrase and if @samp{passphrase} is set to @samp{True} then gpg-agent
2524 will launch pinentry to prompt for a passphrase.  For the sake of
2525 convenience, these examples will keep @samp{passphrase} set to @samp{None}.
2526
2527 @example
2528 import gpg
2529
2530 c = gpg.Context()
2531
2532 c.home_dir = "~/.gnupg-dm"
2533 userid = "Danger Mouse <dm@@secret.example.net>"
2534
2535 dmkey = c.create_key(userid, algorithm="rsa3072", expires_in=31536000,
2536                      sign=True, certify=True)
2537 @end example
2538
2539 One thing to note here is the use of setting the @samp{c.home_dir}
2540 parameter.  This enables generating the key or keys in a different
2541 location.  In this case to keep the new key data created for this
2542 example in a separate location rather than adding it to existing and
2543 active key store data.  As with the default directory, @samp{~/.gnupg}, any
2544 temporary or separate directory needs the permissions set to only
2545 permit access by the directory owner.  On posix systems this means
2546 setting the directory permissions to 700.
2547
2548 The @samp{temp-homedir-config.py} script in the HOWTO examples directory
2549 will create an alternative homedir with these configuration options
2550 already set and the correct directory and file permissions.
2551
2552 The successful generation of the key can be confirmed via the returned
2553 @samp{GenkeyResult} object, which includes the following data:
2554
2555 @example
2556 print("""
2557  Fingerprint:  @{0@}
2558  Primary Key:  @{1@}
2559   Public Key:  @{2@}
2560   Secret Key:  @{3@}
2561  Sub Key:  @{4@}
2562 User IDs:  @{5@}
2563 """.format(dmkey.fpr, dmkey.primary, dmkey.pubkey, dmkey.seckey, dmkey.sub,
2564            dmkey.uid))
2565 @end example
2566
2567 Alternatively the information can be confirmed using the command line
2568 program:
2569
2570 @example
2571 bash-4.4$ gpg --homedir ~/.gnupg-dm -K
2572 ~/.gnupg-dm/pubring.kbx
2573 ----------------------
2574 sec   rsa3072 2018-03-15 [SC] [expires: 2019-03-15]
2575       177B7C25DB99745EE2EE13ED026D2F19E99E63AA
2576 uid           [ultimate] Danger Mouse <dm@@secret.example.net>
2577
2578 bash-4.4$
2579 @end example
2580
2581 As with generating keys manually, to preconfigure expanded preferences
2582 for the cipher, digest and compression algorithms, the @samp{gpg.conf} file
2583 must contain those details in the home directory in which the new key
2584 is being generated.  I used a cut down version of my own @samp{gpg.conf}
2585 file in order to be able to generate this:
2586
2587 @example
2588 bash-4.4$ gpg --homedir ~/.gnupg-dm --edit-key 177B7C25DB99745EE2EE13ED026D2F19E99E63AA showpref quit
2589 Secret key is available.
2590
2591 sec  rsa3072/026D2F19E99E63AA
2592      created: 2018-03-15  expires: 2019-03-15  usage: SC
2593      trust: ultimate      validity: ultimate
2594 [ultimate] (1). Danger Mouse <dm@@secret.example.net>
2595
2596 [ultimate] (1). Danger Mouse <dm@@secret.example.net>
2597      Cipher: TWOFISH, CAMELLIA256, AES256, CAMELLIA192, AES192, CAMELLIA128, AES, BLOWFISH, IDEA, CAST5, 3DES
2598      Digest: SHA512, SHA384, SHA256, SHA224, RIPEMD160, SHA1
2599      Compression: ZLIB, BZIP2, ZIP, Uncompressed
2600      Features: MDC, Keyserver no-modify
2601
2602 bash-4.4$
2603 @end example
2604
2605 @node Subkeys
2606 @section Subkeys
2607
2608 Adding subkeys to a primary key is fairly similar to creating the
2609 primary key with the @samp{create_subkey} method.  Most of the arguments
2610 are the same, but not quite all.  Instead of the @samp{userid} argument
2611 there is now a @samp{key} argument for selecting which primary key to add
2612 the subkey to.
2613
2614 In the following example an encryption subkey will be added to the
2615 primary key.  Since Danger Mouse is a security conscious secret agent,
2616 this subkey will only be valid for about six months, half the length
2617 of the primary key.
2618
2619 @example
2620 import gpg
2621
2622 c = gpg.Context()
2623 c.home_dir = "~/.gnupg-dm"
2624
2625 key = c.get_key(dmkey.fpr, secret=True)
2626 dmsub = c.create_subkey(key, algorithm="rsa3072", expires_in=15768000,
2627                         encrypt=True)
2628 @end example
2629
2630 As with the primary key, the results here can be checked with:
2631
2632 @example
2633 print("""
2634  Fingerprint:  @{0@}
2635  Primary Key:  @{1@}
2636   Public Key:  @{2@}
2637   Secret Key:  @{3@}
2638  Sub Key:  @{4@}
2639 User IDs:  @{5@}
2640 """.format(dmsub.fpr, dmsub.primary, dmsub.pubkey, dmsub.seckey, dmsub.sub,
2641            dmsub.uid))
2642 @end example
2643
2644 As well as on the command line with:
2645
2646 @example
2647 bash-4.4$ gpg --homedir ~/.gnupg-dm -K
2648 ~/.gnupg-dm/pubring.kbx
2649 ----------------------
2650 sec   rsa3072 2018-03-15 [SC] [expires: 2019-03-15]
2651       177B7C25DB99745EE2EE13ED026D2F19E99E63AA
2652 uid           [ultimate] Danger Mouse <dm@@secret.example.net>
2653 ssb   rsa3072 2018-03-15 [E] [expires: 2018-09-13]
2654
2655 bash-4.4$
2656 @end example
2657
2658 @node User IDs
2659 @section User IDs
2660
2661 @menu
2662 * Adding User IDs::
2663 * Revoking User IDs::
2664 @end menu
2665
2666 @node Adding User IDs
2667 @subsection Adding User IDs
2668
2669 By comparison to creating primary keys and subkeys, adding a new user
2670 ID to an existing key is much simpler.  The method used to do this is
2671 @samp{key_add_uid} and the only arguments it takes are for the @samp{key} and
2672 the new @samp{uid}.
2673
2674 @example
2675 import gpg
2676
2677 c = gpg.Context()
2678 c.home_dir = "~/.gnupg-dm"
2679
2680 dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA"
2681 key = c.get_key(dmfpr, secret=True)
2682 uid = "Danger Mouse <danger.mouse@@secret.example.net>"
2683
2684 c.key_add_uid(key, uid)
2685 @end example
2686
2687 Unsurprisingly the result of this is:
2688
2689 @example
2690 bash-4.4$ gpg --homedir ~/.gnupg-dm -K
2691 ~/.gnupg-dm/pubring.kbx
2692 ----------------------
2693 sec   rsa3072 2018-03-15 [SC] [expires: 2019-03-15]
2694       177B7C25DB99745EE2EE13ED026D2F19E99E63AA
2695 uid           [ultimate] Danger Mouse <danger.mouse@@secret.example.net>
2696 uid           [ultimate] Danger Mouse <dm@@secret.example.net>
2697 ssb   rsa3072 2018-03-15 [E] [expires: 2018-09-13]
2698
2699 bash-4.4$
2700 @end example
2701
2702 @node Revoking User IDs
2703 @subsection Revoking User IDs
2704
2705 Revoking a user ID is a fairly similar process, except that it uses
2706 the @samp{key_revoke_uid} method.
2707
2708 @example
2709 import gpg
2710
2711 c = gpg.Context()
2712 c.home_dir = "~/.gnupg-dm"
2713
2714 dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA"
2715 key = c.get_key(dmfpr, secret=True)
2716 uid = "Danger Mouse <danger.mouse@@secret.example.net>"
2717
2718 c.key_revoke_uid(key, uid)
2719 @end example
2720
2721 @node Key certification
2722 @section Key certification
2723
2724 Since key certification is more frequently referred to as key signing,
2725 the method used to perform this function is @samp{key_sign}.
2726
2727 The @samp{key_sign} method takes four arguments: @samp{key}, @samp{uids},
2728 @samp{expires_in} and @samp{local}.  The default value of @samp{uids} is @samp{None} and
2729 which results in all user IDs being selected.  The default value of
2730 both @samp{expires_in} and @samp{local} is @samp{False}; which results in the
2731 signature never expiring and being able to be exported.
2732
2733 The @samp{key} is the key being signed rather than the key doing the
2734 signing.  To change the key doing the signing refer to the signing key
2735 selection above for signing messages and files.
2736
2737 If the @samp{uids} value is not @samp{None} then it must either be a string to
2738 match a single user ID or a list of strings to match multiple user
2739 IDs.  In this case the matching of those strings must be precise and
2740 it is case sensitive.
2741
2742 To sign Danger Mouse's key for just the initial user ID with a
2743 signature which will last a little over a month, do this:
2744
2745 @example
2746 import gpg
2747
2748 c = gpg.Context()
2749 uid = "Danger Mouse <dm@@secret.example.net>"
2750
2751 dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA"
2752 key = c.get_key(dmfpr, secret=True)
2753 c.key_sign(key, uids=uid, expires_in=2764800)
2754 @end example
2755
2756 @node Advanced or Experimental Use Cases
2757 @chapter Advanced or Experimental Use Cases
2758
2759 @menu
2760 * C plus Python plus SWIG plus Cython::
2761 @end menu
2762
2763 @node C plus Python plus SWIG plus Cython
2764 @section C plus Python plus SWIG plus Cython
2765
2766 In spite of the apparent incongruence of using Python bindings to a C
2767 interface only to generate more C from the Python; it is in fact quite
2768 possible to use the GPGME bindings with @uref{http://docs.cython.org/en/latest/index.html, Cython}.  Though in many cases
2769 the benefits may not be obvious since the most computationally
2770 intensive work never leaves the level of the C code with which GPGME
2771 itself is interacting with.
2772
2773 Nevertheless, there are some situations where the benefits are
2774 demonstrable.  One of the better and easier examples being the one of
2775 the early examples in this HOWTO, the @ref{Counting keys, , key counting} code.  Running that
2776 example as an executable Python script, @samp{keycount.py} (available in
2777 the @samp{examples/howto/} directory), will take a noticeable amount of time
2778 to run on most systems where the public keybox or keyring contains a
2779 few thousand public keys.
2780
2781 Earlier in the evening, prior to starting this section, I ran that
2782 script on my laptop; as I tend to do periodically and timed it using
2783 @samp{time} utility, with the following results:
2784
2785 @example
2786 bash-4.4$ time keycount.py
2787
2788 Number of secret keys:  23
2789 Number of public keys:  12112
2790
2791
2792 real        11m52.945s
2793 user        0m0.913s
2794 sys        0m0.752s
2795
2796 bash-4.4$
2797 @end example
2798
2799 Sometime after that I imported another key and followed it with a
2800 little test of Cython.  This test was kept fairly basic, essentially
2801 lifting the material from the @uref{http://docs.cython.org/en/latest/src/tutorial/cython_tutorial.html, Cython Basic Tutorial} to demonstrate
2802 compiling Python code to C.  The first step was to take the example
2803 key counting code quoted previously, essentially from the importing of
2804 the @samp{gpg} module to the end of the script:
2805
2806 @example
2807 import gpg
2808
2809 c = gpg.Context()
2810 seckeys = c.keylist(pattern=None, secret=True)
2811 pubkeys = c.keylist(pattern=None, secret=False)
2812
2813 seclist = list(seckeys)
2814 secnum = len(seclist)
2815
2816 publist = list(pubkeys)
2817 pubnum = len(publist)
2818
2819 print("""
2820     Number of secret keys:  @{0@}
2821     Number of public keys:  @{1@}
2822
2823 """.format(secnum, pubnum))
2824 @end example
2825
2826 Save that into a file called @samp{keycount.pyx} and then create a
2827 @samp{setup.py} file which contains this:
2828
2829 @example
2830 from distutils.core import setup
2831 from Cython.Build import cythonize
2832
2833 setup(
2834     ext_modules = cythonize("keycount.pyx")
2835 )
2836 @end example
2837
2838 Compile it:
2839
2840 @example
2841 bash-4.4$ python setup.py build_ext --inplace
2842 bash-4.4$
2843 @end example
2844
2845 Then run it in a similar manner to @samp{keycount.py}:
2846
2847 @example
2848 bash-4.4$ time python3.7 -c "import keycount"
2849
2850 Number of secret keys:  23
2851 Number of public keys:  12113
2852
2853
2854 real        6m47.905s
2855 user        0m0.785s
2856 sys        0m0.331s
2857
2858 bash-4.4$
2859 @end example
2860
2861 Cython turned @samp{keycount.pyx} into an 81KB @samp{keycount.o} file in the
2862 @samp{build/} directory, a 24KB @samp{keycount.cpython-37m-darwin.so} file to be
2863 imported into Python 3.7 and a 113KB @samp{keycount.c} generated C source
2864 code file of nearly three thousand lines.  Quite a bit bigger than the
2865 314 bytes of the @samp{keycount.pyx} file or the full 1,452 bytes of the
2866 full executable @samp{keycount.py} example script.
2867
2868 On the other hand it ran in nearly half the time; taking 6 minutes and
2869 47.905 seconds to run.  As opposed to the 11 minutes and 52.945 seconds
2870 which the CPython script alone took.
2871
2872 The @samp{keycount.pyx} and @samp{setup.py} files used to generate this example
2873 have been added to the @samp{examples/howto/advanced/cython/} directory
2874 The example versions include some additional options to annotate the
2875 existing code and to detect Cython's use.  The latter comes from the
2876 @uref{http://docs.cython.org/en/latest/src/tutorial/pure.html#magic-attributes-within-the-pxd, Magic Attributes} section of the Cython documentation.
2877
2878 @node Miscellaneous extras and work-arounds
2879 @chapter Miscellaneous extras and work-arounds
2880
2881 Most of the things in the following sections are here simply because
2882 there was no better place to put them, even though some are only
2883 peripherally related to the GPGME Python bindings.  Some are also
2884 workarounds for functions not integrated with GPGME as yet.  This is
2885 especially true of the first of these, dealing with @ref{Group lines, , group lines}.
2886
2887 @menu
2888 * Group lines::
2889 * Keyserver access for Python::
2890 @end menu
2891
2892 @node Group lines
2893 @section Group lines
2894
2895 There is not yet an easy way to access groups configured in the
2896 gpg.conf file from within GPGME.  As a consequence these central
2897 groupings of keys cannot be shared amongst multiple programs, such as
2898 MUAs readily.
2899
2900 The following code, however, provides a work-around for obtaining this
2901 information in Python.
2902
2903 @example
2904 import subprocess
2905 import sys
2906
2907 if sys.platform == "win32":
2908     gpgconfcmd = "gpgconf.exe --list-options gpg"
2909 else:
2910     gpgconfcmd = "gpgconf --list-options gpg"
2911
2912 try:
2913     lines = subprocess.getoutput(gpgconfcmd).splitlines()
2914 except:
2915     process = subprocess.Popen(gpgconfcmd.split(), stdout=subprocess.PIPE)
2916     procom = process.communicate()
2917     if sys.version_info[0] == 2:
2918         lines = procom[0].splitlines()
2919     else:
2920         lines = procom[0].decode().splitlines()
2921
2922 for i in range(len(lines)):
2923     if lines[i].startswith("group") is True:
2924         line = lines[i]
2925     else:
2926         pass
2927
2928 groups = line.split(":")[-1].replace('"', '').split(',')
2929
2930 group_lines = []
2931 group_lists = []
2932
2933 for i in range(len(groups)):
2934     group_lines.append(groups[i].split("="))
2935     group_lists.append(groups[i].split("="))
2936
2937 for i in range(len(group_lists)):
2938     group_lists[i][1] = group_lists[i][1].split()
2939 @end example
2940
2941 The result of that code is that @samp{group_lines} is a list of lists where
2942 @samp{group_lines[i][0]} is the name of the group and @samp{group_lines[i][1]}
2943 is the key IDs of the group as a string.
2944
2945 The @samp{group_lists} result is very similar in that it is a list of
2946 lists.  The first part, @samp{group_lists[i][0]} matches
2947 @samp{group_lines[i][0]} as the name of the group, but @samp{group_lists[i][1]}
2948 is the key IDs of the group as a list.
2949
2950 A demonstration of using the @samp{groups.py} module is also available in
2951 the form of the executable @samp{mutt-groups.py} script.  This second
2952 script reads all the group entries in a user's @samp{gpg.conf} file and
2953 converts them into crypt-hooks suitable for use with the Mutt and
2954 Neomutt mail clients.
2955
2956 @node Keyserver access for Python
2957 @section Keyserver access for Python
2958
2959 The @uref{https://github.com/Selfnet/hkp4py, hkp4py} module by Marcel Fest was originally a port of the old
2960 @uref{https://github.com/dgladkov/python-hkp, python-hkp} module from Python 2 to Python 3 and updated to use the
2961 @uref{http://docs.python-requests.org/en/latest/index.html, requests} module instead.  It has since been modified to provide
2962 support for Python 2.7 as well and is available via PyPI.
2963
2964 Since it rewrites the @samp{hkp} protocol prefix as @samp{http} and @samp{hkps} as
2965 @samp{https}, the module is able to be used even with servers which do not
2966 support the full scope of keyserver functions.@footnote{Such as with ProtonMail servers.  This also means that
2967 restricted servers which only advertise either HTTP or HTTPS end
2968 points and not HKP or HKPS end points must still be identified as as
2969 HKP or HKPS within the Python Code.  The @samp{hkp4py} module will rewrite
2970 these appropriately when the connection is made to the server.}  It also works quite
2971 readily when incorporated into a @ref{C plus Python plus SWIG plus Cython, , Cython} generated and compiled version
2972 of any code.
2973
2974 @menu
2975 * Key import format::
2976 @end menu
2977
2978 @node Key import format
2979 @subsection Key import format
2980
2981 The hkp4py module returns key data via requests as string literals
2982 (@samp{r.text}) instead of byte literals (@samp{r.content}).  This means that
2983 the retrurned key data must be encoded to UTF-8 when importing that
2984 key material using a @samp{gpg.Context().key_import()} method.
2985
2986 For this reason an alternative method has been added to the @samp{search}
2987 function of @samp{hkp4py.KeyServer()} which returns the key in the correct
2988 format as expected by @samp{key_import}.  When importing using this module,
2989 it is now possible to import with this:
2990
2991 @example
2992 for key in keys:
2993     if key.revoked is False:
2994         gpg.Context().key_import(key.key_blob)
2995     else:
2996         pass
2997 @end example
2998
2999 Without that recent addition it would have been necessary to encode
3000 the contents of each @samp{hkp4py.KeyServer().search()[i].key} in
3001 @samp{hkp4py.KeyServer().search()} before trying to import it.
3002
3003 An example of this is included in the @ref{Importing keys, , Importing Keys} section of this
3004 HOWTO and the corresponding executable version of that example is
3005 available in the @samp{lang/python/examples/howto} directory as normal; the
3006 executable version is the @samp{import-keys-hkp.py} file.
3007
3008 @node Copyright and Licensing
3009 @chapter Copyright and Licensing
3010
3011 @menu
3012 * Copyright::
3013 * Draft Editions of this HOWTO::
3014 * License GPL compatible::
3015 @end menu
3016
3017 @node Copyright
3018 @section Copyright
3019
3020 Copyright © The GnuPG Project, 2018.
3021
3022 Copyright (C) The GnuPG Project, 2018.
3023
3024 @node Draft Editions of this HOWTO
3025 @section Draft Editions of this HOWTO
3026
3027 Draft editions of this HOWTO may be periodically available directly
3028 from the author at any of the following URLs:
3029
3030 @itemize
3031 @item
3032 @uref{https://files.au.adversary.org/crypto/gpgme-python-howto.html, GPGME Python Bindings HOWTO draft (XHTML AWS S3 SSL)}
3033 @item
3034 @uref{http://files.au.adversary.org/crypto/gpgme-python-howto.html, GPGME Python Bindings HOWTO draft (XHTML AWS S3 no SSL)}
3035 @item
3036 @uref{https://files.au.adversary.org/crypto/gpgme-python-howto.texi, GPGME Python Bindings HOWTO draft (Texinfo file AWS S3 SSL)}
3037 @item
3038 @uref{http://files.au.adversary.org/crypto/gpgme-python-howto.texi, GPGME Python Bindings HOWTO draft (Texinfo file AWS S3 no SSL)}
3039 @item
3040 @uref{https://files.au.adversary.org/crypto/gpgme-python-howto.info, GPGME Python Bindings HOWTO draft (Info file AWS S3 SSL)}
3041 @item
3042 @uref{http://files.au.adversary.org/crypto/gpgme-python-howto.info, GPGME Python Bindings HOWTO draft (Info file AWS S3 no SSL)}
3043 @item
3044 @uref{https://files.au.adversary.org/crypto/gpgme-python-howto.rst, GPGME Python Bindings HOWTO draft (reST file AWS S3 SSL)}
3045 @item
3046 @uref{http://files.au.adversary.org/crypto/gpgme-python-howto.rst, GPGME Python Bindings HOWTO draft (reST file AWS S3 no SSL)}
3047 @item
3048 @uref{https://files.au.adversary.org/crypto/gpgme-python-howto.xml, GPGME Python Bindings HOWTO draft (Docbook 4.2 AWS S3 SSL)}
3049 @item
3050 @uref{http://files.au.adversary.org/crypto/gpgme-python-howto.xml, GPGME Python Bindings HOWTO draft (Docbook 4.2 AWS S3 no SSL)}
3051 @end itemize
3052
3053 All of these draft versions except for one have been generated from
3054 this document via Emacs @uref{https://orgmode.org/, Org mode} and @uref{https://www.gnu.org/software/texinfo/, GNU Texinfo}.  Though it is likely
3055 that the specific @uref{https://files.au.adversary.org/crypto/gpgme-python-howto, file} @uref{http://files.au.adversary.org/crypto/gpgme-python-howto.org, version} used will be on the same server with
3056 the generated output formats.
3057
3058 The one exception is the reStructuredText version, which was converted
3059 using the latest version of Pandoc from the Org mode source file using
3060 either of the following two commands:
3061
3062 @example
3063 pandoc -f org -t rst -o gpgme-python-howto.rst gpgme-python-howto.org
3064 pandoc -f org -t rst -o gpgme-python-howto.rst gpgme-python-howto
3065 @end example
3066
3067 In addition to these there is a significantly less frequently updated
3068 version as a HTML @uref{https://files.au.adversary.org/crypto/gpgme-python-howto/webhelp/index.html, WebHelp site} (AWS S3 SSL); generated from DITA XML
3069 source files, which can be found in @uref{https://dev.gnupg.org/source/gpgme/browse/ben%252Fhowto-dita/, an alternative branch} of the GPGME
3070 git repository.
3071
3072 These draft editions are not official documents and the version of
3073 documentation in the master branch or which ships with released
3074 versions is the only official documentation.  Nevertheless, these
3075 draft editions may occasionally be of use by providing more accessible
3076 web versions which are updated between releases.  They are provided on
3077 the understanding that they may contain errors or may contain content
3078 subject to change prior to an official release.
3079
3080 @node License GPL compatible
3081 @section License GPL compatible
3082
3083 This file is free software; as a special exception the author gives
3084 unlimited permission to copy and/or distribute it, with or without
3085 modifications, as long as this notice is preserved.
3086
3087 This file is distributed in the hope that it will be useful, but
3088 WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
3089 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
3090 PURPOSE.
3091
3092 @bye