From cb6427ba6d3a57c65ce8860cd500c9e7dda4dcdc Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Fri, 20 Dec 2013 09:26:47 -0800 Subject: [PATCH] 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 --- gpg-migrate.py | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) 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 -- 2.26.2