VERSION | 2 +- doc/news.rst | 7 +++++++ pyderasn.py | 14 +++++++++++--- tests/test_pyderasn.py | 7 +++++-- diff --git a/VERSION b/VERSION index c228ab57ed0d95dbe9c9d8a37f590862f41f073fa643b27c5e8ec74450875208..ae93b695fac83ee53e1e7fa1cafe3d225d0bd4f364d2af94be5abc0b693a9027 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.6 +4.7 diff --git a/doc/news.rst b/doc/news.rst index a6dfd1a589b2be9b8a961b74c77e11dd500beb2340ca60c8952faf57bf7eee03..a189c8e6fe07fb96e4f39974ff6279021ca71dd9183ae30573bd5299e75d3979 100644 --- a/doc/news.rst +++ b/doc/news.rst @@ -1,6 +1,13 @@ News ==== +.. _release4.7: + +4.7 +--- +* ObjectIdentifier has ``ber_encoded`` set to True, if non-normalized + arc encoding is met + .. _release4.6: 4.6 diff --git a/pyderasn.py b/pyderasn.py index f69f5e404801ff773f17ebaa9dace712de4ffb69d42d85a5376c8bf2b46a9dee..730ec2ce556029a8452933b0a2ff04ab44678a82ee4a9c8d3df89a54bf0c63eb 100755 --- a/pyderasn.py +++ b/pyderasn.py @@ -384,7 +384,8 @@ constructed primitive types should be parsed successfully. * If object is encoded in BER form (not the DER one), then ``ber_encoded`` attribute is set to True. Only ``BOOLEAN``, ``BIT STRING``, ``OCTET - STRING``, ``SEQUENCE``, ``SET``, ``SET OF`` can contain it. + STRING``, ``OBJECT IDENTIFIER``, ``SEQUENCE``, ``SET``, ``SET OF`` + can contain it. * If object has an indefinite length encoding, then its ``lenindef`` attribute is set to True. Only ``BIT STRING``, ``OCTET STRING``, ``SEQUENCE``, ``SET``, ``SEQUENCE OF``, ``SET OF``, ``ANY`` can @@ -3223,13 +3224,17 @@ offset=offset, ) v, tail = v[:l], v[l:] arcs = [] + ber_encoded = False while len(v) > 0: i = 0 arc = 0 while True: octet = indexbytes(v, i) - if i == 0 and octet == 0x80 and not ctx.get("bered", False): - raise DecodeError("non normalized arc encoding") + if i == 0 and octet == 0x80: + if ctx.get("bered", False): + ber_encoded = True + else: + raise DecodeError("non normalized arc encoding") arc = (arc << 7) | (octet & 0x7F) if octet & 0x80 == 0: arcs.append(arc) @@ -3261,6 +3266,8 @@ default=self.default, optional=self.optional, _decoded=(offset, llen, l), ) + if ber_encoded: + obj.ber_encoded = True return obj, tail def __repr__(self): @@ -3286,6 +3293,7 @@ expl_tlen=self.expl_tlen if self.expled else None, expl_llen=self.expl_llen if self.expled else None, expl_vlen=self.expl_vlen if self.expled else None, expl_lenindef=self.expl_lenindef, + ber_encoded=self.ber_encoded, bered=self.bered, ) for pp in self.pps_lenindef(decode_path): diff --git a/tests/test_pyderasn.py b/tests/test_pyderasn.py index a7f71fa726add084257b8f719323abc990b66461716d158e93659bac15a74584..6fb765ba2aa2d6921ba4f82fba028e030b1e499d45e321878eec181bbf6b0ba5 100644 --- a/tests/test_pyderasn.py +++ b/tests/test_pyderasn.py @@ -2410,6 +2410,7 @@ obj.encode() repr(err.exception) obj = ObjectIdentifier(value) self.assertTrue(obj.ready) + self.assertFalse(obj.ber_encoded) repr(obj) list(obj.pps()) pprint(obj, big_blobs=True, with_decode_path=True) @@ -2728,7 +2729,8 @@ len_encode(2) + b'\x80' + ObjectIdentifier((1, 0)).encode()[-1:] ) - ObjectIdentifier().decode(tampered, ctx={"bered": True}) + obj, _ = ObjectIdentifier().decode(tampered, ctx={"bered": True}) + self.assertTrue(obj.ber_encoded) with assertRaisesRegex(self, DecodeError, "non normalized arc encoding"): ObjectIdentifier().decode(tampered) @@ -2756,7 +2758,8 @@ ObjectIdentifier.tag_default + len_encode(len(tampered)) + tampered ) - ObjectIdentifier().decode(tampered, ctx={"bered": True}) + obj, _ = ObjectIdentifier().decode(tampered, ctx={"bered": True}) + self.assertTrue(obj.ber_encoded) with assertRaisesRegex(self, DecodeError, "non normalized arc encoding"): ObjectIdentifier().decode(tampered)