From: W. Trevor King Date: Sun, 22 Dec 2013 22:14:03 +0000 (-0800) Subject: Parse algorithm-specific data in _parse_generic_secret_key_packet X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=e2a7ca0eb5a450a756bdec0766eef7c474936c80;p=gpg-migrate.git 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 --- 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