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