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