raise NotImplementedError(
'cannot parse packet type {!r}'.format(self['type']))
method(data=packet)
+ self['raw'] = data[:offset]
return offset
def _parse_header(self, data):
plaintext = plaintext[:-padding]
return plaintext
+ def check_roundtrip(self):
+ serialized = self.to_bytes()
+ source = self['raw']
+ if serialized != source:
+ if len(serialized) != len(source):
+ raise ValueError(
+ ('serialized {} is {} bytes long, '
+ 'but input is {} bytes long').format(
+ self['type'], len(serialized), len(source)))
+ chunk_size = 8
+ for i in range(0, len(source), 8):
+ in_chunk = source[i: i + chunk_size]
+ out_chunk = serialized[i: i + chunk_size]
+ if in_chunk != out_chunk:
+ raise ValueError(
+ ('serialized {} differs from input packet: '
+ 'at byte {}, {} != {}').format(
+ self['type'], i,
+ ' '.join('{:02x}'.format(byte) for byte in out_chunk),
+ ' '.join('{:02x}'.format(byte) for byte in in_chunk)))
+
class PGPKey (object):
"""An OpenPGP key with public and private parts.
raise ValueError(
'{} does not start with a secret-key packet'.format(
self.fingerprint))
+ for packet in self.public_packets + self.secret_packets:
+ packet.check_roundtrip()
def _packets_from_bytes(self, data):
offset = 0