From 61cf9dcaa34c5c679b6a0b01f1b92dcd3968ec72 Mon Sep 17 00:00:00 2001 From: Mike Hostetler Date: Wed, 7 Aug 2019 12:36:25 -0500 Subject: [PATCH 1/6] sometimes when exporting keys, gnupg sends back messages that aren't understood. Maybe because I'm on a newer version? --- pretty_bad_protocol/_parsers.py | 4 +++- pretty_bad_protocol/test/test_gnupg.py | 27 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/pretty_bad_protocol/_parsers.py b/pretty_bad_protocol/_parsers.py index 6af3d6d..0dba116 100644 --- a/pretty_bad_protocol/_parsers.py +++ b/pretty_bad_protocol/_parsers.py @@ -991,6 +991,8 @@ def _handle_status(self, key, value): key.startswith("PKA_TRUST_") or key == "NEWSIG"): pass + elif key == 'ERROR': + log.error("Received error %s", value) else: raise ValueError("Unknown status message: %r" % key) @@ -1351,7 +1353,7 @@ def _handle_status(self, key, value): :raises ValueError: if the status message is unknown. """ - informational_keys = ["KEY_CONSIDERED"] + informational_keys = ["KEY_CONSIDERED", 'PINENTRY_LAUNCHED'] if key in ("EXPORTED"): self.fingerprints.append(value) elif key == "EXPORT_RES": diff --git a/pretty_bad_protocol/test/test_gnupg.py b/pretty_bad_protocol/test/test_gnupg.py index 75346d1..6b08c26 100755 --- a/pretty_bad_protocol/test/test_gnupg.py +++ b/pretty_bad_protocol/test/test_gnupg.py @@ -1635,6 +1635,29 @@ def test_signing_key_with_wrong_password(self): self.assertEqual('bad passphrase: %s' % default_key_pair.fingerprint[-16:], result.status) self.assertNotIn(default_key_pair.fingerprint[-16:], hehe_sigs_keyids) + def test_key_export(self): + + input_data = self.gpg.gen_key_input( + key_type='RSA', + expire_date=0, + passphrase="testme" + ) + + key = self.gpg.gen_key(input_data) + + + key_file = os.path.join("/tmp","testkey.asc") + pubkey = self.gpg.export_keys(key.fingerprint) + privkey = self.gpg.export_keys(key.fingerprint, secret=True) + + with open(key_file,"w") as key_fp: + key_fp.write(pubkey) + key_fp.write(privkey) + + assert os.stat(key_file).st_size > 0 + + + suites = { 'parsers': set(['test_parsers_fix_unsafe', 'test_parsers_fix_unsafe_semicolon', 'test_parsers_is_hex_valid', @@ -1715,6 +1738,10 @@ def test_signing_key_with_wrong_password(self): 'test_key_signing_with_different_key', 'test_signing_an_already_signed_key_does_nothing_and_is_okay', 'test_signing_key_with_wrong_password']), + + 'key_export' : set(['test_key_export', + ]), + } From fcee1965d281df818a0e7f8313d7a70ca18830fe Mon Sep 17 00:00:00 2001 From: Michael Hostetler Date: Tue, 13 Aug 2019 10:58:19 -0500 Subject: [PATCH 2/6] More messages to ignore... these come in decrypt --- pretty_bad_protocol/_parsers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pretty_bad_protocol/_parsers.py b/pretty_bad_protocol/_parsers.py index 0dba116..324f993 100644 --- a/pretty_bad_protocol/_parsers.py +++ b/pretty_bad_protocol/_parsers.py @@ -1573,7 +1573,7 @@ def _handle_status(self, key, value): # pub/subkeys on the key, not just the one doing the signing. # if we want to check for signatures make with expired key, # the relevant flags are REVKEYSIG and KEYREVOKED. - elif key in ("KEYEXPIRED", "SIGEXPIRED"): + elif key in ("KEYEXPIRED", "SIGEXPIRED", "INQUIRE_MAXLEN", "DECRYPTION_COMPLIANCE_MODE"): pass # The signature has an expiration date which has already passed # (EXPKEYSIG), or the signature has been revoked (REVKEYSIG): From e243b554d193986afa0c03f0f15174717ced45f2 Mon Sep 17 00:00:00 2001 From: Michael Hostetler Date: Wed, 21 Aug 2019 10:01:40 -0500 Subject: [PATCH 3/6] added more items to parse out and log. fixed a deprecated log.warn call. --- pretty_bad_protocol/_parsers.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pretty_bad_protocol/_parsers.py b/pretty_bad_protocol/_parsers.py index 324f993..1541a53 100644 --- a/pretty_bad_protocol/_parsers.py +++ b/pretty_bad_protocol/_parsers.py @@ -1302,6 +1302,9 @@ def _handle_status(self, key, value): res = {'fingerprint': None, 'status': 'Signature expired'} self.results.append(res) + + elif key in ('USERID_HINT', 'NEED_PASSPHRASE', 'INQUIRE_MAXLEN',): + log.warnings("%s -> %s", key, value) else: raise ValueError("Unknown status message: %r" % key) @@ -1564,7 +1567,7 @@ def _handle_status(self, key, value): # case of WARNING or ERROR) additional text. # Have fun figuring out what it means. self.status = value - log.warn("%s status emitted from gpg process: %s" % (key, value)) + log.warning("%s status emitted from gpg process: %s" % (key, value)) elif key == "NO_PUBKEY": self.valid = False self.key_id = value From 43b9f7c18483a245784c0be1920ad265a7ffecfa Mon Sep 17 00:00:00 2001 From: Michael Hostetler Date: Wed, 21 Aug 2019 10:02:27 -0500 Subject: [PATCH 4/6] fixed a typo --- pretty_bad_protocol/_parsers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pretty_bad_protocol/_parsers.py b/pretty_bad_protocol/_parsers.py index 1541a53..d64b297 100644 --- a/pretty_bad_protocol/_parsers.py +++ b/pretty_bad_protocol/_parsers.py @@ -1304,7 +1304,7 @@ def _handle_status(self, key, value): self.results.append(res) elif key in ('USERID_HINT', 'NEED_PASSPHRASE', 'INQUIRE_MAXLEN',): - log.warnings("%s -> %s", key, value) + log.warning("%s -> %s", key, value) else: raise ValueError("Unknown status message: %r" % key) From fcde9564a4653af679c61648030e4ad36039a3ab Mon Sep 17 00:00:00 2001 From: Michael Hostetler Date: Wed, 21 Aug 2019 10:02:35 -0500 Subject: [PATCH 5/6] added passphrase to key import, via https://github.com/isislovecruft/python-gnupg/issues/205 --- pretty_bad_protocol/gnupg.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pretty_bad_protocol/gnupg.py b/pretty_bad_protocol/gnupg.py index 7efabcf..7260deb 100644 --- a/pretty_bad_protocol/gnupg.py +++ b/pretty_bad_protocol/gnupg.py @@ -320,7 +320,7 @@ def verify_file(self, file, sig_file=None): sig_fh.close() return result - def import_keys(self, key_data): + def import_keys(self, key_data, passphrase=False): """ Import the key_data into our keyring. @@ -359,10 +359,11 @@ def import_keys(self, key_data): ## xxx need way to validate that key_data is actually a valid GPG key ## it might be possible to use --list-packets and parse the output + # passphrase fix from https://github.com/isislovecruft/python-gnupg/issues/205 result = self._result_map['import'](self) log.info('Importing: %r', key_data[:256]) data = _make_binary_stream(key_data, self._encoding) - self._handle_io(['--import'], data, result, binary=True) + self._handle_io(['--import'], data, result, passphrase=passphrase, binary=True) data.close() return result From fb7969f02509e6286a439092ab7159e8be77fd13 Mon Sep 17 00:00:00 2001 From: Michael Hostetler Date: Fri, 30 Aug 2019 08:14:40 -0500 Subject: [PATCH 6/6] turn the initialization message to debug --- pretty_bad_protocol/gnupg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pretty_bad_protocol/gnupg.py b/pretty_bad_protocol/gnupg.py index 7260deb..4a583ec 100644 --- a/pretty_bad_protocol/gnupg.py +++ b/pretty_bad_protocol/gnupg.py @@ -126,7 +126,7 @@ def __init__(self, binary=None, homedir=None, verbose=False, ignore_homedir_permissions=ignore_homedir_permissions, ) - log.info(textwrap.dedent(""" + log.debug(textwrap.dedent(""" Initialised settings: binary: %s binary version: %s