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
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