diff options
Diffstat (limited to 'lang/python/docs')
| -rw-r--r-- | lang/python/docs/GPGMEpythonHOWTOen.org | 1247 | 
1 files changed, 623 insertions, 624 deletions
| diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index df37226b..c40772f2 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -340,40 +340,40 @@ pattern is upper or lower case.  So this is the best method: -#+begin_src python -  import gpg +#+begin_src python -i +import gpg -  k = gpg.Context().keylist(pattern="258E88DCBD3CD44D8E7AB43F6ECB6AF0DEADBEEF") -  keys = list(k) +k = gpg.Context().keylist(pattern="258E88DCBD3CD44D8E7AB43F6ECB6AF0DEADBEEF") +keys = list(k)  #+end_src  This is passable and very likely to be common: -#+begin_src python -  import gpg +#+begin_src python -i +import gpg -  k = gpg.Context().keylist(pattern="0x6ECB6AF0DEADBEEF") -  keys = list(k) +k = gpg.Context().keylist(pattern="0x6ECB6AF0DEADBEEF") +keys = list(k)  #+end_src  And this is a really bad idea: -#+begin_src python -  import gpg +#+begin_src python -i +import gpg -  k = gpg.Context().keylist(pattern="0xDEADBEEF") -  keys = list(k) +k = gpg.Context().keylist(pattern="0xDEADBEEF") +keys = list(k)  #+end_src  Alternatively it may be that the intention is to create a list of keys  which all match a particular search string.  For instance all the  addresses at a particular domain, like this: -#+begin_src python -  import gpg +#+begin_src python -i +import gpg -  ncsc = gpg.Context().keylist(pattern="ncsc.mil") -  nsa = list(ncsc) +ncsc = gpg.Context().keylist(pattern="ncsc.mil") +nsa = list(ncsc)  #+end_src @@ -386,23 +386,23 @@ Counting the number of keys in your public keybox (=pubring.kbx=), the  format which has superseded the old keyring format (=pubring.gpg= and  =secring.gpg=), or the number of secret keys is a very simple task. -#+begin_src python -  import gpg +#+begin_src python -i +import gpg -  c = gpg.Context() -  seckeys = c.keylist(pattern=None, secret=True) -  pubkeys = c.keylist(pattern=None, secret=False) +c = gpg.Context() +seckeys = c.keylist(pattern=None, secret=True) +pubkeys = c.keylist(pattern=None, secret=False) -  seclist = list(seckeys) -  secnum = len(seclist) +seclist = list(seckeys) +secnum = len(seclist) -  publist = list(pubkeys) -  pubnum = len(publist) +publist = list(pubkeys) +pubnum = len(publist) -  print(""" +print("""    Number of secret keys:  {0}    Number of public keys:  {1} -  """.format(secnum, pubnum)) +""".format(secnum, pubnum))  #+end_src @@ -424,21 +424,21 @@ secret keys as well.  This first example demonstrates selecting the current key of Werner  Koch, which is due to expire at the end of 2018: -#+begin_src python -  import gpg +#+begin_src python -i +import gpg -  fingerprint = "80615870F5BAD690333686D0F2AD85AC1E42B367" -  key = gpg.Context().get_key(fingerprint) +fingerprint = "80615870F5BAD690333686D0F2AD85AC1E42B367" +key = gpg.Context().get_key(fingerprint)  #+end_src  Whereas this example demonstrates selecting the author's current key  with the =secret= key word argument set to =True=: -#+begin_src python -  import gpg +#+begin_src python -i +import gpg -  fingerprint = "DB4724E6FA4286C92B4E55C4321E4E2373590E5D" -  key = gpg.Context().get_key(fingerprint, secret=True) +fingerprint = "DB4724E6FA4286C92B4E55C4321E4E2373590E5D" +key = gpg.Context().get_key(fingerprint, secret=True)  #+end_src  It is, of course, quite possible to select expired, disabled and @@ -463,30 +463,30 @@ 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(""" +#+begin_src python -i +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} @@ -497,13 +497,13 @@ directly to import the resulting data into our keybox.     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 +""".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 @@ -538,54 +538,54 @@ 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 +#+begin_src python -i +import gpg +import os.path +import sys -  print(""" +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 +""") + +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 @@ -593,54 +593,54 @@ 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 +#+begin_src python -i +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 @@ -657,58 +657,58 @@ 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 +#+begin_src python -i +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 @@ -718,91 +718,91 @@ 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 +#+begin_src python -i +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 @@ -850,24 +850,23 @@ trust model settings for recipient keys (defaults to =False=);  =expect_sign=, prepare for signing (defaults to =False=); =compress=,  compresses the plaintext prior to encryption (defaults to =True=). -#+begin_src python -  import gpg +#+begin_src python -i +import gpg -  a_key = "0x12345678DEADBEEF" -  text = b"""Some text to test with. +a_key = "0x12345678DEADBEEF" +text = b"""Some text to test with. -  Since the text in this case must be bytes, it is most likely that -  the input form will be a separate file which is opened with "rb" -  as this is the simplest method of obtaining the correct data -  format. -  """ +Since the text in this case must be bytes, it is most likely that +the input form will be a separate file which is opened with "rb" +as this is the simplest method of obtaining the correct data format. +""" -  c = gpg.Context(armor=True) -  rkey = list(c.keylist(pattern=a_key, secret=False)) -  ciphertext, result, sign_result = c.encrypt(text, recipients=rkey, sign=False) +c = gpg.Context(armor=True) +rkey = list(c.keylist(pattern=a_key, secret=False)) +ciphertext, result, sign_result = c.encrypt(text, recipients=rkey, sign=False) -  with open("secret_plans.txt.asc", "wb") as afile: -      afile.write(ciphertext) +with open("secret_plans.txt.asc", "wb") as afile: +    afile.write(ciphertext)  #+end_src  Though this is even more likely to be used like this; with the @@ -875,22 +874,22 @@ plaintext input read from a file, the recipient keys used for  encryption regardless of key trust status and the encrypted output  also encrypted to any preconfigured keys set in the =gpg.conf= file: -#+begin_src python -  import gpg +#+begin_src python -i +import gpg -  a_key = "0x12345678DEADBEEF" +a_key = "0x12345678DEADBEEF" -  with open("secret_plans.txt", "rb") as afile: -      text = afile.read() +with open("secret_plans.txt", "rb") as afile: +    text = afile.read() -  c = gpg.Context(armor=True) -  rkey = list(c.keylist(pattern=a_key, secret=False)) -  ciphertext, result, sign_result = c.encrypt(text, recipients=rkey, sign=True, -					      always_trust=True, -					      add_encrypt_to=True) +c = gpg.Context(armor=True) +rkey = list(c.keylist(pattern=a_key, secret=False)) +ciphertext, result, sign_result = c.encrypt(text, recipients=rkey, sign=True, +					    always_trust=True, +					    add_encrypt_to=True) -  with open("secret_plans.txt.asc", "wb") as afile: -      afile.write(ciphertext) +with open("secret_plans.txt.asc", "wb") as afile: +    afile.write(ciphertext)  #+end_src  If the =recipients= paramater is empty then the plaintext is encrypted @@ -912,45 +911,45 @@ email address on the =gnupg.org= domain,[fn:3] but does /not/ encrypt  to a default key or other key which is configured to normally encrypt  to. -#+begin_src python -  import gpg +#+begin_src python -i +import gpg -  text = b"""Oh look, another test message. +text = b"""Oh look, another test message. -  The same rules apply as with the previous example and more likely -  than not, the message will actually be drawn from reading the -  contents of a file or, maybe, from entering data at an input() -  prompt. +The same rules apply as with the previous example and more likely +than not, the message will actually be drawn from reading the +contents of a file or, maybe, from entering data at an input() +prompt. -  Since the text in this case must be bytes, it is most likely that -  the input form will be a separate file which is opened with "rb" -  as this is the simplest method of obtaining the correct data -  format. -  """ +Since the text in this case must be bytes, it is most likely that +the input form will be a separate file which is opened with "rb" +as this is the simplest method of obtaining the correct data +format. +""" -  c = gpg.Context(armor=True) -  rpattern = list(c.keylist(pattern="@gnupg.org", secret=False)) -  logrus = [] +c = gpg.Context(armor=True) +rpattern = list(c.keylist(pattern="@gnupg.org", secret=False)) +logrus = [] -  for i in range(len(rpattern)): -      if rpattern[i].can_encrypt == 1: -	  logrus.append(rpattern[i]) +for i in range(len(rpattern)): +    if rpattern[i].can_encrypt == 1: +	logrus.append(rpattern[i]) -  ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, -					      sign=False, always_trust=True) +ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, +					    sign=False, always_trust=True) -  with open("secret_plans.txt.asc", "wb") as afile: -      afile.write(ciphertext) +with open("secret_plans.txt.asc", "wb") as afile: +    afile.write(ciphertext)  #+end_src  All it would take to change the above example to sign the message  and also encrypt the message to any configured default keys would  be to change the =c.encrypt= line to this: -#+begin_src python -  ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, -					      always_trust=True, -					      add_encrypt_to=True) +#+begin_src python -i +ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, +					    always_trust=True, +					    add_encrypt_to=True)  #+end_src  The only keyword arguments requiring modification are those for which @@ -963,38 +962,38 @@ are not trusted (e.g. not signed or locally signed) then the  encryption will raise an error.  It is possible to mitigate this  somewhat with something more like this: -#+begin_src python -  import gpg - -  with open("secret_plans.txt.asc", "rb") as afile: -      text = afile.read() - -  c = gpg.Context(armor=True) -  rpattern = list(c.keylist(pattern="@gnupg.org", secret=False)) -  logrus = [] - -  for i in range(len(rpattern)): -      if rpattern[i].can_encrypt == 1: -	  logrus.append(rpattern[i]) - -      try: -	  ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, -						      add_encrypt_to=True) -      except gpg.errors.InvalidRecipients as e: -	  for i in range(len(e.recipients)): -	      for n in range(len(logrus)): -		  if logrus[n].fpr == e.recipients[i].fpr: -		      logrus.remove(logrus[n]) -		  else: -		      pass -	  try: -	      ciphertext, result, sign_result = c.encrypt(text, -							  recipients=logrus, -							  add_encrypt_to=True) -	      with open("secret_plans.txt.asc", "wb") as afile: -		  afile.write(ciphertext) -	  except: -	      pass +#+begin_src python -i +import gpg + +with open("secret_plans.txt.asc", "rb") as afile: +    text = afile.read() + +c = gpg.Context(armor=True) +rpattern = list(c.keylist(pattern="@gnupg.org", secret=False)) +logrus = [] + +for i in range(len(rpattern)): +    if rpattern[i].can_encrypt == 1: +	logrus.append(rpattern[i]) + +    try: +	ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, +						    add_encrypt_to=True) +    except gpg.errors.InvalidRecipients as e: +	for i in range(len(e.recipients)): +	    for n in range(len(logrus)): +		if logrus[n].fpr == e.recipients[i].fpr: +		    logrus.remove(logrus[n]) +		else: +		    pass +	try: +	    ciphertext, result, sign_result = c.encrypt(text, +							recipients=logrus, +							add_encrypt_to=True) +	    with open("secret_plans.txt.asc", "wb") as afile: +		afile.write(ciphertext) +	except: +	    pass  #+end_src  This will attempt to encrypt to all the keys searched for, then remove @@ -1015,24 +1014,24 @@ to modify the Context prior to conducting the decryption and since the  Context is only used once, setting it to =c= simply adds lines for no  gain. -#+begin_src python -  import gpg +#+begin_src python -i +import gpg -  ciphertext = input("Enter path and filename of encrypted file: ") -  newfile = input("Enter path and filename of file to save decrypted data to: ") +ciphertext = input("Enter path and filename of encrypted file: ") +newfile = input("Enter path and filename of file to save decrypted data to: ") -  with open(ciphertext, "rb") as cfile: -      try: -	  plaintext, result, verify_result = gpg.Context().decrypt(cfile) -      except gpg.errors.GPGMEError as e: -	  plaintext = None -	  print(e) +with open(ciphertext, "rb") as cfile: +    try: +	plaintext, result, verify_result = gpg.Context().decrypt(cfile) +    except gpg.errors.GPGMEError as e: +	plaintext = None +	print(e) -  if plaintext is not None: -      with open(newfile, "wb") as nfile: -	  nfile.write(plaintext) -  else: -      pass +    if plaintext is not None: +	with open(newfile, "wb") as nfile: +	    nfile.write(plaintext) +    else: +	pass  #+end_src  The data available in =plaintext= in this example is the decrypted @@ -1060,12 +1059,12 @@ default key specified and there is more than one secret key available  it may be necessary to specify the key or keys with which to sign  messages and files. -#+begin_src python -  import gpg +#+begin_src python -i +import gpg -  logrus = input("Enter the email address or string to match signing keys to: ") -  hancock = gpg.Context().keylist(pattern=logrus, secret=True) -  sig_src = list(hancock) +logrus = input("Enter the email address or string to match signing keys to: ") +hancock = gpg.Context().keylist(pattern=logrus, secret=True) +sig_src = list(hancock)  #+end_src  The signing examples in the following sections include the explicitly @@ -1101,19 +1100,19 @@ multiple keys are involved; from the preferences saved into the key  itself or by comparison with the preferences with all other keys  involved. -#+begin_src python -  import gpg +#+begin_src python -i +import gpg -  text0 = """Declaration of ... something. +text0 = """Declaration of ... something. -  """ -  text = text0.encode() +""" +text = text0.encode() -  c = gpg.Context(armor=True, signers=sig_src) -  signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.NORMAL) +c = gpg.Context(armor=True, signers=sig_src) +signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.NORMAL) -  with open("/path/to/statement.txt.asc", "w") as afile: -      afile.write(signed_data.decode()) +with open("/path/to/statement.txt.asc", "w") as afile: +    afile.write(signed_data.decode())  #+end_src  Though everything in this example is accurate, it is more likely that @@ -1121,17 +1120,17 @@ reading the input data from another file and writing the result to a  new file will be performed more like the way it is done in the next  example.  Even if the output format is ASCII armoured. -#+begin_src python -  import gpg +#+begin_src python -i +import gpg -  with open("/path/to/statement.txt", "rb") as tfile: -      text = tfile.read() +with open("/path/to/statement.txt", "rb") as tfile: +    text = tfile.read() -  c = gpg.Context() -  signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.NORMAL) +c = gpg.Context() +signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.NORMAL) -  with open("/path/to/statement.txt.sig", "wb") as afile: -      afile.write(signed_data) +with open("/path/to/statement.txt.sig", "wb") as afile: +    afile.write(signed_data)  #+end_src @@ -1144,35 +1143,35 @@ Detached signatures will often be needed in programmatic uses of  GPGME, either for signing files (e.g. tarballs of code releases) or as  a component of message signing (e.g. PGP/MIME encoded email). -#+begin_src python -  import gpg +#+begin_src python -i +import gpg -  text0 = """Declaration of ... something. +text0 = """Declaration of ... something. -  """ -  text = text0.encode() +""" +text = text0.encode() -  c = gpg.Context(armor=True) -  signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.DETACH) +c = gpg.Context(armor=True) +signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.DETACH) -  with open("/path/to/statement.txt.asc", "w") as afile: -      afile.write(signed_data.decode()) +with open("/path/to/statement.txt.asc", "w") as afile: +    afile.write(signed_data.decode())  #+end_src  As with normal signatures, detached signatures are best handled as  byte literals, even when the output is ASCII armoured. -#+begin_src python -  import gpg +#+begin_src python -i +import gpg -  with open("/path/to/statement.txt", "rb") as tfile: -      text = tfile.read() +with open("/path/to/statement.txt", "rb") as tfile: +    text = tfile.read() -  c = gpg.Context(signers=sig_src) -  signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.DETACH) +c = gpg.Context(signers=sig_src) +signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.DETACH) -  with open("/path/to/statement.txt.sig", "wb") as afile: -      afile.write(signed_data) +with open("/path/to/statement.txt.sig", "wb") as afile: +    afile.write(signed_data)  #+end_src @@ -1185,35 +1184,35 @@ Though PGP/in-line messages are no longer encouraged in favour of  PGP/MIME, there is still sometimes value in utilising in-line  signatures.  This is where clear-signed messages or text is of value. -#+begin_src python -  import gpg +#+begin_src python -i +import gpg -  text0 = """Declaration of ... something. +text0 = """Declaration of ... something. -  """ -  text = text0.encode() +""" +text = text0.encode() -  c = gpg.Context() -  signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.CLEAR) +c = gpg.Context() +signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.CLEAR) -  with open("/path/to/statement.txt.asc", "w") as afile: -      afile.write(signed_data.decode()) +with open("/path/to/statement.txt.asc", "w") as afile: +    afile.write(signed_data.decode())  #+end_src  In spite of the appearance of a clear-signed message, the data handled  by GPGME in signing it must still be byte literals. -#+begin_src python -  import gpg +#+begin_src python -i +import gpg -  with open("/path/to/statement.txt", "rb") as tfile: -      text = tfile.read() +with open("/path/to/statement.txt", "rb") as tfile: +    text = tfile.read() -  c = gpg.Context() -  signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.CLEAR) +c = gpg.Context() +signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.CLEAR) -  with open("/path/to/statement.txt.asc", "wb") as afile: -      afile.write(signed_data) +with open("/path/to/statement.txt.asc", "wb") as afile: +    afile.write(signed_data)  #+end_src @@ -1230,79 +1229,79 @@ with files and data with detached signatures.  The following example is intended for use with the default signing  method where the file was not ASCII armoured: -#+begin_src python -  import gpg -  import time - -  filename = "statement.txt" -  gpg_file = "statement.txt.gpg" - -  c = gpg.Context() - -  try: -      data, result = c.verify(open(gpg_file)) -      verified = True -  except gpg.errors.BadSignatures as e: -      verified = False -      print(e) - -  if verified is True: -      for i in range(len(result.signatures)): -	  sign = result.signatures[i] -      print("""Good signature from: -  {0} -  with key {1} -  made at {2} -  """.format(c.get_key(sign.fpr).uids[0].uid, sign.fpr, -	     time.ctime(sign.timestamp))) -  else: -      pass +#+begin_src python -i +import gpg +import time + +filename = "statement.txt" +gpg_file = "statement.txt.gpg" + +c = gpg.Context() + +try: +    data, result = c.verify(open(gpg_file)) +    verified = True +except gpg.errors.BadSignatures as e: +    verified = False +    print(e) + +if verified is True: +    for i in range(len(result.signatures)): +	sign = result.signatures[i] +	print("""Good signature from: +{0} +with key {1} +made at {2} +""".format(c.get_key(sign.fpr).uids[0].uid, sign.fpr, +	   time.ctime(sign.timestamp))) +else: +    pass  #+end_src  Whereas this next example, which is almost identical would work with  normal ASCII armoured files and with clear-signed files: -#+begin_src python -  import gpg -  import time - -  filename = "statement.txt" -  asc_file = "statement.txt.asc" - -  c = gpg.Context() - -  try: -      data, result = c.verify(open(asc_file)) -      verified = True -  except gpg.errors.BadSignatures as e: -      verified = False -      print(e) - -  if verified is True: -      for i in range(len(result.signatures)): -	  sign = result.signatures[i] -      print("""Good signature from: -  {0} -  with key {1} -  made at {2} -  """.format(c.get_key(sign.fpr).uids[0].uid, sign.fpr, -	     time.ctime(sign.timestamp))) -  else: -      pass +#+begin_src python -i +import gpg +import time + +filename = "statement.txt" +asc_file = "statement.txt.asc" + +c = gpg.Context() + +try: +    data, result = c.verify(open(asc_file)) +    verified = True +except gpg.errors.BadSignatures as e: +    verified = False +    print(e) + +if verified is True: +    for i in range(len(result.signatures)): +	sign = result.signatures[i] +	print("""Good signature from: +{0} +with key {1} +made at {2} +""".format(c.get_key(sign.fpr).uids[0].uid, sign.fpr, +	   time.ctime(sign.timestamp))) +else: +    pass  #+end_src  In both of the previous examples it is also possible to compare the  original data that was signed against the signed data in =data= to see  if it matches with something like this: -#+begin_src python -  with open(filename, "rb") as afile: -      text = afile.read() +#+begin_src python -i +with open(filename, "rb") as afile: +    text = afile.read() -  if text == data: -      print("Good signature.") -  else: -      pass +if text == data: +    print("Good signature.") +else: +    pass  #+end_src  The following two examples, however, deal with detached signatures. @@ -1311,62 +1310,62 @@ returned since it is already being explicitly referenced in the first  argument of =c.verify=.  So =data= is =None= and only the information  in =result= is available. -#+begin_src python -  import gpg -  import time - -  filename = "statement.txt" -  sig_file = "statement.txt.sig" - -  c = gpg.Context() - -  try: -      data, result = c.verify(open(filename), open(sig_file)) -      verified = True -  except gpg.errors.BadSignatures as e: -      verified = False -      print(e) - -  if verified is True: -      for i in range(len(result.signatures)): -	  sign = result.signatures[i] -      print("""Good signature from: -  {0} -  with key {1} -  made at {2} -  """.format(c.get_key(sign.fpr).uids[0].uid, sign.fpr, -	     time.ctime(sign.timestamp))) -  else: -      pass +#+begin_src python -i +import gpg +import time + +filename = "statement.txt" +sig_file = "statement.txt.sig" + +c = gpg.Context() + +try: +    data, result = c.verify(open(filename), open(sig_file)) +    verified = True +except gpg.errors.BadSignatures as e: +    verified = False +    print(e) + +if verified is True: +    for i in range(len(result.signatures)): +	sign = result.signatures[i] +	print("""Good signature from: +{0} +with key {1} +made at {2} +""".format(c.get_key(sign.fpr).uids[0].uid, sign.fpr, +	   time.ctime(sign.timestamp))) +else: +    pass  #+end_src -#+begin_src python -  import gpg -  import time - -  filename = "statement.txt" -  asc_file = "statement.txt.asc" - -  c = gpg.Context() - -  try: -      data, result = c.verify(open(filename), open(asc_file)) -      verified = True -  except gpg.errors.BadSignatures as e: -      verified = False -      print(e) - -  if verified is True: -      for i in range(len(result.signatures)): -	  sign = result.signatures[i] -      print("""Good signature from: -  {0} -  with key {1} -  made at {2} -  """.format(c.get_key(sign.fpr).uids[0].uid, sign.fpr, -	     time.ctime(sign.timestamp))) -  else: -      pass +#+begin_src python -i +import gpg +import time + +filename = "statement.txt" +asc_file = "statement.txt.asc" + +c = gpg.Context() + +try: +    data, result = c.verify(open(filename), open(asc_file)) +    verified = True +except gpg.errors.BadSignatures as e: +    verified = False +    print(e) + +if verified is True: +    for i in range(len(result.signatures)): +	sign = result.signatures[i] +	print("""Good signature from: +{0} +with key {1} +made at {2} +""".format(c.get_key(sign.fpr).uids[0].uid, sign.fpr, +	   time.ctime(sign.timestamp))) +else: +    pass  #+end_src @@ -1424,16 +1423,16 @@ be the passphrase and if =passphrase= is set to =True= then gpg-agent  will launch pinentry to prompt for a passphrase.  For the sake of  convenience, these examples will keep =passphrase= set to =None=. -#+begin_src python -  import gpg +#+begin_src python -i +import gpg -  c = gpg.Context() +c = gpg.Context() -  c.home_dir = "~/.gnupg-dm" -  userid = "Danger Mouse <[email protected]>" +c.home_dir = "~/.gnupg-dm" +userid = "Danger Mouse <[email protected]>" -  dmkey = c.create_key(userid, algorithm="rsa3072", expires_in=31536000, -		       sign=True, certify=True) +dmkey = c.create_key(userid, algorithm="rsa3072", expires_in=31536000, +		     sign=True, certify=True)  #+end_src  One thing to note here is the use of setting the =c.home_dir= @@ -1452,8 +1451,8 @@ already set and the correct directory and file permissions.  The successful generation of the key can be confirmed via the returned  =GenkeyResult= object, which includes the following data: -#+begin_src python -   print(""" +#+begin_src python -i +print("""     Fingerprint:  {0}     Primary Key:  {1}      Public Key:  {2} @@ -1519,21 +1518,21 @@ primary key.  Since Danger Mouse is a security conscious secret agent,  this subkey will only be valid for about six months, half the length  of the primary key. -#+begin_src python -  import gpg +#+begin_src python -i +import gpg -  c = gpg.Context() -  c.home_dir = "~/.gnupg-dm" +c = gpg.Context() +c.home_dir = "~/.gnupg-dm" -  key = c.get_key(dmkey.fpr, secret=True) -  dmsub = c.create_subkey(key, algorithm="rsa3072", expires_in=15768000, -			  encrypt=True) +key = c.get_key(dmkey.fpr, secret=True) +dmsub = c.create_subkey(key, algorithm="rsa3072", expires_in=15768000, +			encrypt=True)  #+end_src  As with the primary key, the results here can be checked with: -#+begin_src python -   print(""" +#+begin_src python -i +print("""     Fingerprint:  {0}     Primary Key:  {1}      Public Key:  {2} @@ -1575,17 +1574,17 @@ ID to an existing key is much simpler.  The method used to do this is  =key_add_uid= and the only arguments it takes are for the =key= and  the new =uid=. -#+begin_src python -  import gpg +#+begin_src python -i +import gpg -  c = gpg.Context() -  c.home_dir = "~/.gnupg-dm" +c = gpg.Context() +c.home_dir = "~/.gnupg-dm" -  dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA" -  key = c.get_key(dmfpr, secret=True) -  uid = "Danger Mouse <[email protected]>" +dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA" +key = c.get_key(dmfpr, secret=True) +uid = "Danger Mouse <[email protected]>" -  c.key_add_uid(key, uid) +c.key_add_uid(key, uid)  #+end_src  Unsurprisingly the result of this is: @@ -1612,17 +1611,17 @@ Unsurprisingly the result of this is:  Revoking a user ID is a fairly similar process, except that it uses  the =key_revoke_uid= method. -#+begin_src python -  import gpg +#+begin_src python -i +import gpg -  c = gpg.Context() -  c.home_dir = "~/.gnupg-dm" +c = gpg.Context() +c.home_dir = "~/.gnupg-dm" -  dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA" -  key = c.get_key(dmfpr, secret=True) -  uid = "Danger Mouse <[email protected]>" +dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA" +key = c.get_key(dmfpr, secret=True) +uid = "Danger Mouse <[email protected]>" -  c.key_revoke_uid(key, uid) +c.key_revoke_uid(key, uid)  #+end_src @@ -1652,15 +1651,15 @@ it is case sensitive.  To sign Danger Mouse's key for just the initial user ID with a  signature which will last a little over a month, do this: -#+begin_src python -  import gpg +#+begin_src python -i +import gpg -  c = gpg.Context() -  uid = "Danger Mouse <[email protected]>" +c = gpg.Context() +uid = "Danger Mouse <[email protected]>" -  dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA" -  key = c.get_key(dmfpr, secret=True) -  c.key_sign(key, uids=uid, expires_in=2764800) +dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA" +key = c.get_key(dmfpr, secret=True) +c.key_sign(key, uids=uid, expires_in=2764800)  #+end_src @@ -1683,28 +1682,28 @@ MUAs readily.  The following code, however, provides a work-around for obtaining this  information in Python. -#+begin_src python -  import subprocess +#+begin_src python -i +import subprocess -  lines = subprocess.getoutput("gpgconf --list-options gpg").splitlines() +lines = subprocess.getoutput("gpgconf --list-options gpg").splitlines() -  for i in range(len(lines)): -      if lines[i].startswith("group") is True: -	  line = lines[i] -      else: -	  pass +for i in range(len(lines)): +    if lines[i].startswith("group") is True: +	line = lines[i] +    else: +	pass -  groups = line.split(":")[-1].replace('"', '').split(',') +groups = line.split(":")[-1].replace('"', '').split(',') -  group_lines = [] -  group_lists = [] +group_lines = [] +group_lists = [] -  for i in range(len(groups)): -      group_lines.append(groups[i].split("=")) -      group_lists.append(groups[i].split("=")) +for i in range(len(groups)): +    group_lines.append(groups[i].split("=")) +    group_lists.append(groups[i].split("=")) -  for i in range(len(group_lists)): -      group_lists[i][1] = group_lists[i][1].split() +for i in range(len(group_lists)): +    group_lists[i][1] = group_lists[i][1].split()  #+end_src  The result of that code is that =group_lines= is a list of lists where | 
