From 9a03857e0eee9568be70dd7e18dea0aeddb17a01 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Fri, 20 Dec 2013 18:34:41 -0800 Subject: [PATCH] Check the secret key checksum in PGPPacket._parse_generic_secret_key_packet From RFC 4880 [1]: - If the string-to-key usage octet is zero or 255, then a two-octet checksum of the plaintext of the algorithm-specific portion (sum of all octets, mod 65536). If the string-to-key usage octet was 254, then a 20-octet SHA-1 hash of the plaintext of the algorithm-specific portion. This checksum or hash is encrypted together with the algorithm-specific fields (if string-to-key usage octet is not zero). Note that for all other values, a two-octet checksum is required. [1]: section 5.5.3 --- gpg-migrate.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/gpg-migrate.py b/gpg-migrate.py index 8b0f1a2..6d8f8f3 100755 --- a/gpg-migrate.py +++ b/gpg-migrate.py @@ -522,9 +522,15 @@ class PGPPacket (dict): key_end = -2 else: key_end = 0 - self['secret-key'] = data[offset:key_end] + secret_key = data[offset:key_end] if key_end: - self['secret-key-checksum'] = data[key_end:] + secret_key_checksum = data[key_end:] + calculated_checksum = sum(secret_key) % 65536 + if secret_key_checksum != calculated_checksum: + raise ValueError( + 'corrupt secret key (checksum {} != expected {})'.format( + secret_key_checksum, calculated_checksum)) + self['secret-key'] = secret_key def _parse_signature_subpackets(self, data): offset = 0 -- 2.26.2