aboutsummaryrefslogtreecommitdiffstats
path: root/lang/python/docs
diff options
context:
space:
mode:
Diffstat (limited to 'lang/python/docs')
-rw-r--r--lang/python/docs/GPGMEpythonHOWTOen.org1247
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