[git] GPGME - branch, ben/export-keys, updated. gpgme-1.11.1-71-gfa1a4e0

by Ben McGinnes cvs at cvs.gnupg.org
Thu Jun 28 10:36:10 CEST 2018


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GnuPG Made Easy".

The branch, ben/export-keys has been updated
       via  fa1a4e0b25faf995ff1fbadd54917de23da59ebd (commit)
      from  6573eb339a2a657354d3290061b5a2f9e31dab85 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit fa1a4e0b25faf995ff1fbadd54917de23da59ebd
Author: Ben McGinnes <ben at adversary.org>
Date:   Thu Jun 28 18:33:51 2018 +1000

    docs: python bindings howto
    
    * Updated official doc (the org-mode file) with the instructions on
      importing and exporting both public and secret keys.

diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org
index 3325c08..6a3f9db 100644
--- a/lang/python/docs/GPGMEpythonHOWTOen.org
+++ b/lang/python/docs/GPGMEpythonHOWTOen.org
@@ -454,6 +454,364 @@
    literals with the fingerprint when getting a key in this way.
 
 
+** Importing keys
+   :PROPERTIES:
+   :CUSTOM_ID: howto-import-key
+   :END:
+
+   Importing keys is possible with the =key_import()= method and takes
+   one argument which is a bytes literal object containing either the
+   binary or ASCII armoured key data for one or more keys.
+
+   The following example retrieves one or more keys from the SKS
+   keyservers via the web using the requests module. Since requests
+   returns the content as a bytes literal object, we can then use that
+   directly to import the resulting data into our keybox.
+
+   #+begin_src python
+     import gpg
+     import os.path
+     import requests
+
+     c = gpg.Context()
+     url = "https://sks-keyservers.net/pks/lookup"
+     pattern = input("Enter the pattern to search for key or user IDs: ")
+     payload = { "op": "get", "search": pattern }
+
+     r = requests.get(url, verify=True, params=payload)
+     result = c.key_import(r.content)
+
+     if result is not None and hasattr(result, "considered") is False:
+	 print(result)
+     elif result is not None and hasattr(result, "considered") is True:
+	 num_keys = len(result.imports)
+	 new_revs = result.new_revocations
+	 new_sigs = result.new_signatures
+	 new_subs = result.new_sub_keys
+	 new_uids = result.new_user_ids
+	 new_scrt = result.secret_imported
+	 nochange = result.unchanged
+	 print("""
+     The total number of keys considered for import was:  {0}
+
+	Number of keys revoked:  {1}
+      Number of new signatures:  {2}
+	 Number of new subkeys:  {3}
+	Number of new user IDs:  {4}
+     Number of new secret keys:  {5}
+      Number of unchanged keys:  {6}
+
+     The key IDs for all considered keys were:
+     """.format(num_keys, new_revs, new_sigs, new_subs, new_uids, new_scrt,
+		 nochange))
+	 for i in range(num_keys):
+	     print(result.imports[i].fpr)
+	 print("")
+     else:
+	 pass
+   #+end_src
+
+   *NOTE:* When searching for a key ID of any length or a fingerprint
+   (without spaces), the SKS servers require the the leading =0x=
+   indicative of hexadecimal be included. Also note that the old short
+   key IDs (e.g. =0xDEADBEEF=) should no longer be used due to the
+   relative ease by which such key IDs can be reproduced, as
+   demonstrated by the Evil32 Project in 2014 (which was subsequently
+   exploited in 2016).
+
+
+** Exporting keys
+   :PROPERTIES:
+   :CUSTOM_ID: howto-export-key
+   :END:
+
+   Exporting keys remains a reasonably simple task, but has been
+   separated into three different functions for the OpenPGP
+   cryptographic engine.  Two of those functions are for exporting
+   public keys and the third is for exporting secret keys.
+
+
+*** Exporting public keys
+    :PROPERTIES:
+    :CUSTOM_ID: howto-export-public-key
+    :END:
+
+    There are two methods of exporting public keys, both of which are
+    very similar to the other.  The default method, =key_export()=,
+    will export a public key or keys matching a specified pattern as
+    normal.  The alternative, the =key_export_minimal()= method, will
+    do the same thing except producing a minimised output with extra
+    signatures and third party signatures or certifications removed.
+
+    #+begin_src python
+      import gpg
+      import os.path
+      import sys
+
+      print("""
+      This script exports one or more public keys.
+      """)
+
+      c = gpg.Context(armor=True)
+
+      if len(sys.argv) >= 4:
+	  keyfile = sys.argv[1]
+	  logrus = sys.argv[2]
+	  homedir = sys.argv[3]
+      elif len(sys.argv) == 3:
+	  keyfile = sys.argv[1]
+	  logrus = sys.argv[2]
+	  homedir = input("Enter the GPG configuration directory path (optional): ")
+      elif len(sys.argv) == 2:
+	  keyfile = sys.argv[1]
+	  logrus = input("Enter the UID matching the key(s) to export: ")
+	  homedir = input("Enter the GPG configuration directory path (optional): ")
+      else:
+	  keyfile = input("Enter the path and filename to save the secret key to: ")
+	  logrus = input("Enter the UID matching the key(s) to export: ")
+	  homedir = input("Enter the GPG configuration directory path (optional): ")
+
+      if homedir.startswith("~"):
+	  if os.path.exists(os.path.expanduser(homedir)) is True:
+	      c.home_dir = os.path.expanduser(homedir)
+	  else:
+	      pass
+      elif os.path.exists(homedir) is True:
+	  c.home_dir = homedir
+      else:
+	  pass
+
+      try:
+	  result = c.key_export(pattern=logrus)
+      except:
+	  result = c.key_export(pattern=None)
+
+      if result is not None:
+	  with open(keyfile, "wb") as f:
+	      f.write(result)
+      else:
+	  pass
+    #+end_src
+
+    It is important to note that the result will only return =None=
+    when a pattern has been entered for =logrus=, but it has not
+    matched any keys. When the search pattern itself is set to =None=
+    this triggers the exporting of the entire public keybox.
+
+    #+begin_src python
+      import gpg
+      import os.path
+      import sys
+
+      print("""
+      This script exports one or more public keys in minimised form.
+      """)
+
+      c = gpg.Context(armor=True)
+
+      if len(sys.argv) >= 4:
+	  keyfile = sys.argv[1]
+	  logrus = sys.argv[2]
+	  homedir = sys.argv[3]
+      elif len(sys.argv) == 3:
+	  keyfile = sys.argv[1]
+	  logrus = sys.argv[2]
+	  homedir = input("Enter the GPG configuration directory path (optional): ")
+      elif len(sys.argv) == 2:
+	  keyfile = sys.argv[1]
+	  logrus = input("Enter the UID matching the key(s) to export: ")
+	  homedir = input("Enter the GPG configuration directory path (optional): ")
+      else:
+	  keyfile = input("Enter the path and filename to save the secret key to: ")
+	  logrus = input("Enter the UID matching the key(s) to export: ")
+	  homedir = input("Enter the GPG configuration directory path (optional): ")
+
+      if homedir.startswith("~"):
+	  if os.path.exists(os.path.expanduser(homedir)) is True:
+	      c.home_dir = os.path.expanduser(homedir)
+	  else:
+	      pass
+      elif os.path.exists(homedir) is True:
+	  c.home_dir = homedir
+      else:
+	  pass
+
+      try:
+	  result = c.key_export_minimal(pattern=logrus)
+      except:
+	  result = c.key_export_minimal(pattern=None)
+
+      if result is not None:
+	  with open(keyfile, "wb") as f:
+	      f.write(result)
+      else:
+	  pass
+    #+end_src
+
+
+*** Exporting secret keys
+    :PROPERTIES:
+    :CUSTOM_ID: howto-export-secret-key
+    :END:
+
+    Exporting secret keys is, functionally, very similar to exporting
+    public keys; save for the invocation of =pinentry= via =gpg-agent=
+    in order to securely enter the key's passphrase and authorise the
+    export.
+
+    The following example exports the secret key to a file which is
+    then set with the same permissions as the output files created by
+    the command line secret key export options.
+
+    #+begin_src python
+      import gpg
+      import os
+      import os.path
+      import sys
+
+      print("""
+      This script exports one or more secret keys.
+
+      The gpg-agent and pinentry are invoked to authorise the export.
+      """)
+
+      c = gpg.Context(armor=True)
+
+      if len(sys.argv) >= 4:
+	  keyfile = sys.argv[1]
+	  logrus = sys.argv[2]
+	  homedir = sys.argv[3]
+      elif len(sys.argv) == 3:
+	  keyfile = sys.argv[1]
+	  logrus = sys.argv[2]
+	  homedir = input("Enter the GPG configuration directory path (optional): ")
+      elif len(sys.argv) == 2:
+	  keyfile = sys.argv[1]
+	  logrus = input("Enter the UID matching the secret key(s) to export: ")
+	  homedir = input("Enter the GPG configuration directory path (optional): ")
+      else:
+	  keyfile = input("Enter the path and filename to save the secret key to: ")
+	  logrus = input("Enter the UID matching the secret key(s) to export: ")
+	  homedir = input("Enter the GPG configuration directory path (optional): ")
+
+      if homedir.startswith("~"):
+	  if os.path.exists(os.path.expanduser(homedir)) is True:
+	      c.home_dir = os.path.expanduser(homedir)
+	  else:
+	      pass
+      elif os.path.exists(homedir) is True:
+	  c.home_dir = homedir
+      else:
+	  pass
+
+      try:
+	  result = c.key_export_secret(pattern=logrus)
+      except:
+	  result = c.key_export_secret(pattern=None)
+
+      if result is not None:
+	  with open(keyfile, "wb") as f:
+	      f.write(result)
+	  os.chmod(keyfile, 0o600)
+      else:
+	  pass
+    #+end_src
+
+    Alternatively the approach of the following script can be
+    used.  This longer example saves the exported secret key(s) in
+    files in the GnuPG home directory, in addition to setting the file
+    permissions as only readable and writable by the user.  It also
+    exports the secret key(s) twice in order to output both GPG binary
+    (=.gpg=) and ASCII armoured (=.asc=) files.
+
+    #+begin_src python
+      import gpg
+      import os
+      import os.path
+      import subprocess
+      import sys
+
+      print("""
+      This script exports one or more secret keys as both ASCII armored and binary
+      file formats, saved in files within the user's GPG home directory.
+
+      The gpg-agent and pinentry are invoked to authorise the export.
+      """)
+
+      if sys.platform == "win32":
+	  gpgconfcmd = "gpgconf.exe --list-dirs homedir"
+      else:
+	  gpgconfcmd = "gpgconf --list-dirs homedir"
+
+      a = gpg.Context(armor=True)
+      b = gpg.Context()
+      c = gpg.Context()
+
+      if len(sys.argv) >= 4:
+	  keyfile = sys.argv[1]
+	  logrus = sys.argv[2]
+	  homedir = sys.argv[3]
+      elif len(sys.argv) == 3:
+	  keyfile = sys.argv[1]
+	  logrus = sys.argv[2]
+	  homedir = input("Enter the GPG configuration directory path (optional): ")
+      elif len(sys.argv) == 2:
+	  keyfile = sys.argv[1]
+	  logrus = input("Enter the UID matching the secret key(s) to export: ")
+	  homedir = input("Enter the GPG configuration directory path (optional): ")
+      else:
+	  keyfile = input("Enter the filename to save the secret key to: ")
+	  logrus = input("Enter the UID matching the secret key(s) to export: ")
+	  homedir = input("Enter the GPG configuration directory path (optional): ")
+
+      if homedir.startswith("~"):
+	  if os.path.exists(os.path.expanduser(homedir)) is True:
+	      c.home_dir = os.path.expanduser(homedir)
+	  else:
+	      pass
+      elif os.path.exists(homedir) is True:
+	  c.home_dir = homedir
+      else:
+	  pass
+
+      if c.home_dir is not None:
+	  if c.home_dir.endswith("/"):
+	      gpgfile = "{0}{1}.gpg".format(c.home_dir, keyfile)
+	      ascfile = "{0}{1}.asc".format(c.home_dir, keyfile)
+	  else:
+	      gpgfile = "{0}/{1}.gpg".format(c.home_dir, keyfile)
+	      ascfile = "{0}/{1}.asc".format(c.home_dir, keyfile)
+      else:
+	  if os.path.exists(os.environ["GNUPGHOME"]) is True:
+	      hd = os.environ["GNUPGHOME"]
+	  else:
+	      hd = subprocess.getoutput(gpgconfcmd)
+	  gpgfile = "{0}/{1}.gpg".format(hd, keyfile)
+	  ascfile = "{0}/{1}.asc".format(hd, keyfile)
+
+      try:
+	  a_result = a.key_export_secret(pattern=logrus)
+	  b_result = b.key_export_secret(pattern=logrus)
+      except:
+	  a_result = a.key_export_secret(pattern=None)
+	  b_result = b.key_export_secret(pattern=None)
+
+      if a_result is not None:
+	  with open(ascfile, "wb") as f:
+	      f.write(a_result)
+	  os.chmod(ascfile, 0o600)
+      else:
+	  pass
+
+      if b_result is not None:
+	  with open(gpgfile, "wb") as f:
+	      f.write(b_result)
+	  os.chmod(gpgfile, 0o600)
+      else:
+	  pass
+    #+end_src
+
+
 * Basic Functions
   :PROPERTIES:
   :CUSTOM_ID: howto-the-basics

-----------------------------------------------------------------------

Summary of changes:
 lang/python/docs/GPGMEpythonHOWTOen.org | 358 ++++++++++++++++++++++++++++++++
 1 file changed, 358 insertions(+)


hooks/post-receive
-- 
GnuPG Made Easy
http://git.gnupg.org




More information about the Gnupg-commits mailing list