From: W. Trevor King Date: Fri, 20 Dec 2013 17:26:47 +0000 (-0800) Subject: Parse algorithm-specific data in _parse_generic_public_key_packet X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=cb6427ba6d3a57c65ce8860cd500c9e7dda4dcdc;p=gpg-migrate.git Parse algorithm-specific data in _parse_generic_public_key_packet From RFC 4880 [1]: This algorithm-specific portion is: Algorithm-Specific Fields for RSA public keys: - multiprecision integer (MPI) of RSA public modulus n; - MPI of RSA public encryption exponent e. Algorithm-Specific Fields for DSA public keys: - MPI of DSA prime p; - MPI of DSA group order q (q is a prime divisor of p-1); - MPI of DSA group generator g; - MPI of DSA public-key value y (= g**x mod p where x is secret). Algorithm-Specific Fields for Elgamal public keys: - MPI of Elgamal prime p; - MPI of Elgamal group generator g; - MPI of Elgamal public key value y (= g**x mod p where x is secret). We need to parse these fields explicitly, because the secret key packets start with public key packets. In order to tell where the rest of the secret key data starts, we need to know the length of the public key packet; simply treating the rest of the packet as an opaque public key doesn't work. [1]: http://tools.ietf.org/search/rfc4880#section-5.5.2 --- diff --git a/gpg-migrate.py b/gpg-migrate.py index 3a89352..c1e32cc 100755 --- a/gpg-migrate.py +++ b/gpg-migrate.py @@ -223,7 +223,41 @@ class PGPPacket (dict): '>IB', data[offset: offset + length]) offset += length self['public-key-algorithm'] = self._public_key_algorithms[algorithm] - self['key'] = data[offset:] + if self['public-key-algorithm'].startswith('rsa '): + o, self['public-modulus'] = self._parse_multiprecision_integer( + data[offset:]) + offset += o + o, self['public-exponent'] = self._parse_multiprecision_integer( + data[offset:]) + offset += o + elif self['public-key-algorithm'].startswith('dsa '): + o, self['prime'] = self._parse_multiprecision_integer( + data[offset:]) + offset += o + o, self['group-order'] = self._parse_multiprecision_integer( + data[offset:]) + offset += o + o, self['group-generator'] = self._parse_multiprecision_integer( + data[offset:]) + offset += o + o, self['public-key'] = self._parse_multiprecision_integer( + data[offset:]) + offset += o + elif self['public-key-algorithm'].startswith('elgamal '): + o, self['prime'] = self._parse_multiprecision_integer( + data[offset:]) + offset += o + o, self['group-generator'] = self._parse_multiprecision_integer( + data[offset:]) + offset += o + o, self['public-key'] = self._parse_multiprecision_integer( + data[offset:]) + offset += o + else: + raise NotImplementedError( + 'algorithm-specific key fields for {}'.format( + self['public-key-algorithm'])) + return offset def to_bytes(self): pass