[git] GPGME - branch, master, updated. gpgme-1.11.1-107-g4d1642b
by Ben McGinnes
cvs at cvs.gnupg.org
Sun Jul 22 17:36:45 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, master has been updated
via 4d1642b11ea64b8009a8720d9b59e89636d691d2 (commit)
via d7c5366d58d035d7b7119f955824e842d0b6bbe0 (commit)
via b47e1bb98a8ff93cae560449bfa9103c47f4d4f8 (commit)
from 5ef492c5635ae1677eed6f439a75a86a99dbbe18 (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 4d1642b11ea64b8009a8720d9b59e89636d691d2
Author: Ben McGinnes <ben at adversary.org>
Date: Mon Jul 23 01:16:31 2018 +1000
docs: python bindings howto
* Fixed and tested the changes necessary for org-mode to correctly
parse pythonic (Python 3) indentation.
* Updated the source blocks to recommended upper case for BEGIN_SRC
and END_SRC.
* Tested and confirmed XHTML output matches correct examples.
* Tested against pseudo-control output via exporting from org-mode to
org-mode and then exporting that to XHTML. Remaining differences
appear to be discarding the custom tags used to provide X[HT]ML id
elements to each section which does not appear to offer any benefit.
* Exporting directly to XHTML or other HTML output should no longer
cause problems, but if there are any then the first step should be
exporting from org-to-org and then exporting that to XHTML.
Tested-by: Ben McGinnes <ben at adversary.org>
Signed-off-by: Ben McGinnes <ben at adversary.org>
diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org
index c40772f..a712ec2 100644
--- a/lang/python/docs/GPGMEpythonHOWTOen.org
+++ b/lang/python/docs/GPGMEpythonHOWTOen.org
@@ -340,41 +340,41 @@ pattern is upper or lower case.
So this is the best method:
-#+begin_src python -i
+#+BEGIN_SRC python -i
import gpg
k = gpg.Context().keylist(pattern="258E88DCBD3CD44D8E7AB43F6ECB6AF0DEADBEEF")
keys = list(k)
-#+end_src
+#+END_SRC
This is passable and very likely to be common:
-#+begin_src python -i
+#+BEGIN_SRC python -i
import gpg
k = gpg.Context().keylist(pattern="0x6ECB6AF0DEADBEEF")
keys = list(k)
-#+end_src
+#+END_SRC
And this is a really bad idea:
-#+begin_src python -i
+#+BEGIN_SRC python -i
import gpg
k = gpg.Context().keylist(pattern="0xDEADBEEF")
keys = list(k)
-#+end_src
+#+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 -i
+#+BEGIN_SRC python -i
import gpg
ncsc = gpg.Context().keylist(pattern="ncsc.mil")
nsa = list(ncsc)
-#+end_src
+#+END_SRC
*** Counting keys
@@ -386,7 +386,7 @@ 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 -i
+#+BEGIN_SRC python -i
import gpg
c = gpg.Context()
@@ -403,7 +403,7 @@ print("""
Number of secret keys: {0}
Number of public keys: {1}
""".format(secnum, pubnum))
-#+end_src
+#+END_SRC
** Get key
@@ -424,22 +424,22 @@ 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 -i
+#+BEGIN_SRC python -i
import gpg
fingerprint = "80615870F5BAD690333686D0F2AD85AC1E42B367"
key = gpg.Context().get_key(fingerprint)
-#+end_src
+#+END_SRC
Whereas this example demonstrates selecting the author's current key
with the =secret= key word argument set to =True=:
-#+begin_src python -i
+#+BEGIN_SRC python -i
import gpg
fingerprint = "DB4724E6FA4286C92B4E55C4321E4E2373590E5D"
key = gpg.Context().get_key(fingerprint, secret=True)
-#+end_src
+#+END_SRC
It is, of course, quite possible to select expired, disabled and
revoked keys with this function, but only to effectively display
@@ -463,7 +463,7 @@ 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 -i
+#+BEGIN_SRC python -i
import gpg
import os.path
import requests
@@ -498,13 +498,12 @@ elif result is not None and hasattr(result, "considered") is True:
The key IDs for all considered keys were:
""".format(num_keys, new_revs, new_sigs, new_subs, new_uids, new_scrt,
- nochange))
+ nochange))
for i in range(num_keys):
- print(result.imports[i].fpr)
- print("")
+ print("{0}\n".format(result.imports[i].fpr))
else:
pass
-#+end_src
+#+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=
@@ -538,13 +537,13 @@ 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 -i
+#+BEGIN_SRC python -i
import gpg
import os.path
import sys
print("""
- This script exports one or more public keys.
+This script exports one or more public keys.
""")
c = gpg.Context(armor=True)
@@ -568,9 +567,9 @@ else:
if homedir.startswith("~"):
if os.path.exists(os.path.expanduser(homedir)) is True:
- c.home_dir = os.path.expanduser(homedir)
+ c.home_dir = os.path.expanduser(homedir)
else:
- pass
+ pass
elif os.path.exists(homedir) is True:
c.home_dir = homedir
else:
@@ -583,17 +582,17 @@ except:
if result is not None:
with open(keyfile, "wb") as f:
- f.write(result)
+ f.write(result)
else:
pass
-#+end_src
+#+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 -i
+#+BEGIN_SRC python -i
import gpg
import os.path
import sys
@@ -623,9 +622,9 @@ else:
if homedir.startswith("~"):
if os.path.exists(os.path.expanduser(homedir)) is True:
- c.home_dir = os.path.expanduser(homedir)
+ c.home_dir = os.path.expanduser(homedir)
else:
- pass
+ pass
elif os.path.exists(homedir) is True:
c.home_dir = homedir
else:
@@ -638,10 +637,10 @@ except:
if result is not None:
with open(keyfile, "wb") as f:
- f.write(result)
+ f.write(result)
else:
pass
-#+end_src
+#+END_SRC
*** Exporting secret keys
@@ -657,7 +656,7 @@ 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 -i
+#+BEGIN_SRC python -i
import gpg
import os
import os.path
@@ -690,9 +689,9 @@ else:
if homedir.startswith("~"):
if os.path.exists(os.path.expanduser(homedir)) is True:
- c.home_dir = os.path.expanduser(homedir)
+ c.home_dir = os.path.expanduser(homedir)
else:
- pass
+ pass
elif os.path.exists(homedir) is True:
c.home_dir = homedir
else:
@@ -705,11 +704,11 @@ except:
if result is not None:
with open(keyfile, "wb") as f:
- f.write(result)
+ f.write(result)
os.chmod(keyfile, 0o600)
else:
pass
-#+end_src
+#+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
@@ -718,7 +717,7 @@ 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 -i
+#+BEGIN_SRC python -i
import gpg
import os
import os.path
@@ -760,9 +759,9 @@ else:
if homedir.startswith("~"):
if os.path.exists(os.path.expanduser(homedir)) is True:
- c.home_dir = os.path.expanduser(homedir)
+ c.home_dir = os.path.expanduser(homedir)
else:
- pass
+ pass
elif os.path.exists(homedir) is True:
c.home_dir = homedir
else:
@@ -770,16 +769,16 @@ else:
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)
+ 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)
+ 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"]
+ hd = os.environ["GNUPGHOME"]
else:
- hd = subprocess.getoutput(gpgconfcmd)
+ hd = subprocess.getoutput(gpgconfcmd)
gpgfile = "{0}/{1}.gpg".format(hd, keyfile)
ascfile = "{0}/{1}.asc".format(hd, keyfile)
@@ -792,18 +791,18 @@ except:
if a_result is not None:
with open(ascfile, "wb") as f:
- f.write(a_result)
+ 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)
+ f.write(b_result)
os.chmod(gpgfile, 0o600)
else:
pass
-#+end_src
+#+END_SRC
* Basic Functions
@@ -850,7 +849,7 @@ 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 -i
+#+BEGIN_SRC python -i
import gpg
a_key = "0x12345678DEADBEEF"
@@ -867,14 +866,14 @@ ciphertext, result, sign_result = c.encrypt(text, recipients=rkey, sign=False)
with open("secret_plans.txt.asc", "wb") as afile:
afile.write(ciphertext)
-#+end_src
+#+END_SRC
Though this is even more likely to be used like this; with the
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 -i
+#+BEGIN_SRC python -i
import gpg
a_key = "0x12345678DEADBEEF"
@@ -885,12 +884,12 @@ with open("secret_plans.txt", "rb") as afile:
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)
+ always_trust=True,
+ add_encrypt_to=True)
with open("secret_plans.txt.asc", "wb") as afile:
afile.write(ciphertext)
-#+end_src
+#+END_SRC
If the =recipients= paramater is empty then the plaintext is encrypted
symmetrically. If no =passphrase= is supplied as a parameter or via a
@@ -911,7 +910,7 @@ 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 -i
+#+BEGIN_SRC python -i
import gpg
text = b"""Oh look, another test message.
@@ -933,24 +932,24 @@ logrus = []
for i in range(len(rpattern)):
if rpattern[i].can_encrypt == 1:
- logrus.append(rpattern[i])
+ logrus.append(rpattern[i])
ciphertext, result, sign_result = c.encrypt(text, recipients=logrus,
- sign=False, always_trust=True)
+ sign=False, always_trust=True)
with open("secret_plans.txt.asc", "wb") as afile:
afile.write(ciphertext)
-#+end_src
+#+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 -i
+#+BEGIN_SRC python -i
ciphertext, result, sign_result = c.encrypt(text, recipients=logrus,
- always_trust=True,
- add_encrypt_to=True)
-#+end_src
+ always_trust=True,
+ add_encrypt_to=True)
+#+END_SRC
The only keyword arguments requiring modification are those for which
the default values are changing. The default value of =sign= is
@@ -962,7 +961,7 @@ 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 -i
+#+BEGIN_SRC python -i
import gpg
with open("secret_plans.txt.asc", "rb") as afile:
@@ -974,27 +973,27 @@ logrus = []
for i in range(len(rpattern)):
if rpattern[i].can_encrypt == 1:
- logrus.append(rpattern[i])
+ logrus.append(rpattern[i])
try:
- ciphertext, result, sign_result = c.encrypt(text, recipients=logrus,
- add_encrypt_to=True)
+ 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
+ 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
invalid recipients if it fails and try again.
@@ -1014,7 +1013,7 @@ 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 -i
+#+BEGIN_SRC python -i
import gpg
ciphertext = input("Enter path and filename of encrypted file: ")
@@ -1022,17 +1021,17 @@ 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)
+ plaintext, result, verify_result = gpg.Context().decrypt(cfile)
except gpg.errors.GPGMEError as e:
- plaintext = None
- print(e)
+ plaintext = None
+ print(e)
- if plaintext is not None:
- with open(newfile, "wb") as nfile:
+if plaintext is not None:
+ with open(newfile, "wb") as nfile:
nfile.write(plaintext)
else:
- pass
-#+end_src
+ pass
+#+END_SRC
The data available in =plaintext= in this example is the decrypted
content as a byte object, the recipient key IDs and algorithms in
@@ -1059,13 +1058,13 @@ 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 -i
+#+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)
-#+end_src
+#+END_SRC
The signing examples in the following sections include the explicitly
designated =signers= parameter in two of the five examples; once where
@@ -1100,7 +1099,7 @@ 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 -i
+#+BEGIN_SRC python -i
import gpg
text0 = """Declaration of ... something.
@@ -1113,14 +1112,14 @@ 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())
-#+end_src
+#+END_SRC
Though everything in this example is accurate, it is more likely that
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 -i
+#+BEGIN_SRC python -i
import gpg
with open("/path/to/statement.txt", "rb") as tfile:
@@ -1131,7 +1130,7 @@ 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)
-#+end_src
+#+END_SRC
*** Detached signing messages and files
@@ -1143,7 +1142,7 @@ 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 -i
+#+BEGIN_SRC python -i
import gpg
text0 = """Declaration of ... something.
@@ -1156,12 +1155,12 @@ 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())
-#+end_src
+#+END_SRC
As with normal signatures, detached signatures are best handled as
byte literals, even when the output is ASCII armoured.
-#+begin_src python -i
+#+BEGIN_SRC python -i
import gpg
with open("/path/to/statement.txt", "rb") as tfile:
@@ -1172,7 +1171,7 @@ 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)
-#+end_src
+#+END_SRC
*** Clearsigning messages or text
@@ -1184,7 +1183,7 @@ 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 -i
+#+BEGIN_SRC python -i
import gpg
text0 = """Declaration of ... something.
@@ -1197,12 +1196,12 @@ 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())
-#+end_src
+#+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 -i
+#+BEGIN_SRC python -i
import gpg
with open("/path/to/statement.txt", "rb") as tfile:
@@ -1213,7 +1212,7 @@ 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)
-#+end_src
+#+END_SRC
** Signature verification
@@ -1229,7 +1228,7 @@ 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 -i
+#+BEGIN_SRC python -i
import gpg
import time
@@ -1247,21 +1246,21 @@ except gpg.errors.BadSignatures as e:
if verified is True:
for i in range(len(result.signatures)):
- sign = result.signatures[i]
- print("""Good signature from:
+ 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)))
+ time.ctime(sign.timestamp)))
else:
pass
-#+end_src
+#+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 -i
+#+BEGIN_SRC python -i
import gpg
import time
@@ -1279,22 +1278,22 @@ except gpg.errors.BadSignatures as e:
if verified is True:
for i in range(len(result.signatures)):
- sign = result.signatures[i]
- print("""Good signature from:
+ 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)))
+ time.ctime(sign.timestamp)))
else:
pass
-#+end_src
+#+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 -i
+#+BEGIN_SRC python -i
with open(filename, "rb") as afile:
text = afile.read()
@@ -1302,7 +1301,7 @@ if text == data:
print("Good signature.")
else:
pass
-#+end_src
+#+END_SRC
The following two examples, however, deal with detached signatures.
With his method of verification the data that was signed does not get
@@ -1310,7 +1309,7 @@ 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 -i
+#+BEGIN_SRC python -i
import gpg
import time
@@ -1328,18 +1327,18 @@ except gpg.errors.BadSignatures as e:
if verified is True:
for i in range(len(result.signatures)):
- sign = result.signatures[i]
- print("""Good signature from:
+ 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)))
+ time.ctime(sign.timestamp)))
else:
pass
-#+end_src
+#+END_SRC
-#+begin_src python -i
+#+BEGIN_SRC python -i
import gpg
import time
@@ -1357,16 +1356,16 @@ except gpg.errors.BadSignatures as e:
if verified is True:
for i in range(len(result.signatures)):
- sign = result.signatures[i]
- print("""Good signature from:
+ 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)))
+ time.ctime(sign.timestamp)))
else:
pass
-#+end_src
+#+END_SRC
* Creating keys and subkeys
@@ -1387,7 +1386,7 @@ clearance, so his keys will be 3072-bit keys.
The pre-configured =gpg.conf= file which sets cipher, digest and other
preferences contains the following configuration parameters:
-#+begin_src conf
+#+BEGIN_SRC conf
expert
allow-freeform-uid
allow-secret-key-import
@@ -1400,7 +1399,7 @@ preferences contains the following configuration parameters:
personal-cipher-preferences TWOFISH CAMELLIA256 AES256 CAMELLIA192 AES192 CAMELLIA128 AES BLOWFISH IDEA CAST5 3DES
personal-digest-preferences SHA512 SHA384 SHA256 SHA224 RIPEMD160 SHA1
personal-compress-preferences ZLIB BZIP2 ZIP Uncompressed
-#+end_src
+#+END_SRC
** Primary key
@@ -1423,7 +1422,7 @@ 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 -i
+#+BEGIN_SRC python -i
import gpg
c = gpg.Context()
@@ -1432,8 +1431,8 @@ c.home_dir = "~/.gnupg-dm"
userid = "Danger Mouse <dm at secret.example.net>"
dmkey = c.create_key(userid, algorithm="rsa3072", expires_in=31536000,
- sign=True, certify=True)
-#+end_src
+ sign=True, certify=True)
+#+END_SRC
One thing to note here is the use of setting the =c.home_dir=
parameter. This enables generating the key or keys in a different
@@ -1451,22 +1450,22 @@ 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 -i
+#+BEGIN_SRC python -i
print("""
- Fingerprint: {0}
- Primary Key: {1}
- Public Key: {2}
- Secret Key: {3}
- Sub Key: {4}
- User IDs: {5}
- """.format(dmkey.fpr, dmkey.primary, dmkey.pubkey, dmkey.seckey, dmkey.sub,
- dmkey.uid))
-#+end_src
+ Fingerprint: {0}
+ Primary Key: {1}
+ Public Key: {2}
+ Secret Key: {3}
+ Sub Key: {4}
+User IDs: {5}
+""".format(dmkey.fpr, dmkey.primary, dmkey.pubkey, dmkey.seckey, dmkey.sub,
+ dmkey.uid))
+#+END_SRC
Alternatively the information can be confirmed using the command line
program:
-#+begin_src shell
+#+BEGIN_SRC shell
bash-4.4$ gpg --homedir ~/.gnupg-dm -K
~/.gnupg-dm/pubring.kbx
----------------------
@@ -1475,7 +1474,7 @@ program:
uid [ultimate] Danger Mouse <dm at secret.example.net>
bash-4.4$
-#+end_src
+#+END_SRC
As with generating keys manually, to preconfigure expanded preferences
for the cipher, digest and compression algorithms, the =gpg.conf= file
@@ -1483,7 +1482,7 @@ must contain those details in the home directory in which the new key
is being generated. I used a cut down version of my own =gpg.conf=
file in order to be able to generate this:
-#+begin_src shell
+#+BEGIN_SRC shell
bash-4.4$ gpg --homedir ~/.gnupg-dm --edit-key 177B7C25DB99745EE2EE13ED026D2F19E99E63AA showpref quit
Secret key is available.
@@ -1499,7 +1498,7 @@ file in order to be able to generate this:
Features: MDC, Keyserver no-modify
bash-4.4$
-#+end_src
+#+END_SRC
** Subkeys
@@ -1518,7 +1517,7 @@ 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 -i
+#+BEGIN_SRC python -i
import gpg
c = gpg.Context()
@@ -1526,26 +1525,26 @@ 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)
-#+end_src
+ encrypt=True)
+#+END_SRC
As with the primary key, the results here can be checked with:
-#+begin_src python -i
+#+BEGIN_SRC python -i
print("""
- Fingerprint: {0}
- Primary Key: {1}
- Public Key: {2}
- Secret Key: {3}
- Sub Key: {4}
- User IDs: {5}
- """.format(dmsub.fpr, dmsub.primary, dmsub.pubkey, dmsub.seckey, dmsub.sub,
- dmsub.uid))
-#+end_src
+ Fingerprint: {0}
+ Primary Key: {1}
+ Public Key: {2}
+ Secret Key: {3}
+ Sub Key: {4}
+User IDs: {5}
+""".format(dmsub.fpr, dmsub.primary, dmsub.pubkey, dmsub.seckey, dmsub.sub,
+ dmsub.uid))
+#+END_SRC
As well as on the command line with:
-#+begin_src shell
+#+BEGIN_SRC shell
bash-4.4$ gpg --homedir ~/.gnupg-dm -K
~/.gnupg-dm/pubring.kbx
----------------------
@@ -1555,7 +1554,7 @@ As well as on the command line with:
ssb rsa3072 2018-03-15 [E] [expires: 2018-09-13]
bash-4.4$
-#+end_src
+#+END_SRC
** User IDs
@@ -1574,7 +1573,7 @@ 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 -i
+#+BEGIN_SRC python -i
import gpg
c = gpg.Context()
@@ -1585,11 +1584,11 @@ key = c.get_key(dmfpr, secret=True)
uid = "Danger Mouse <danger.mouse at secret.example.net>"
c.key_add_uid(key, uid)
-#+end_src
+#+END_SRC
Unsurprisingly the result of this is:
-#+begin_src shell
+#+BEGIN_SRC shell
bash-4.4$ gpg --homedir ~/.gnupg-dm -K
~/.gnupg-dm/pubring.kbx
----------------------
@@ -1600,7 +1599,7 @@ Unsurprisingly the result of this is:
ssb rsa3072 2018-03-15 [E] [expires: 2018-09-13]
bash-4.4$
-#+end_src
+#+END_SRC
*** Revokinging User IDs
@@ -1611,7 +1610,7 @@ 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 -i
+#+BEGIN_SRC python -i
import gpg
c = gpg.Context()
@@ -1622,7 +1621,7 @@ key = c.get_key(dmfpr, secret=True)
uid = "Danger Mouse <danger.mouse at secret.example.net>"
c.key_revoke_uid(key, uid)
-#+end_src
+#+END_SRC
** Key certification
@@ -1651,7 +1650,7 @@ 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 -i
+#+BEGIN_SRC python -i
import gpg
c = gpg.Context()
@@ -1660,7 +1659,7 @@ uid = "Danger Mouse <dm at secret.example.net>"
dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA"
key = c.get_key(dmfpr, secret=True)
c.key_sign(key, uids=uid, expires_in=2764800)
-#+end_src
+#+END_SRC
* Miscellaneous work-arounds
@@ -1682,16 +1681,16 @@ MUAs readily.
The following code, however, provides a work-around for obtaining this
information in Python.
-#+begin_src python -i
+#+BEGIN_SRC python -i
import subprocess
lines = subprocess.getoutput("gpgconf --list-options gpg").splitlines()
for i in range(len(lines)):
if lines[i].startswith("group") is True:
- line = lines[i]
+ line = lines[i]
else:
- pass
+ pass
groups = line.split(":")[-1].replace('"', '').split(',')
@@ -1704,7 +1703,7 @@ for i in range(len(groups)):
for i in range(len(group_lists)):
group_lists[i][1] = group_lists[i][1].split()
-#+end_src
+#+END_SRC
The result of that code is that =group_lines= is a list of lists where
=group_lines[i][0]= is the name of the group and =group_lines[i][1]=
commit d7c5366d58d035d7b7119f955824e842d0b6bbe0
Author: Ben McGinnes <ben at adversary.org>
Date: Mon Jul 23 00:21:05 2018 +1000
doc: python bindings howto
* Another retrofitting of the HOWTO Python example code, this time
following adjustments to python-mode configuration and having
trawled through the org-mode mailing lists for clues.
diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org
index df37226..c40772f 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 <dm at secret.example.net>"
+c.home_dir = "~/.gnupg-dm"
+userid = "Danger Mouse <dm at secret.example.net>"
- 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 <danger.mouse at secret.example.net>"
+dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA"
+key = c.get_key(dmfpr, secret=True)
+uid = "Danger Mouse <danger.mouse at secret.example.net>"
- 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 <danger.mouse at secret.example.net>"
+dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA"
+key = c.get_key(dmfpr, secret=True)
+uid = "Danger Mouse <danger.mouse at secret.example.net>"
- 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 <dm at secret.example.net>"
+c = gpg.Context()
+uid = "Danger Mouse <dm at secret.example.net>"
- 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
commit b47e1bb98a8ff93cae560449bfa9103c47f4d4f8
Author: Ben McGinnes <ben at adversary.org>
Date: Sun Jul 22 21:20:41 2018 +1000
doc: python bindings howto
* Added org-mode byline.
diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org
index 106b624..df37226 100644
--- a/lang/python/docs/GPGMEpythonHOWTOen.org
+++ b/lang/python/docs/GPGMEpythonHOWTOen.org
@@ -1,4 +1,5 @@
#+TITLE: GNU Privacy Guard (GnuPG) Made Easy Python Bindings HOWTO (English)
+#+AUTHOR: Ben McGinnes
#+LATEX_COMPILER: xelatex
#+LATEX_CLASS: article
#+LATEX_CLASS_OPTIONS: [12pt]
-----------------------------------------------------------------------
Summary of changes:
lang/python/docs/GPGMEpythonHOWTOen.org | 1381 +++++++++++++++----------------
1 file changed, 690 insertions(+), 691 deletions(-)
hooks/post-receive
--
GnuPG Made Easy
http://git.gnupg.org
More information about the Gnupg-commits
mailing list