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