From: W. Trevor King Date: Thu, 19 Dec 2013 04:05:25 +0000 (-0800) Subject: Add PGPPacket._old_format_packet_lengths X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=9ec1ee890062d781415badc9d1b07f5e03159ba7;p=gpg-migrate.git Add PGPPacket._old_format_packet_lengths From RFC 4880 [1]: The meaning of the length-type in old format packets is: 0 - The packet has a one-octet length. The header is 2 octets long. 1 - The packet has a two-octet length. The header is 3 octets long. 2 - The packet has a four-octet length. The header is 5 octets long. 3 - The packet is of indeterminate length. The header is 1 octet long, and the implementation must determine how long the packet is. If the packet is in a file, this means that the packet extends until the end of the file. In general, an implementation SHOULD NOT use indeterminate-length packets except where the end of the data will be clear from the context, and even then it is better to use a definite length, or a new format header. The new format headers described below have a mechanism for precisely encoding data of indeterminate length. The struct format characters are [2]: Format C Type Python type Standard size Notes B unsigned char integer 1 (3) H unsigned short integer 2 (3) I unsigned int integer 4 (3) 3. When attempting to pack a non-integer using any of the integer conversion codes, if the non-integer has a __index__() method then that method is called to convert the argument to an integer before packing. Changed in version 3.2: Use of the __index__() method for non-integers is new in 3.2. [1]: http://tools.ietf.org/search/rfc4880#section-4.2.1 [2]: http://docs.python.org/3/library/struct.html#format-characters --- diff --git a/gpg-migrate.py b/gpg-migrate.py index 1eb09be..b836926 100755 --- a/gpg-migrate.py +++ b/gpg-migrate.py @@ -18,6 +18,13 @@ def _get_stdout(args, stdin=None): class PGPPacket (dict): # http://tools.ietf.org/search/rfc4880 + _old_format_packet_length_type = { # type: (bytes, struct type) + 0: (1, 'B'), # 1-byte unsigned integer + 1: (2, 'H'), # 2-byte unsigned integer + 2: (4, 'I'), # 4-byte unsigned integer + 3: (None, None), + } + def from_bytes(self, data): packet_tag = data[0] always_one = packet_tag & 1 << 7 @@ -26,9 +33,15 @@ class PGPPacket (dict): self['new-format'] = packet_tag & 1 << 6 if self['new-format']: self['packet-tag'] = packet_tag & 0b111111 + raise NotImplementedError('new-format packet length') else: self['packet-tag'] = packet_tag >> 2 & 0b1111 self['length-type'] = packet_tag & 0b11 + length_bytes, length_type = self._old_format_packet_length_type[ + self['length-type']] + if not length_bytes: + raise NotImplementedError( + 'old-format packet of indeterminate length') def to_bytes(self): pass