From 0958c0ddf71564391d664e36adc782f43d89291f Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Fri, 20 Dec 2013 11:43:21 -0800 Subject: [PATCH] Add PGPKey with a basic key-level API This currently handles importing keys from GnuPG and stubs out a key-stringification framework along the lines of the existing packet-parsing framework in PGPPacket.from_bytes. --- gpg-migrate.py | 70 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 16 deletions(-) diff --git a/gpg-migrate.py b/gpg-migrate.py index fb5ea92..5b9ef10 100755 --- a/gpg-migrate.py +++ b/gpg-migrate.py @@ -190,6 +190,17 @@ class PGPPacket (dict): def _clean_type(self): return self._clean_type_regex.sub('_', self['type']) + def __str__(self): + method_name = '_str_{}'.format(self._clean_type()) + method = getattr(self, method_name, None) + if not method: + return self['type'] + details = method() + return '{}: {}'.format(self['type'], details) + + def _str_user_id_packet(self): + return self['user'] + def from_bytes(self, data): offset = self._parse_header(data=data) packet = data[offset:offset + self['length']] @@ -410,6 +421,42 @@ def packets_from_bytes(data): yield packet +class PGPKey (object): + def __init__(self, fingerprint): + self.fingerprint = fingerprint + self.public_packets = None + self.secret_packets = None + + def __str__(self): + lines = ['key: {}'.format(self.fingerprint)] + if self.public_packets: + lines.append(' public:') + for packet in self.public_packets: + lines.append(' {}'.format(packet)) + if self.secret_packets: + lines.append(' secret:') + for packet in self.secret_packets: + lines.append(' {}'.format(packet)) + return '\n'.join(lines) + + def import_from_gpg(self): + key_export = _get_stdout( + ['gpg', '--export', self.fingerprint]) + self.public_packets = list( + packets_from_bytes(data=key_export)) + if self.public_packets[0]['type'] != 'public-key packet': + raise ValueError( + '{} does not start with a public-key packet'.format( + self.fingerprint)) + key_secret_export = _get_stdout( + ['gpg', '--export-secret-keys', self.fingerprint]) + self.secret_packets = list( + packets_from_bytes(data=key_secret_export)) + + def export_to_gpg(self): + raise NotImplemetedError('export to gpg') + + def migrate(old_key, new_key): """Add the old key and sub-keys to the new key @@ -417,22 +464,13 @@ def migrate(old_key, new_key): signatures you'd made. You will lose signature *on* your old key though, since sub-keys can't be signed (I don't think). """ - old_key_export = _get_stdout( - ['gpg', '--export', old_key]) - old_key_packets = list( - packets_from_bytes(data=old_key_export)) - if old_key_packets[0]['type'] != 'public-key packet': - raise ValueError( - '{} does not start with a public-key packet'.format( - old_key)) - old_key_secret_export = _get_stdout( - ['gpg', '--export-secret-keys', old_key]) - old_key_secret_packets = list( - packets_from_bytes(data=old_key_secret_export)) - - import pprint - pprint.pprint(old_key_packets) - pprint.pprint(old_key_secret_packets) + old_key = PGPKey(fingerprint=old_key) + old_key.import_from_gpg() + new_key = PGPKey(fingerprint=new_key) + new_key.import_from_gpg() + + print(old_key) + print(new_key) if __name__ == '__main__': -- 2.26.2