From: W. Trevor King Date: Mon, 23 Dec 2013 00:23:47 +0000 (-0800) Subject: Add a serialization check after parsing X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=0c4c22c896c6f4be34bca6411045ebad344e988e;p=gpg-migrate.git Add a serialization check after parsing Ensure that we can serialize everything we parse, using the input data as a check against our output. --- diff --git a/gpg-migrate.py b/gpg-migrate.py index f3eb3f9..8d475f7 100755 --- a/gpg-migrate.py +++ b/gpg-migrate.py @@ -411,6 +411,7 @@ class PGPPacket (dict): raise NotImplementedError( 'cannot parse packet type {!r}'.format(self['type'])) method(data=packet) + self['raw'] = data[:offset] return offset def _parse_header(self, data): @@ -978,6 +979,27 @@ class PGPPacket (dict): 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. @@ -1055,6 +1077,8 @@ class PGPKey (object): 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