docs: python bindings howto
[gpgme.git] / lang / python / docs / GPGMEpythonHOWTOen.org
1 #+TITLE: GNU Privacy Guard (GnuPG) Made Easy Python Bindings HOWTO (English)
2 #+LATEX_COMPILER: xelatex
3 #+LATEX_CLASS: article
4 #+LATEX_CLASS_OPTIONS: [12pt]
5 #+LATEX_HEADER: \usepackage{xltxtra}
6 #+LATEX_HEADER: \usepackage[margin=1in]{geometry}
7 #+LATEX_HEADER: \setmainfont[Ligatures={Common}]{Times New Roman}
8 #+LATEX_HEADER: \author{Ben McGinnes <ben@gnupg.org>}
9 #+HTML_HEAD_EXTRA: <link type="application/rss+xml" href="https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gpgme.git;a=rss;f=lang/python/docs/GPGMEpythonHOWTOen.org"/>
10
11
12 * Introduction
13   :PROPERTIES:
14   :CUSTOM_ID: intro
15   :END:
16
17 | Version:        | 0.1.3                                    |
18 | Author:         | Ben McGinnes <ben@gnupg.org>             |
19 | Author GPG Key: | DB4724E6FA4286C92B4E55C4321E4E2373590E5D |
20 | Language:       | Australian English, British English      |
21 | xml:lang:       | en-AU, en-GB, en                         |
22
23 This document provides basic instruction in how to use the GPGME
24 Python bindings to programmatically leverage the GPGME library.
25
26
27 ** Python 2 versus Python 3
28    :PROPERTIES:
29    :CUSTOM_ID: py2-vs-py3
30    :END:
31
32 Though the GPGME Python bindings themselves provide support for both
33 Python 2 and 3, the focus is unequivocally on Python 3 and
34 specifically from Python 3.4 and above.  As a consequence all the
35 examples and instructions in this guide use Python 3 code.
36
37 Much of it will work with Python 2, but much of it also deals with
38 Python 3 byte literals, particularly when reading and writing data.
39 Developers concentrating on Python 2.7, and possibly even 2.6, will
40 need to make the appropriate modifications to support the older string
41 and unicode types as opposed to bytes.
42
43 There are multiple reasons for concentrating on Python 3; some of
44 which relate to the immediate integration of these bindings, some of
45 which relate to longer term plans for both GPGME and the python
46 bindings and some of which relate to the impending EOL period for
47 Python 2.7.  Essentially, though, there is little value in tying the
48 bindings to a version of the language which is a dead end and the
49 advantages offered by Python 3 over Python 2 make handling the data
50 types with which GPGME deals considerably easier.
51
52
53 ** Examples
54    :PROPERTIES:
55    :CUSTOM_ID: howto-python3-examples
56    :END:
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
62 * GPGME Concepts
63   :PROPERTIES:
64   :CUSTOM_ID: gpgme-concepts
65   :END:
66
67
68 ** A C API
69    :PROPERTIES:
70    :CUSTOM_ID: gpgme-c-api
71    :END:
72
73 Unlike many modern APIs with which programmers will be more familiar
74 with these days, the GPGME API is a C API.  The API is intended for
75 use by C coders who would be able to access its features by including
76 the =gpgme.h= header file with their own C source code and then access
77 its functions just as they would any other C headers.
78
79 This is a very effective method of gaining complete access to the API
80 and in the most efficient manner possible.  It does, however, have the
81 drawback that it cannot be directly used by other languages without
82 some means of providing an interface to those languages.  This is
83 where the need for bindings in various languages stems.
84
85
86 ** Python bindings
87    :PROPERTIES:
88    :CUSTOM_ID: gpgme-python-bindings
89    :END:
90
91 The Python bindings for GPGME provide a higher level means of
92 accessing the complete feature set of GPGME itself.  It also provides
93 a more pythonic means of calling these API functions.
94
95 The bindings are generated dynamically with SWIG and the copy of
96 =gpgme.h= generated when GPGME is compiled.
97
98 This means that a version of the Python bindings is fundamentally tied
99 to the exact same version of GPGME used to generate that copy of
100 =gpgme.h=.
101
102
103 ** Difference between the Python bindings and other GnuPG Python packages
104    :PROPERTIES:
105    :CUSTOM_ID: gpgme-python-bindings-diffs
106    :END:
107
108 There have been numerous attempts to add GnuPG support to Python over
109 the years.  Some of the most well known are listed here, along with
110 what differentiates them.
111
112
113 *** The python-gnupg package maintained by Vinay Sajip
114     :PROPERTIES:
115     :CUSTOM_ID: diffs-python-gnupg
116     :END:
117
118 This is arguably the most popular means of integrating GPG with
119 Python.  The package utilises the =subprocess= module to implement
120 wrappers for the =gpg= and =gpg2= executables normally invoked on the
121 command line (=gpg.exe= and =gpg2.exe= on Windows).
122
123 The popularity of this package stemmed from its ease of use and
124 capability in providing the most commonly required features.
125
126 Unfortunately it has been beset by a number of security issues in the
127 past; most of which stemmed from using unsafe methods of accessing the
128 command line via the =subprocess= calls.  While some effort has been
129 made over the last two to three years (as of 2018) to mitigate this,
130 particularly by no longer providing shell access through those
131 subprocess calls, the wrapper is still somewhat limited in the scope
132 of its GnuPG features coverage.
133
134 The python-gnupg package is available under the MIT license.
135
136
137 *** The gnupg package created and maintained by Isis Lovecruft
138     :PROPERTIES:
139     :CUSTOM_ID: diffs-isis-gnupg
140     :END:
141
142 In 2015 Isis Lovecruft from the Tor Project forked and then
143 re-implemented the python-gnupg package as just gnupg.  This new
144 package also relied on subprocess to call the =gpg= or =gpg2=
145 binaries, but did so somewhat more securely.
146
147 The naming and version numbering selected for this package, however,
148 resulted in conflicts with the original python-gnupg and since its
149 functions were called in a different manner to python-gnupg, the
150 release of this package also resulted in a great deal of consternation
151 when people installed what they thought was an upgrade that
152 subsequently broke the code relying on it.
153
154 The gnupg package is available under the GNU General Public License
155 version 3.0 (or any later version).
156
157
158 *** The PyME package maintained by Martin Albrecht
159     :PROPERTIES:
160     :CUSTOM_ID: diffs-pyme
161     :END:
162
163 This package is the origin of these bindings, though they are somewhat
164 different now.  For details of when and how the PyME package was
165 folded back into GPGME itself see the /Short History/ document[fn:1]
166 in the Python bindings =docs= directory.[fn:2]
167
168 The PyME package was first released in 2002 and was also the first
169 attempt to implement a low level binding to GPGME.  In doing so it
170 provided access to considerably more functionality than either the
171 =python-gnupg= or =gnupg= packages.
172
173 The PyME package is only available for Python 2.6 and 2.7.
174
175 Porting the PyME package to Python 3.4 in 2015 is what resulted in it
176 being folded into the GPGME project and the current bindings are the
177 end result of that effort.
178
179 The PyME package is available under the same dual licensing as GPGME
180 itself: the GNU General Public License version 2.0 (or any later
181 version) and the GNU Lesser General Public License version 2.1 (or any
182 later version).
183
184
185 * GPGME Python bindings installation
186   :PROPERTIES:
187   :CUSTOM_ID: gpgme-python-install
188   :END:
189
190
191 ** No PyPI
192    :PROPERTIES:
193    :CUSTOM_ID: do-not-use-pypi
194    :END:
195
196 Most third-party Python packages and modules are available and
197 distributed through the Python Package Installer, known as PyPI.
198
199 Due to the nature of what these bindings are and how they work, it is
200 infeasible to install the GPGME Python bindings in the same way.
201
202 This is because the bindings use SWIG to dynamically generate C
203 bindings against =gpgme.h= and =gpgme.h= is generated from
204 =gpgme.h.in= at compile time when GPGME is built from source.  Thus to
205 include a package in PyPI which actually built correctly would require
206 either statically built libraries for every architecture bundled with
207 it or a full implementation of C for each architecture.
208
209
210 ** Requirements
211    :PROPERTIES:
212    :CUSTOM_ID: gpgme-python-requirements
213    :END:
214
215 The GPGME Python bindings only have three requirements:
216
217 1. A suitable version of Python 2 or Python 3.  With Python 2 that
218    means Python 2.7 and with Python 3 that means Python 3.4 or higher.
219 2. SWIG.
220 3. GPGME itself.  Which also means that all of GPGME's dependencies
221    must be installed too.
222
223
224 ** Installation
225    :PROPERTIES:
226    :CUSTOM_ID: installation
227    :END:
228
229 Installing the Python bindings is effectively achieved by compiling
230 and installing GPGME itself.
231
232 Once SWIG is installed with Python and all the dependencies for GPGME
233 are installed you only need to confirm that the version(s) of Python
234 you want the bindings installed for are in your =$PATH=.
235
236 By default GPGME will attempt to install the bindings for the most
237 recent or highest version number of Python 2 and Python 3 it detects
238 in =$PATH=.  It specifically checks for the =python= and =python3=
239 executables first and then checks for specific version numbers.
240
241 For Python 2 it checks for these executables in this order: =python=,
242 =python2= and =python2.7=.
243
244 For Python 3 it checks for these executables in this order: =python3=,
245 =python3.6=, =python3.5=, =python3.4= and =python3.7=.[fn:4]
246
247
248 *** Installing GPGME
249     :PROPERTIES:
250     :CUSTOM_ID: install-gpgme
251     :END:
252
253 See the GPGME =README= file for details of how to install GPGME from
254 source.
255
256
257 * Fundamentals
258   :PROPERTIES:
259   :CUSTOM_ID: howto-fund-a-mental
260   :END:
261
262 Before we can get to the fun stuff, there are a few matters regarding
263 GPGME's design which hold true whether you're dealing with the C code
264 directly or these Python bindings.
265
266
267 ** No REST
268    :PROPERTIES:
269    :CUSTOM_ID: no-rest-for-the-wicked
270    :END:
271
272 The first part of which is or will be fairly blatantly obvious upon
273 viewing the first example, but it's worth reiterating anyway.  That
274 being that this API is /*not*/ a REST API.  Nor indeed could it ever
275 be one.
276
277 Most, if not all, Python programmers (and not just Python programmers)
278 know how easy it is to work with a RESTful API.  In fact they've
279 become so popular that many other APIs attempt to emulate REST-like
280 behaviour as much as they are able.  Right down to the use of JSON
281 formatted output to facilitate the use of their API without having to
282 retrain developers.
283
284 This API does not do that.  It would not be able to do that and also
285 provide access to the entire C API on which it's built.  It does,
286 however, provide a very pythonic interface on top of the direct
287 bindings and it's this pythonic layer with which this HOWTO deals
288 with.
289
290
291 ** Context
292    :PROPERTIES:
293    :CUSTOM_ID: howto-get-context
294    :END:
295
296 One of the reasons which prevents this API from being RESTful is that
297 most operations require more than one instruction to the API to
298 perform the task.  Sure, there are certain functions which can be
299 performed simultaneously, particularly if the result known or strongly
300 anticipated (e.g. selecting and encrypting to a key known to be in the
301 public keybox).
302
303 There are many more, however, which cannot be manipulated so readily:
304 they must be performed in a specific sequence and the result of one
305 operation has a direct bearing on the outcome of subsequent
306 operations.  Not merely by generating an error either.
307
308 When dealing with this type of persistent state on the web, full of
309 both the RESTful and REST-like, it's most commonly referred to as a
310 session.  In GPGME, however, it is called a context and every
311 operation type has one.
312
313
314 * Working with keys
315   :PROPERTIES:
316   :CUSTOM_ID: howto-keys
317   :END:
318
319
320 ** Key selection
321    :PROPERTIES:
322    :CUSTOM_ID: howto-keys-selection
323    :END:
324
325 Selecting keys to encrypt to or to sign with will be a common
326 occurrence when working with GPGMe and the means available for doing
327 so are quite simple.
328
329 They do depend on utilising a Context; however once the data is
330 recorded in another variable, that Context does not need to be the
331 same one which subsequent operations are performed.
332
333 The easiest way to select a specific key is by searching for that
334 key's key ID or fingerprint, preferably the full fingerprint without
335 any spaces in it.  A long key ID will probably be okay, but is not
336 advised and short key IDs are already a problem with some being
337 generated to match specific patterns.  It does not matter whether the
338 pattern is upper or lower case.
339
340 So this is the best method:
341
342 #+begin_src python
343   import gpg
344
345   k = gpg.Context().keylist(pattern="258E88DCBD3CD44D8E7AB43F6ECB6AF0DEADBEEF")
346   keys = list(k)
347 #+end_src
348
349 This is passable and very likely to be common:
350
351 #+begin_src python
352   import gpg
353
354   k = gpg.Context().keylist(pattern="0x6ECB6AF0DEADBEEF")
355   keys = list(k)
356 #+end_src
357
358 And this is a really bad idea:
359
360 #+begin_src python
361   import gpg
362
363   k = gpg.Context().keylist(pattern="0xDEADBEEF")
364   keys = list(k)
365 #+end_src
366
367 Alternatively it may be that the intention is to create a list of keys
368 which all match a particular search string.  For instance all the
369 addresses at a particular domain, like this:
370
371 #+begin_src python
372   import gpg
373
374   ncsc = gpg.Context().keylist(pattern="ncsc.mil")
375   nsa = list(ncsc)
376 #+end_src
377
378
379 *** Counting keys
380     :PROPERTIES:
381     :CUSTOM_ID: howto-keys-counting
382     :END:
383
384 Counting the number of keys in your public keybox (=pubring.kbx=), the
385 format which has superseded the old keyring format (=pubring.gpg= and
386 =secring.gpg=), or the number of secret keys is a very simple task.
387
388 #+begin_src python
389   import gpg
390
391   c = gpg.Context()
392   seckeys = c.keylist(pattern=None, secret=True)
393   pubkeys = c.keylist(pattern=None, secret=False)
394
395   seclist = list(seckeys)
396   secnum = len(seclist)
397
398   publist = list(pubkeys)
399   pubnum = len(publist)
400
401   print("""
402   Number of secret keys:  {0}
403   Number of public keys:  {1}
404   """.format(secnum, pubnum))
405 #+end_src
406
407
408 ** Get key
409    :PROPERTIES:
410    :CUSTOM_ID: howto-get-key
411    :END:
412
413 An alternative method of getting a single key via its fingerprint is
414 available directly within a Context with =Context().get_key=.  This is
415 the preferred method of selecting a key in order to modify it, sign or
416 certify it and for obtaining relevant data about a single key as a
417 part of other functions; when verifying a signature made by that key,
418 for instance.
419
420 By default this method will select public keys, but it can select
421 secret keys as well.
422
423 This first example demonstrates selecting the current key of Werner
424 Koch, which is due to expire at the end of 2018:
425
426 #+begin_src python
427   import gpg
428
429   fingerprint = "80615870F5BAD690333686D0F2AD85AC1E42B367"
430   key = gpg.Context().get_key(fingerprint)
431 #+end_src
432
433 Whereas this example demonstrates selecting the author's current key
434 with the =secret= key word argument set to =True=:
435
436 #+begin_src python
437   import gpg
438
439   fingerprint = "DB4724E6FA4286C92B4E55C4321E4E2373590E5D"
440   key = gpg.Context().get_key(fingerprint, secret=True)
441 #+end_src
442
443 It is, of course, quite possible to select expired, disabled and
444 revoked keys with this function, but only to effectively display
445 information about those keys.
446
447 It is also possible to use both unicode or string literals and byte
448 literals with the fingerprint when getting a key in this way.
449
450
451 ** Importing keys
452    :PROPERTIES:
453    :CUSTOM_ID: howto-import-key
454    :END:
455
456 Importing keys is possible with the =key_import()= method and takes
457 one argument which is a bytes literal object containing either the
458 binary or ASCII armoured key data for one or more keys.
459
460 The following example retrieves one or more keys from the SKS
461 keyservers via the web using the requests module. Since requests
462 returns the content as a bytes literal object, we can then use that
463 directly to import the resulting data into our keybox.
464
465 #+begin_src python
466   import gpg
467   import os.path
468   import requests
469
470   c = gpg.Context()
471   url = "https://sks-keyservers.net/pks/lookup"
472   pattern = input("Enter the pattern to search for key or user IDs: ")
473   payload = { "op": "get", "search": pattern }
474
475   r = requests.get(url, verify=True, params=payload)
476   result = c.key_import(r.content)
477
478   if result is not None and hasattr(result, "considered") is False:
479       print(result)
480   elif result is not None and hasattr(result, "considered") is True:
481       num_keys = len(result.imports)
482       new_revs = result.new_revocations
483       new_sigs = result.new_signatures
484       new_subs = result.new_sub_keys
485       new_uids = result.new_user_ids
486       new_scrt = result.secret_imported
487       nochange = result.unchanged
488       print("""
489   The total number of keys considered for import was:  {0}
490
491      Number of keys revoked:  {1}
492    Number of new signatures:  {2}
493       Number of new subkeys:  {3}
494      Number of new user IDs:  {4}
495   Number of new secret keys:  {5}
496    Number of unchanged keys:  {6}
497
498   The key IDs for all considered keys were:
499   """.format(num_keys, new_revs, new_sigs, new_subs, new_uids, new_scrt,
500              nochange))
501       for i in range(num_keys):
502           print(result.imports[i].fpr)
503           print("")
504   else:
505       pass
506 #+end_src
507
508 *NOTE:* When searching for a key ID of any length or a fingerprint
509 (without spaces), the SKS servers require the the leading =0x=
510 indicative of hexadecimal be included. Also note that the old short
511 key IDs (e.g. =0xDEADBEEF=) should no longer be used due to the
512 relative ease by which such key IDs can be reproduced, as demonstrated
513 by the Evil32 Project in 2014 (which was subsequently exploited in
514 2016).
515
516
517 ** Exporting keys
518    :PROPERTIES:
519    :CUSTOM_ID: howto-export-key
520    :END:
521
522 Exporting keys remains a reasonably simple task, but has been
523 separated into three different functions for the OpenPGP cryptographic
524 engine.  Two of those functions are for exporting public keys and the
525 third is for exporting secret keys.
526
527
528 *** Exporting public keys
529     :PROPERTIES:
530     :CUSTOM_ID: howto-export-public-key
531     :END:
532
533 There are two methods of exporting public keys, both of which are very
534 similar to the other.  The default method, =key_export()=, will export
535 a public key or keys matching a specified pattern as normal.  The
536 alternative, the =key_export_minimal()= method, will do the same thing
537 except producing a minimised output with extra signatures and third
538 party signatures or certifications removed.
539
540 #+begin_src python
541   import gpg
542   import os.path
543   import sys
544
545   print("""
546   This script exports one or more public keys.
547   """)
548
549   c = gpg.Context(armor=True)
550
551   if len(sys.argv) >= 4:
552       keyfile = sys.argv[1]
553       logrus = sys.argv[2]
554       homedir = sys.argv[3]
555   elif len(sys.argv) == 3:
556       keyfile = sys.argv[1]
557       logrus = sys.argv[2]
558       homedir = input("Enter the GPG configuration directory path (optional): ")
559   elif len(sys.argv) == 2:
560       keyfile = sys.argv[1]
561       logrus = input("Enter the UID matching the key(s) to export: ")
562       homedir = input("Enter the GPG configuration directory path (optional): ")
563   else:
564       keyfile = input("Enter the path and filename to save the secret key to: ")
565       logrus = input("Enter the UID matching the key(s) to export: ")
566       homedir = input("Enter the GPG configuration directory path (optional): ")
567
568   if homedir.startswith("~"):
569       if os.path.exists(os.path.expanduser(homedir)) is True:
570           c.home_dir = os.path.expanduser(homedir)
571       else:
572           pass
573   elif os.path.exists(homedir) is True:
574       c.home_dir = homedir
575   else:
576       pass
577
578   try:
579       result = c.key_export(pattern=logrus)
580   except:
581       result = c.key_export(pattern=None)
582
583   if result is not None:
584       with open(keyfile, "wb") as f:
585           f.write(result)
586   else:
587       pass
588 #+end_src
589
590 It is important to note that the result will only return =None= when a
591 pattern has been entered for =logrus=, but it has not matched any
592 keys. When the search pattern itself is set to =None= this triggers
593 the exporting of the entire public keybox.
594
595 #+begin_src python
596   import gpg
597   import os.path
598   import sys
599
600   print("""
601   This script exports one or more public keys in minimised form.
602   """)
603
604   c = gpg.Context(armor=True)
605
606   if len(sys.argv) >= 4:
607       keyfile = sys.argv[1]
608       logrus = sys.argv[2]
609       homedir = sys.argv[3]
610   elif len(sys.argv) == 3:
611       keyfile = sys.argv[1]
612       logrus = sys.argv[2]
613       homedir = input("Enter the GPG configuration directory path (optional): ")
614   elif len(sys.argv) == 2:
615       keyfile = sys.argv[1]
616       logrus = input("Enter the UID matching the key(s) to export: ")
617       homedir = input("Enter the GPG configuration directory path (optional): ")
618   else:
619       keyfile = input("Enter the path and filename to save the secret key to: ")
620       logrus = input("Enter the UID matching the key(s) to export: ")
621       homedir = input("Enter the GPG configuration directory path (optional): ")
622
623   if homedir.startswith("~"):
624       if os.path.exists(os.path.expanduser(homedir)) is True:
625           c.home_dir = os.path.expanduser(homedir)
626       else:
627           pass
628   elif os.path.exists(homedir) is True:
629       c.home_dir = homedir
630   else:
631       pass
632
633   try:
634       result = c.key_export_minimal(pattern=logrus)
635   except:
636       result = c.key_export_minimal(pattern=None)
637
638   if result is not None:
639       with open(keyfile, "wb") as f:
640           f.write(result)
641   else:
642       pass
643 #+end_src
644
645
646 *** Exporting secret keys
647     :PROPERTIES:
648     :CUSTOM_ID: howto-export-secret-key
649     :END:
650
651 Exporting secret keys is, functionally, very similar to exporting
652 public keys; save for the invocation of =pinentry= via =gpg-agent= in
653 order to securely enter the key's passphrase and authorise the export.
654
655 The following example exports the secret key to a file which is then
656 set with the same permissions as the output files created by the
657 command line secret key export options.
658
659 #+begin_src python
660   import gpg
661   import os
662   import os.path
663   import sys
664
665   print("""
666   This script exports one or more secret keys.
667
668   The gpg-agent and pinentry are invoked to authorise the export.
669   """)
670
671   c = gpg.Context(armor=True)
672
673   if len(sys.argv) >= 4:
674       keyfile = sys.argv[1]
675       logrus = sys.argv[2]
676       homedir = sys.argv[3]
677   elif len(sys.argv) == 3:
678       keyfile = sys.argv[1]
679       logrus = sys.argv[2]
680       homedir = input("Enter the GPG configuration directory path (optional): ")
681   elif len(sys.argv) == 2:
682       keyfile = sys.argv[1]
683       logrus = input("Enter the UID matching the secret key(s) to export: ")
684       homedir = input("Enter the GPG configuration directory path (optional): ")
685   else:
686       keyfile = input("Enter the path and filename to save the secret key to: ")
687       logrus = input("Enter the UID matching the secret key(s) to export: ")
688       homedir = input("Enter the GPG configuration directory path (optional): ")
689
690   if homedir.startswith("~"):
691       if os.path.exists(os.path.expanduser(homedir)) is True:
692           c.home_dir = os.path.expanduser(homedir)
693       else:
694           pass
695   elif os.path.exists(homedir) is True:
696       c.home_dir = homedir
697   else:
698       pass
699
700   try:
701       result = c.key_export_secret(pattern=logrus)
702   except:
703       result = c.key_export_secret(pattern=None)
704
705   if result is not None:
706       with open(keyfile, "wb") as f:
707           f.write(result)
708       os.chmod(keyfile, 0o600)
709   else:
710       pass
711 #+end_src
712
713 Alternatively the approach of the following script can be used.  This
714 longer example saves the exported secret key(s) in files in the GnuPG
715 home directory, in addition to setting the file permissions as only
716 readable and writable by the user.  It also exports the secret key(s)
717 twice in order to output both GPG binary (=.gpg=) and ASCII armoured
718 (=.asc=) files.
719
720 #+begin_src python
721   import gpg
722   import os
723   import os.path
724   import subprocess
725   import sys
726
727   print("""
728   This script exports one or more secret keys as both ASCII armored and binary
729   file formats, saved in files within the user's GPG home directory.
730
731   The gpg-agent and pinentry are invoked to authorise the export.
732   """)
733
734   if sys.platform == "win32":
735       gpgconfcmd = "gpgconf.exe --list-dirs homedir"
736   else:
737       gpgconfcmd = "gpgconf --list-dirs homedir"
738
739   a = gpg.Context(armor=True)
740   b = gpg.Context()
741   c = gpg.Context()
742
743   if len(sys.argv) >= 4:
744       keyfile = sys.argv[1]
745       logrus = sys.argv[2]
746       homedir = sys.argv[3]
747   elif len(sys.argv) == 3:
748       keyfile = sys.argv[1]
749       logrus = sys.argv[2]
750       homedir = input("Enter the GPG configuration directory path (optional): ")
751   elif len(sys.argv) == 2:
752       keyfile = sys.argv[1]
753       logrus = input("Enter the UID matching the secret key(s) to export: ")
754       homedir = input("Enter the GPG configuration directory path (optional): ")
755   else:
756       keyfile = input("Enter the filename to save the secret key to: ")
757       logrus = input("Enter the UID matching the secret key(s) to export: ")
758       homedir = input("Enter the GPG configuration directory path (optional): ")
759
760   if homedir.startswith("~"):
761       if os.path.exists(os.path.expanduser(homedir)) is True:
762           c.home_dir = os.path.expanduser(homedir)
763       else:
764           pass
765   elif os.path.exists(homedir) is True:
766       c.home_dir = homedir
767   else:
768       pass
769
770   if c.home_dir is not None:
771       if c.home_dir.endswith("/"):
772           gpgfile = "{0}{1}.gpg".format(c.home_dir, keyfile)
773           ascfile = "{0}{1}.asc".format(c.home_dir, keyfile)
774       else:
775           gpgfile = "{0}/{1}.gpg".format(c.home_dir, keyfile)
776           ascfile = "{0}/{1}.asc".format(c.home_dir, keyfile)
777   else:
778       if os.path.exists(os.environ["GNUPGHOME"]) is True:
779           hd = os.environ["GNUPGHOME"]
780       else:
781           hd = subprocess.getoutput(gpgconfcmd)
782       gpgfile = "{0}/{1}.gpg".format(hd, keyfile)
783       ascfile = "{0}/{1}.asc".format(hd, keyfile)
784
785   try:
786       a_result = a.key_export_secret(pattern=logrus)
787       b_result = b.key_export_secret(pattern=logrus)
788   except:
789       a_result = a.key_export_secret(pattern=None)
790       b_result = b.key_export_secret(pattern=None)
791
792   if a_result is not None:
793       with open(ascfile, "wb") as f:
794           f.write(a_result)
795       os.chmod(ascfile, 0o600)
796   else:
797       pass
798
799   if b_result is not None:
800       with open(gpgfile, "wb") as f:
801           f.write(b_result)
802       os.chmod(gpgfile, 0o600)
803   else:
804       pass
805 #+end_src
806
807
808 * Basic Functions
809   :PROPERTIES:
810   :CUSTOM_ID: howto-the-basics
811   :END:
812
813 The most frequently called features of any cryptographic library will
814 be the most fundamental tasks for encryption software.  In this
815 section we will look at how to programmatically encrypt data, decrypt
816 it, sign it and verify signatures.
817
818
819 ** Encryption
820    :PROPERTIES:
821    :CUSTOM_ID: howto-basic-encryption
822    :END:
823
824 Encrypting is very straight forward.  In the first example below the
825 message, =text=, is encrypted to a single recipient's key.  In the
826 second example the message will be encrypted to multiple recipients.
827
828
829 *** Encrypting to one key
830     :PROPERTIES:
831     :CUSTOM_ID: howto-basic-encryption-single
832     :END:
833
834 Once the the Context is set the main issues with encrypting data is
835 essentially reduced to key selection and the keyword arguments
836 specified in the =gpg.Context().encrypt()= method.
837
838 Those keyword arguments are: =recipients=, a list of keys encrypted to
839 (covered in greater detail in the following section); =sign=, whether
840 or not to sign the plaintext data, see subsequent sections on signing
841 and verifying signatures below (defaults to =True=); =sink=, to write
842 results or partial results to a secure sink instead of returning it
843 (defaults to =None=); =passphrase=, only used when utilising symmetric
844 encryption (defaults to =None=); =always_trust=, used to override the
845 trust model settings for recipient keys (defaults to =False=);
846 =add_encrypt_to=, utilises any preconfigured =encrypt-to= or
847 =default-key= settings in the user's =gpg.conf= file (defaults to
848 =False=); =prepare=, prepare for encryption (defaults to =False=);
849 =expect_sign=, prepare for signing (defaults to =False=); =compress=,
850 compresses the plaintext prior to encryption (defaults to =True=).
851
852 #+begin_src python
853   import gpg
854
855   a_key = "0x12345678DEADBEEF"
856   text = b"""Some text to test with.
857
858   Since the text in this case must be bytes, it is most likely that
859   the input form will be a separate file which is opened with "rb"
860   as this is the simplest method of obtaining the correct data
861   format.
862   """
863
864   c = gpg.Context(armor=True)
865   rkey = list(c.keylist(pattern=a_key, secret=False))
866   ciphertext, result, sign_result = c.encrypt(text, recipients=rkey, sign=False)
867
868   with open("secret_plans.txt.asc", "wb") as afile:
869       afile.write(ciphertext)
870 #+end_src
871
872 Though this is even more likely to be used like this; with the
873 plaintext input read from a file, the recipient keys used for
874 encryption regardless of key trust status and the encrypted output
875 also encrypted to any preconfigured keys set in the =gpg.conf= file:
876
877 #+begin_src python
878   import gpg
879
880   a_key = "0x12345678DEADBEEF"
881
882   with open("secret_plans.txt", "rb") as afile:
883       text = afile.read()
884
885   c = gpg.Context(armor=True)
886   rkey = list(c.keylist(pattern=a_key, secret=False))
887   ciphertext, result, sign_result = c.encrypt(text, recipients=rkey, sign=True,
888                                               always_trust=True,
889                                               add_encrypt_to=True)
890
891   with open("secret_plans.txt.asc", "wb") as afile:
892       afile.write(ciphertext)
893 #+end_src
894
895 If the =recipients= paramater is empty then the plaintext is encrypted
896 symmetrically.  If no =passphrase= is supplied as a parameter or via a
897 callback registered with the =Context()= then an out-of-band prompt
898 for the passphrase via pinentry will be invoked.
899
900
901 *** Encrypting to multiple keys
902     :PROPERTIES:
903     :CUSTOM_ID: howto-basic-encryption-multiple
904     :END:
905
906 Encrypting to multiple keys essentially just expands upon the key
907 selection process and the recipients from the previous examples.
908
909 The following example encrypts a message (=text=) to everyone with an
910 email address on the =gnupg.org= domain,[fn:3] but does /not/ encrypt
911 to a default key or other key which is configured to normally encrypt
912 to.
913
914 #+begin_src python
915   import gpg
916
917   text = b"""Oh look, another test message.
918
919   The same rules apply as with the previous example and more likely
920   than not, the message will actually be drawn from reading the
921   contents of a file or, maybe, from entering data at an input()
922   prompt.
923
924   Since the text in this case must be bytes, it is most likely that
925   the input form will be a separate file which is opened with "rb"
926   as this is the simplest method of obtaining the correct data
927   format.
928   """
929
930   c = gpg.Context(armor=True)
931   rpattern = list(c.keylist(pattern="@gnupg.org", secret=False))
932   logrus = []
933
934   for i in range(len(rpattern)):
935       if rpattern[i].can_encrypt == 1:
936           logrus.append(rpattern[i])
937
938   ciphertext, result, sign_result = c.encrypt(text, recipients=logrus,
939                                               sign=False, always_trust=True)
940
941   with open("secret_plans.txt.asc", "wb") as afile:
942       afile.write(ciphertext)
943 #+end_src
944
945 All it would take to change the above example to sign the message
946 and also encrypt the message to any configured default keys would
947 be to change the =c.encrypt= line to this:
948
949 #+begin_src python
950   ciphertext, result, sign_result = c.encrypt(text, recipients=logrus,
951                                               always_trust=True,
952                                               add_encrypt_to=True)
953 #+end_src
954
955 The only keyword arguments requiring modification are those for which
956 the default values are changing.  The default value of =sign= is
957 =True=, the default of =always_trust= is =False=, the default of
958 =add_encrypt_to= is =False=.
959
960 If =always_trust= is not set to =True= and any of the recipient keys
961 are not trusted (e.g. not signed or locally signed) then the
962 encryption will raise an error.  It is possible to mitigate this
963 somewhat with something more like this:
964
965 #+begin_src python
966   import gpg
967
968   with open("secret_plans.txt.asc", "rb") as afile:
969       text = afile.read()
970
971   c = gpg.Context(armor=True)
972   rpattern = list(c.keylist(pattern="@gnupg.org", secret=False))
973   logrus = []
974
975   for i in range(len(rpattern)):
976       if rpattern[i].can_encrypt == 1:
977           logrus.append(rpattern[i])
978
979       try:
980           ciphertext, result, sign_result = c.encrypt(text, recipients=logrus,
981                                                       add_encrypt_to=True)
982       except gpg.errors.InvalidRecipients as e:
983           for i in range(len(e.recipients)):
984               for n in range(len(logrus)):
985                   if logrus[n].fpr == e.recipients[i].fpr:
986                       logrus.remove(logrus[n])
987                   else:
988                       pass
989           try:
990               ciphertext, result, sign_result = c.encrypt(text,
991                                                           recipients=logrus,
992                                                           add_encrypt_to=True)
993               with open("secret_plans.txt.asc", "wb") as afile:
994                   afile.write(ciphertext)
995           except:
996               pass
997 #+end_src
998
999 This will attempt to encrypt to all the keys searched for, then remove
1000 invalid recipients if it fails and try again.
1001
1002
1003 ** Decryption
1004    :PROPERTIES:
1005    :CUSTOM_ID: howto-basic-decryption
1006    :END:
1007
1008 Decrypting something encrypted to a key in one's secret keyring is
1009 fairly straight forward.
1010
1011 In this example code, however, preconfiguring either =gpg.Context()=
1012 or =gpg.core.Context()= as =c= is unnecessary because there is no need
1013 to modify the Context prior to conducting the decryption and since the
1014 Context is only used once, setting it to =c= simply adds lines for no
1015 gain.
1016
1017 #+begin_src python
1018   import gpg
1019
1020   ciphertext = input("Enter path and filename of encrypted file: ")
1021   newfile = input("Enter path and filename of file to save decrypted data to: ")
1022
1023   with open(ciphertext, "rb") as cfile:
1024       try:
1025           plaintext, result, verify_result = gpg.Context().decrypt(cfile)
1026       except gpg.errors.GPGMEError as e:
1027           plaintext = None
1028           print(e)
1029
1030   if plaintext is not None:
1031       with open(newfile, "wb") as nfile:
1032           nfile.write(plaintext)
1033   else:
1034       pass
1035 #+end_src
1036
1037 The data available in =plaintext= in this example is the decrypted
1038 content as a byte object, the recipient key IDs and algorithms in
1039 =result= and the results of verifying any signatures of the data in
1040 =verify_result=.
1041
1042
1043 ** Signing text and files
1044    :PROPERTIES:
1045    :CUSTOM_ID: howto-basic-signing
1046    :END:
1047
1048 The following sections demonstrate how to specify keys to sign with.
1049
1050
1051 *** Signing key selection
1052     :PROPERTIES:
1053     :CUSTOM_ID: howto-basic-signing-signers
1054     :END:
1055
1056 By default GPGME and the Python bindings will use the default key
1057 configured for the user invoking the GPGME API.  If there is no
1058 default key specified and there is more than one secret key available
1059 it may be necessary to specify the key or keys with which to sign
1060 messages and files.
1061
1062 #+begin_src python
1063   import gpg
1064
1065   logrus = input("Enter the email address or string to match signing keys to: ")
1066   hancock = gpg.Context().keylist(pattern=logrus, secret=True)
1067   sig_src = list(hancock)
1068 #+end_src
1069
1070 The signing examples in the following sections include the explicitly
1071 designated =signers= parameter in two of the five examples; once where
1072 the resulting signature would be ASCII armoured and once where it
1073 would not be armoured.
1074
1075 While it would be possible to enter a key ID or fingerprint here to
1076 match a specific key, it is not possible to enter two fingerprints and
1077 match two keys since the patten expects a string, bytes or None and
1078 not a list.  A string with two fingerprints won't match any single
1079 key.
1080
1081
1082 *** Normal or default signing messages or files
1083     :PROPERTIES:
1084     :CUSTOM_ID: howto-basic-signing-normal
1085     :END:
1086
1087 The normal or default signing process is essentially the same as is
1088 most often invoked when also encrypting a message or file.  So when
1089 the encryption component is not utilised, the result is to produce an
1090 encoded and signed output which may or may not be ASCII armoured and
1091 which may or may not also be compressed.
1092
1093 By default compression will be used unless GnuPG detects that the
1094 plaintext is already compressed.  ASCII armouring will be determined
1095 according to the value of =gpg.Context().armor=.
1096
1097 The compression algorithm is selected in much the same way as the
1098 symmetric encryption algorithm or the hash digest algorithm is when
1099 multiple keys are involved; from the preferences saved into the key
1100 itself or by comparison with the preferences with all other keys
1101 involved.
1102
1103 #+begin_src python
1104   import gpg
1105
1106   text0 = """Declaration of ... something.
1107
1108   """
1109   text = text0.encode()
1110
1111   c = gpg.Context(armor=True, signers=sig_src)
1112   signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.NORMAL)
1113
1114   with open("/path/to/statement.txt.asc", "w") as afile:
1115       afile.write(signed_data.decode())
1116 #+end_src
1117
1118 Though everything in this example is accurate, it is more likely that
1119 reading the input data from another file and writing the result to a
1120 new file will be performed more like the way it is done in the next
1121 example.  Even if the output format is ASCII armoured.
1122
1123 #+begin_src python
1124   import gpg
1125
1126   with open("/path/to/statement.txt", "rb") as tfile:
1127       text = tfile.read()
1128
1129   c = gpg.Context()
1130   signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.NORMAL)
1131
1132   with open("/path/to/statement.txt.sig", "wb") as afile:
1133       afile.write(signed_data)
1134 #+end_src
1135
1136
1137 *** Detached signing messages and files
1138     :PROPERTIES:
1139     :CUSTOM_ID: howto-basic-signing-detached
1140     :END:
1141
1142 Detached signatures will often be needed in programmatic uses of
1143 GPGME, either for signing files (e.g. tarballs of code releases) or as
1144 a component of message signing (e.g. PGP/MIME encoded email).
1145
1146 #+begin_src python
1147   import gpg
1148
1149   text0 = """Declaration of ... something.
1150
1151   """
1152   text = text0.encode()
1153
1154   c = gpg.Context(armor=True)
1155   signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.DETACH)
1156
1157   with open("/path/to/statement.txt.asc", "w") as afile:
1158       afile.write(signed_data.decode())
1159 #+end_src
1160
1161 As with normal signatures, detached signatures are best handled as
1162 byte literals, even when the output is ASCII armoured.
1163
1164 #+begin_src python
1165   import gpg
1166
1167   with open("/path/to/statement.txt", "rb") as tfile:
1168       text = tfile.read()
1169
1170   c = gpg.Context(signers=sig_src)
1171   signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.DETACH)
1172
1173   with open("/path/to/statement.txt.sig", "wb") as afile:
1174       afile.write(signed_data)
1175 #+end_src
1176
1177
1178 *** Clearsigning messages or text
1179     :PROPERTIES:
1180     :CUSTOM_ID: howto-basic-signing-clear
1181     :END:
1182
1183 Though PGP/in-line messages are no longer encouraged in favour of
1184 PGP/MIME, there is still sometimes value in utilising in-line
1185 signatures.  This is where clear-signed messages or text is of value.
1186
1187 #+begin_src python
1188   import gpg
1189
1190   text0 = """Declaration of ... something.
1191
1192   """
1193   text = text0.encode()
1194
1195   c = gpg.Context()
1196   signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.CLEAR)
1197
1198   with open("/path/to/statement.txt.asc", "w") as afile:
1199       afile.write(signed_data.decode())
1200 #+end_src
1201
1202 In spite of the appearance of a clear-signed message, the data handled
1203 by GPGME in signing it must still be byte literals.
1204
1205 #+begin_src python
1206   import gpg
1207
1208   with open("/path/to/statement.txt", "rb") as tfile:
1209       text = tfile.read()
1210
1211   c = gpg.Context()
1212   signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.CLEAR)
1213
1214   with open("/path/to/statement.txt.asc", "wb") as afile:
1215       afile.write(signed_data)
1216 #+end_src
1217
1218
1219 ** Signature verification
1220    :PROPERTIES:
1221    :CUSTOM_ID: howto-basic-verification
1222    :END:
1223
1224 Essentially there are two principal methods of verification of a
1225 signature.  The first of these is for use with the normal or default
1226 signing method and for clear-signed messages.  The second is for use
1227 with files and data with detached signatures.
1228
1229 The following example is intended for use with the default signing
1230 method where the file was not ASCII armoured:
1231
1232 #+begin_src python
1233   import gpg
1234   import time
1235
1236   filename = "statement.txt"
1237   gpg_file = "statement.txt.gpg"
1238
1239   c = gpg.Context()
1240
1241   try:
1242       data, result = c.verify(open(gpg_file))
1243       verified = True
1244   except gpg.errors.BadSignatures as e:
1245       verified = False
1246       print(e)
1247
1248   if verified is True:
1249       for i in range(len(result.signatures)):
1250           sign = result.signatures[i]
1251       print("""Good signature from:
1252   {0}
1253   with key {1}
1254   made at {2}
1255   """.format(c.get_key(sign.fpr).uids[0].uid, sign.fpr,
1256              time.ctime(sign.timestamp)))
1257   else:
1258       pass
1259 #+end_src
1260
1261 Whereas this next example, which is almost identical would work with
1262 normal ASCII armoured files and with clear-signed files:
1263
1264 #+begin_src python
1265   import gpg
1266   import time
1267
1268   filename = "statement.txt"
1269   asc_file = "statement.txt.asc"
1270
1271   c = gpg.Context()
1272
1273   try:
1274       data, result = c.verify(open(asc_file))
1275       verified = True
1276   except gpg.errors.BadSignatures as e:
1277       verified = False
1278       print(e)
1279
1280   if verified is True:
1281       for i in range(len(result.signatures)):
1282           sign = result.signatures[i]
1283       print("""Good signature from:
1284   {0}
1285   with key {1}
1286   made at {2}
1287   """.format(c.get_key(sign.fpr).uids[0].uid, sign.fpr,
1288              time.ctime(sign.timestamp)))
1289   else:
1290       pass
1291 #+end_src
1292
1293 In both of the previous examples it is also possible to compare the
1294 original data that was signed against the signed data in =data= to see
1295 if it matches with something like this:
1296
1297 #+begin_src python
1298   with open(filename, "rb") as afile:
1299       text = afile.read()
1300
1301   if text == data:
1302       print("Good signature.")
1303   else:
1304       pass
1305 #+end_src
1306
1307 The following two examples, however, deal with detached signatures.
1308 With his method of verification the data that was signed does not get
1309 returned since it is already being explicitly referenced in the first
1310 argument of =c.verify=.  So =data= is =None= and only the information
1311 in =result= is available.
1312
1313 #+begin_src python
1314   import gpg
1315   import time
1316
1317   filename = "statement.txt"
1318   sig_file = "statement.txt.sig"
1319
1320   c = gpg.Context()
1321
1322   try:
1323       data, result = c.verify(open(filename), open(sig_file))
1324       verified = True
1325   except gpg.errors.BadSignatures as e:
1326       verified = False
1327       print(e)
1328
1329   if verified is True:
1330       for i in range(len(result.signatures)):
1331           sign = result.signatures[i]
1332       print("""Good signature from:
1333   {0}
1334   with key {1}
1335   made at {2}
1336   """.format(c.get_key(sign.fpr).uids[0].uid, sign.fpr,
1337              time.ctime(sign.timestamp)))
1338   else:
1339       pass
1340 #+end_src
1341
1342 #+begin_src python
1343   import gpg
1344   import time
1345
1346   filename = "statement.txt"
1347   asc_file = "statement.txt.asc"
1348
1349   c = gpg.Context()
1350
1351   try:
1352       data, result = c.verify(open(filename), open(asc_file))
1353       verified = True
1354   except gpg.errors.BadSignatures as e:
1355       verified = False
1356       print(e)
1357
1358   if verified is True:
1359       for i in range(len(result.signatures)):
1360           sign = result.signatures[i]
1361       print("""Good signature from:
1362   {0}
1363   with key {1}
1364   made at {2}
1365   """.format(c.get_key(sign.fpr).uids[0].uid, sign.fpr,
1366              time.ctime(sign.timestamp)))
1367   else:
1368       pass
1369 #+end_src
1370
1371
1372 * Creating keys and subkeys
1373   :PROPERTIES:
1374   :CUSTOM_ID: key-generation
1375   :END:
1376
1377 The one thing, aside from GnuPG itself, that GPGME depends on, of
1378 course, is the keys themselves.  So it is necessary to be able to
1379 generate them and modify them by adding subkeys, revoking or disabling
1380 them, sometimes deleting them and doing the same for user IDs.
1381
1382 In the following examples a key will be created for the world's
1383 greatest secret agent, Danger Mouse.  Since Danger Mouse is a secret
1384 agent he needs to be able to protect information to =SECRET= level
1385 clearance, so his keys will be 3072-bit keys.
1386
1387 The pre-configured =gpg.conf= file which sets cipher, digest and other
1388 preferences contains the following configuration parameters:
1389
1390 #+begin_src conf
1391   expert
1392   allow-freeform-uid
1393   allow-secret-key-import
1394   trust-model tofu+pgp
1395   tofu-default-policy unknown
1396   enable-large-rsa
1397   enable-dsa2
1398   cert-digest-algo SHA512
1399   default-preference-list TWOFISH CAMELLIA256 AES256 CAMELLIA192 AES192 CAMELLIA128 AES BLOWFISH IDEA CAST5 3DES SHA512 SHA384 SHA256 SHA224 RIPEMD160 SHA1 ZLIB BZIP2 ZIP Uncompressed
1400   personal-cipher-preferences TWOFISH CAMELLIA256 AES256 CAMELLIA192 AES192 CAMELLIA128 AES BLOWFISH IDEA CAST5 3DES
1401   personal-digest-preferences SHA512 SHA384 SHA256 SHA224 RIPEMD160 SHA1
1402   personal-compress-preferences ZLIB BZIP2 ZIP Uncompressed
1403 #+end_src
1404
1405
1406 ** Primary key
1407    :PROPERTIES:
1408    :CUSTOM_ID: keygen-primary
1409    :END:
1410
1411 Generating a primary key uses the =create_key= method in a Context.
1412 It contains multiple arguments and keyword arguments, including:
1413 =userid=, =algorithm=, =expires_in=, =expires=, =sign=, =encrypt=,
1414 =certify=, =authenticate=, =passphrase= and =force=.  The defaults for
1415 all of those except =userid=, =algorithm=, =expires_in=, =expires= and
1416 =passphrase= is =False=.  The defaults for =algorithm= and
1417 =passphrase= is =None=.  The default for =expires_in= is =0=.  The
1418 default for =expires= is =True=.  There is no default for =userid=.
1419
1420 If =passphrase= is left as =None= then the key will not be generated
1421 with a passphrase, if =passphrase= is set to a string then that will
1422 be the passphrase and if =passphrase= is set to =True= then gpg-agent
1423 will launch pinentry to prompt for a passphrase.  For the sake of
1424 convenience, these examples will keep =passphrase= set to =None=.
1425
1426 #+begin_src python
1427   import gpg
1428
1429   c = gpg.Context()
1430
1431   c.home_dir = "~/.gnupg-dm"
1432   userid = "Danger Mouse <dm@secret.example.net>"
1433
1434   dmkey = c.create_key(userid, algorithm="rsa3072", expires_in=31536000,
1435                        sign=True, certify=True)
1436 #+end_src
1437
1438 One thing to note here is the use of setting the =c.home_dir=
1439 parameter.  This enables generating the key or keys in a different
1440 location.  In this case to keep the new key data created for this
1441 example in a separate location rather than adding it to existing and
1442 active key store data.  As with the default directory, =~/.gnupg=, any
1443 temporary or separate directory needs the permissions set to only
1444 permit access by the directory owner.  On posix systems this means
1445 setting the directory permissions to 700.
1446
1447 The =temp-homedir-config.py= script in the HOWTO examples directory
1448 will create an alternative homedir with these configuration options
1449 already set and the correct directory and file permissions.
1450
1451 The successful generation of the key can be confirmed via the returned
1452 =GenkeyResult= object, which includes the following data:
1453
1454 #+begin_src python
1455    print("""
1456    Fingerprint:  {0}
1457    Primary Key:  {1}
1458     Public Key:  {2}
1459     Secret Key:  {3}
1460    Sub Key:  {4}
1461   User IDs:  {5}
1462    """.format(dmkey.fpr, dmkey.primary, dmkey.pubkey, dmkey.seckey, dmkey.sub,
1463               dmkey.uid))
1464 #+end_src
1465
1466 Alternatively the information can be confirmed using the command line
1467 program:
1468
1469 #+begin_src shell
1470   bash-4.4$ gpg --homedir ~/.gnupg-dm -K
1471   ~/.gnupg-dm/pubring.kbx
1472   ----------------------
1473   sec   rsa3072 2018-03-15 [SC] [expires: 2019-03-15]
1474         177B7C25DB99745EE2EE13ED026D2F19E99E63AA
1475   uid           [ultimate] Danger Mouse <dm@secret.example.net>
1476
1477   bash-4.4$
1478 #+end_src
1479
1480 As with generating keys manually, to preconfigure expanded preferences
1481 for the cipher, digest and compression algorithms, the =gpg.conf= file
1482 must contain those details in the home directory in which the new key
1483 is being generated.  I used a cut down version of my own =gpg.conf=
1484 file in order to be able to generate this:
1485
1486 #+begin_src shell
1487   bash-4.4$ gpg --homedir ~/.gnupg-dm --edit-key 177B7C25DB99745EE2EE13ED026D2F19E99E63AA showpref quit
1488   Secret key is available.
1489
1490   sec  rsa3072/026D2F19E99E63AA
1491        created: 2018-03-15  expires: 2019-03-15  usage: SC
1492        trust: ultimate      validity: ultimate
1493   [ultimate] (1). Danger Mouse <dm@secret.example.net>
1494
1495   [ultimate] (1). Danger Mouse <dm@secret.example.net>
1496        Cipher: TWOFISH, CAMELLIA256, AES256, CAMELLIA192, AES192, CAMELLIA128, AES, BLOWFISH, IDEA, CAST5, 3DES
1497        Digest: SHA512, SHA384, SHA256, SHA224, RIPEMD160, SHA1
1498        Compression: ZLIB, BZIP2, ZIP, Uncompressed
1499        Features: MDC, Keyserver no-modify
1500
1501   bash-4.4$
1502 #+end_src
1503
1504
1505 ** Subkeys
1506    :PROPERTIES:
1507    :CUSTOM_ID: keygen-subkeys
1508    :END:
1509
1510 Adding subkeys to a primary key is fairly similar to creating the
1511 primary key with the =create_subkey= method.  Most of the arguments
1512 are the same, but not quite all.  Instead of the =userid= argument
1513 there is now a =key= argument for selecting which primary key to add
1514 the subkey to.
1515
1516 In the following example an encryption subkey will be added to the
1517 primary key.  Since Danger Mouse is a security conscious secret agent,
1518 this subkey will only be valid for about six months, half the length
1519 of the primary key.
1520
1521 #+begin_src python
1522   import gpg
1523
1524   c = gpg.Context()
1525   c.home_dir = "~/.gnupg-dm"
1526
1527   key = c.get_key(dmkey.fpr, secret=True)
1528   dmsub = c.create_subkey(key, algorithm="rsa3072", expires_in=15768000,
1529                           encrypt=True)
1530 #+end_src
1531
1532 As with the primary key, the results here can be checked with:
1533
1534 #+begin_src python
1535    print("""
1536    Fingerprint:  {0}
1537    Primary Key:  {1}
1538     Public Key:  {2}
1539     Secret Key:  {3}
1540    Sub Key:  {4}
1541   User IDs:  {5}
1542    """.format(dmsub.fpr, dmsub.primary, dmsub.pubkey, dmsub.seckey, dmsub.sub,
1543               dmsub.uid))
1544 #+end_src
1545
1546 As well as on the command line with:
1547
1548 #+begin_src shell
1549   bash-4.4$ gpg --homedir ~/.gnupg-dm -K
1550   ~/.gnupg-dm/pubring.kbx
1551   ----------------------
1552   sec   rsa3072 2018-03-15 [SC] [expires: 2019-03-15]
1553         177B7C25DB99745EE2EE13ED026D2F19E99E63AA
1554   uid           [ultimate] Danger Mouse <dm@secret.example.net>
1555   ssb   rsa3072 2018-03-15 [E] [expires: 2018-09-13]
1556
1557   bash-4.4$
1558 #+end_src
1559
1560
1561 ** User IDs
1562    :PROPERTIES:
1563    :CUSTOM_ID: keygen-uids
1564    :END:
1565
1566
1567 *** Adding User IDs
1568     :PROPERTIES:
1569     :CUSTOM_ID: keygen-uids-add
1570     :END:
1571
1572 By comparison to creating primary keys and subkeys, adding a new user
1573 ID to an existing key is much simpler.  The method used to do this is
1574 =key_add_uid= and the only arguments it takes are for the =key= and
1575 the new =uid=.
1576
1577 #+begin_src python
1578   import gpg
1579
1580   c = gpg.Context()
1581   c.home_dir = "~/.gnupg-dm"
1582
1583   dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA"
1584   key = c.get_key(dmfpr, secret=True)
1585   uid = "Danger Mouse <danger.mouse@secret.example.net>"
1586
1587   c.key_add_uid(key, uid)
1588 #+end_src
1589
1590 Unsurprisingly the result of this is:
1591
1592 #+begin_src shell
1593   bash-4.4$ gpg --homedir ~/.gnupg-dm -K
1594   ~/.gnupg-dm/pubring.kbx
1595   ----------------------
1596   sec   rsa3072 2018-03-15 [SC] [expires: 2019-03-15]
1597         177B7C25DB99745EE2EE13ED026D2F19E99E63AA
1598   uid           [ultimate] Danger Mouse <danger.mouse@secret.example.net>
1599   uid           [ultimate] Danger Mouse <dm@secret.example.net>
1600   ssb   rsa3072 2018-03-15 [E] [expires: 2018-09-13]
1601
1602   bash-4.4$
1603 #+end_src
1604
1605
1606 *** Revokinging User IDs
1607     :PROPERTIES:
1608     :CUSTOM_ID: keygen-uids-revoke
1609     :END:
1610
1611 Revoking a user ID is a fairly similar process, except that it uses
1612 the =key_revoke_uid= method.
1613
1614 #+begin_src python
1615   import gpg
1616
1617   c = gpg.Context()
1618   c.home_dir = "~/.gnupg-dm"
1619
1620   dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA"
1621   key = c.get_key(dmfpr, secret=True)
1622   uid = "Danger Mouse <danger.mouse@secret.example.net>"
1623
1624   c.key_revoke_uid(key, uid)
1625 #+end_src
1626
1627
1628 ** Key certification
1629    :PROPERTIES:
1630    :CUSTOM_ID: key-sign
1631    :END:
1632
1633 Since key certification is more frequently referred to as key signing,
1634 the method used to perform this function is =key_sign=.
1635
1636 The =key_sign= method takes four arguments: =key=, =uids=,
1637 =expires_in= and =local=.  The default value of =uids= is =None= and
1638 which results in all user IDs being selected.  The default value of
1639 both =expires_in= and =local= is =False=; which results in the
1640 signature never expiring and being able to be exported.
1641
1642 The =key= is the key being signed rather than the key doing the
1643 signing.  To change the key doing the signing refer to the signing key
1644 selection above for signing messages and files.
1645
1646 If the =uids= value is not =None= then it must either be a string to
1647 match a single user ID or a list of strings to match multiple user
1648 IDs.  In this case the matching of those strings must be precise and
1649 it is case sensitive.
1650
1651 To sign Danger Mouse's key for just the initial user ID with a
1652 signature which will last a little over a month, do this:
1653
1654 #+begin_src python
1655   import gpg
1656
1657   c = gpg.Context()
1658   uid = "Danger Mouse <dm@secret.example.net>"
1659
1660   dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA"
1661   key = c.get_key(dmfpr, secret=True)
1662   c.key_sign(key, uids=uid, expires_in=2764800)
1663 #+end_src
1664
1665
1666 * Miscellaneous work-arounds
1667   :PROPERTIES:
1668   :CUSTOM_ID: cheats-and-hacks
1669   :END:
1670
1671
1672 ** Group lines
1673    :PROPERTIES:
1674    :CUSTOM_ID: group-lines
1675    :END:
1676
1677 There is not yet an easy way to access groups configured in the
1678 gpg.conf file from within GPGME.  As a consequence these central
1679 groupings of keys cannot be shared amongst multiple programs, such as
1680 MUAs readily.
1681
1682 The following code, however, provides a work-around for obtaining this
1683 information in Python.
1684
1685 #+begin_src python
1686   import subprocess
1687
1688   lines = subprocess.getoutput("gpgconf --list-options gpg").splitlines()
1689
1690   for i in range(len(lines)):
1691       if lines[i].startswith("group") is True:
1692           line = lines[i]
1693       else:
1694           pass
1695
1696   groups = line.split(":")[-1].replace('"', '').split(',')
1697
1698   group_lines = []
1699   group_lists = []
1700
1701   for i in range(len(groups)):
1702       group_lines.append(groups[i].split("="))
1703       group_lists.append(groups[i].split("="))
1704
1705   for i in range(len(group_lists)):
1706       group_lists[i][1] = group_lists[i][1].split()
1707 #+end_src
1708
1709 The result of that code is that =group_lines= is a list of lists where
1710 =group_lines[i][0]= is the name of the group and =group_lines[i][1]=
1711 is the key IDs of the group as a string.
1712
1713 The =group_lists= result is very similar in that it is a list of
1714 lists.  The first part, =group_lists[i][0]= matches
1715 =group_lines[i][0]= as the name of the group, but =group_lists[i][1]=
1716 is the key IDs of the group as a string.
1717
1718 A demonstration of using the =groups.py= module is also available in
1719 the form of the executable =mutt-groups.py= script.  This second
1720 script reads all the group entries in a user's =gpg.conf= file and
1721 converts them into crypt-hooks suitable for use with the Mutt and
1722 Neomutt mail clients.
1723
1724
1725 * Copyright and Licensing
1726   :PROPERTIES:
1727   :CUSTOM_ID: copyright-and-license
1728   :END:
1729
1730
1731 ** Copyright (C) The GnuPG Project, 2018
1732    :PROPERTIES:
1733    :CUSTOM_ID: copyright
1734    :END:
1735
1736 Copyright © The GnuPG Project, 2018.
1737
1738
1739 ** License GPL compatible
1740    :PROPERTIES:
1741    :CUSTOM_ID: license
1742    :END:
1743
1744 This file is free software; as a special exception the author gives
1745 unlimited permission to copy and/or distribute it, with or without
1746 modifications, as long as this notice is preserved.
1747
1748 This file is distributed in the hope that it will be useful, but
1749 WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
1750 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
1751 PURPOSE.
1752
1753
1754 * Footnotes
1755
1756 [fn:1] =Short_History.org= and/or =Short_History.html=.
1757
1758 [fn:2] The =lang/python/docs/= directory in the GPGME source.
1759
1760 [fn:3] You probably don't really want to do this.  Searching the
1761 keyservers for "gnupg.org" produces over 400 results, the majority of
1762 which aren't actually at the gnupg.org domain, but just included a
1763 comment regarding the project in their key somewhere.
1764
1765 [fn:4] As Python 3.7 is a very recent release, it is not given
1766 priority over 3.6 yet, but will probably be prioritised by the release
1767 of Python 3.7.2.