From 016e8645034c7dadf9b8cf0b44b6c7389c0ed884 Mon Sep 17 00:00:00 2001 From: Nicolas Pouillard Date: Mon, 5 Sep 2016 23:47:01 +0200 Subject: [PATCH 1/2] Attempt at fixing issue #32 --- trezor_agent/gpg/protocol.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/trezor_agent/gpg/protocol.py b/trezor_agent/gpg/protocol.py index e0f0709..4785bbc 100644 --- a/trezor_agent/gpg/protocol.py +++ b/trezor_agent/gpg/protocol.py @@ -47,9 +47,22 @@ def subpacket_byte(subpacket_type, value): return subpacket(subpacket_type, '>B', value) +def subpacket_prefix_len(blob): + """Prefix GPG subpacket with the encoding of it's length.""" + if len(blob) < 2**8: + length_type = 0 + elif len(blob) < 2**16: + length_type = 1 + else: + length_type = 2 + fmt = ['>B', '>H', '>L'][length_type] + prefix = [b'', b'', struct.pack('>B', 255)][length_type] + return prefix + struct.pack(fmt, len(blob)) + blob + + def subpackets(*items): """Serialize several GPG subpackets.""" - prefixed = [util.prefix_len('>B', item) for item in items] + prefixed = [subpacket_prefix_len(item) for item in items] return util.prefix_len('>H', b''.join(prefixed)) From 91146303a3dbf6286f4b35cbadc6aafb25904428 Mon Sep 17 00:00:00 2001 From: Roman Zeyde Date: Wed, 28 Sep 2016 17:23:11 +0300 Subject: [PATCH 2/2] Follow GPG implementation for subpacket prefix encoding. Conflicts: trezor_agent/gpg/protocol.py --- trezor_agent/gpg/protocol.py | 20 ++++++++++---------- trezor_agent/gpg/tests/test_decode.py | 11 ++++++++++- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/trezor_agent/gpg/protocol.py b/trezor_agent/gpg/protocol.py index 4785bbc..b4d4e01 100644 --- a/trezor_agent/gpg/protocol.py +++ b/trezor_agent/gpg/protocol.py @@ -47,17 +47,17 @@ def subpacket_byte(subpacket_type, value): return subpacket(subpacket_type, '>B', value) -def subpacket_prefix_len(blob): - """Prefix GPG subpacket with the encoding of it's length.""" - if len(blob) < 2**8: - length_type = 0 - elif len(blob) < 2**16: - length_type = 1 +def subpacket_prefix_len(item): + """Prefix subpacket length according to RFC 4880 section-5.2.3.1.""" + n = len(item) + if n >= 8384: + prefix = b'\xFF' + struct.pack('>L', n) + elif n >= 192: + n = n - 192 + prefix = struct.pack('BB', (n // 256) + 192, n % 256) else: - length_type = 2 - fmt = ['>B', '>H', '>L'][length_type] - prefix = [b'', b'', struct.pack('>B', 255)][length_type] - return prefix + struct.pack(fmt, len(blob)) + blob + prefix = struct.pack('B', n) + return prefix + item def subpackets(*items): diff --git a/trezor_agent/gpg/tests/test_decode.py b/trezor_agent/gpg/tests/test_decode.py index 00d5eec..5480f80 100644 --- a/trezor_agent/gpg/tests/test_decode.py +++ b/trezor_agent/gpg/tests/test_decode.py @@ -5,7 +5,7 @@ import os import pytest -from .. import decode +from .. import decode, protocol from ... import util @@ -14,6 +14,15 @@ def test_subpackets(): assert decode.parse_subpackets(util.Reader(s)) == [b'\xAB\xCD', b'\xEF'] +def test_subpackets_prefix(): + for n in [0, 1, 2, 4, 5, 10, 191, 192, 193, + 255, 256, 257, 8383, 8384, 65530]: + item = b'?' * n # create dummy subpacket + prefixed = protocol.subpackets(item) + result = decode.parse_subpackets(util.Reader(io.BytesIO(prefixed))) + assert [item] == result + + def test_mpi(): s = io.BytesIO(b'\x00\x09\x01\x23') assert decode.parse_mpi(util.Reader(s)) == 0x123