From e2a7ca0eb5a450a756bdec0766eef7c474936c80 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Sun, 22 Dec 2013 14:14:03 -0800 Subject: [PATCH] Parse algorithm-specific data in _parse_generic_secret_key_packet From RFC 4880 [1]: Algorithm-Specific Fields for RSA secret keys: - multiprecision integer (MPI) of RSA secret exponent d. - MPI of RSA secret prime value p. - MPI of RSA secret prime value q (p < q). - MPI of u, the multiplicative inverse of p, mod q. Algorithm-Specific Fields for DSA secret keys: - MPI of DSA secret exponent x. Algorithm-Specific Fields for Elgamal secret keys: - MPI of Elgamal secret exponent x. We'll need these if we want to sign new subkey bindings. [1]: http://tools.ietf.org/search/rfc4880#section-5.5.3 --- gpg-migrate.py | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/gpg-migrate.py b/gpg-migrate.py index de00b49..f3eb3f9 100755 --- a/gpg-migrate.py +++ b/gpg-migrate.py @@ -596,6 +596,7 @@ class PGPPacket (dict): else: key_end = 0 secret_key = decrypted_data[:key_end] + secret_offset = 0 if key_end: secret_key_checksum = decrypted_data[key_end:] if key_end == -2: @@ -608,7 +609,38 @@ class PGPPacket (dict): raise ValueError( 'corrupt secret key (checksum {} != expected {})'.format( secret_key_checksum, calculated_checksum)) - self['secret-key'] = secret_key + if self['public-key-algorithm'].startswith('rsa '): + o, self['secret-exponent'] = self._parse_multiprecision_integer( + secret_key[secret_offset:]) + secret_offset += o + o, self['secret-prime-p'] = self._parse_multiprecision_integer( + secret_key[secret_offset:]) + secret_offset += o + o, self['secret-prime-q'] = self._parse_multiprecision_integer( + secret_key[secret_offset:]) + secret_offset += o + o, self['secret-inverse-of-p-mod-q'] = ( + self._parse_multiprecision_integer( + secret_key[secret_offset:])) + secret_offset += o + elif self['public-key-algorithm'].startswith('dsa '): + o, self['secret-exponent'] = self._parse_multiprecision_integer( + secret_key[secret_offset:]) + secret_offset += o + elif self['public-key-algorithm'].startswith('elgamal '): + o, self['secret-exponent'] = self._parse_multiprecision_integer( + secret_key[secret_offset:]) + secret_offset += o + else: + raise NotImplementedError( + 'algorithm-specific key fields for {}'.format( + self['public-key-algorithm'])) + if secret_offset != len(secret_key): + raise ValueError( + ('parsed {} out of {} bytes of algorithm-specific key fields ' + 'for {}').format( + secret_offset, len(secret_key), + self['public-key-algorithm'])) def _parse_signature_subpackets(self, data): offset = 0 -- 2.26.2