Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sometimes when exporting keys, gnupg sends back messages that aren't recognized #264

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions pretty_bad_protocol/_parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -1300,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.warning("%s -> %s", key, value)
else:
raise ValueError("Unknown status message: %r" % key)

Expand Down Expand Up @@ -1351,7 +1356,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":
Expand Down Expand Up @@ -1562,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
Expand All @@ -1571,7 +1576,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):
Expand Down
7 changes: 4 additions & 3 deletions pretty_bad_protocol/gnupg.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.

Expand Down Expand Up @@ -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

Expand Down
27 changes: 27 additions & 0 deletions pretty_bad_protocol/test/test_gnupg.py
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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',
]),

}


Expand Down