]> Cypherpunks.ru repositories - pyderasn.git/commitdiff
Check for OID arc values normalization 4.6
authorSergey Matveev <stargrave@stargrave.org>
Sat, 29 Dec 2018 21:09:37 +0000 (00:09 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Sat, 29 Dec 2018 22:13:06 +0000 (01:13 +0300)
doc/news.rst
pyderasn.py
tests/test_pyderasn.py

index 90bf903e9c757c6bce741a750abe91ce97b38efd..a187825eb3bc0be3610c599a78a0874024279672 100644 (file)
@@ -8,6 +8,8 @@ News
 * Added `COMPLI <https://github.com/YuryStrozhevsky/asn1-test-suite>`__
   ASN.1:2008 test suite. PyDERASN passes it (except for REAL values),
   but it is more strict sometimes and aimed to be compliant with X.690-201508
+* Check for arc values normalization in ObjectIdentifier.
+  Forbid non-normalized in DER encoding
 
 .. _release4.5:
 
index 482b3456cc2eca5e6b5ea3936ee9927a89744d4f..4e9def7bff226e6a53c6b4b4abba12ad3787480b 100755 (executable)
@@ -3228,6 +3228,8 @@ class ObjectIdentifier(Obj):
             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")
                 arc = (arc << 7) | (octet & 0x7F)
                 if octet & 0x80 == 0:
                     arcs.append(arc)
index 94d6343e4e5c5b45e54caac9e63eb9d9b9d0d77b..174abb6d7beaaca1871cc4fadb84c208d0e8cc37 100644 (file)
@@ -2720,6 +2720,46 @@ class TestObjectIdentifier(CommonMixin, TestCase):
             ObjectIdentifier((2, 999, 3)),
         )
 
+    @given(data_strategy())
+    def test_nonnormalized_first_arc(self, d):
+        tampered = (
+            ObjectIdentifier.tag_default +
+            len_encode(2) +
+            b'\x80' +
+            ObjectIdentifier((1, 0)).encode()[-1:]
+        )
+        ObjectIdentifier().decode(tampered, ctx={"bered": True})
+        with assertRaisesRegex(self, DecodeError, "non normalized arc encoding"):
+            ObjectIdentifier().decode(tampered)
+
+    @given(data_strategy())
+    def test_nonnormalized_arcs(self, d):
+        arcs = d.draw(lists(
+            integers(min_value=0, max_value=100),
+            min_size=1,
+            max_size=5,
+        ))
+        dered = ObjectIdentifier((1, 0) + tuple(arcs)).encode()
+        _, tlen, lv = tag_strip(dered)
+        _, llen, v = len_decode(lv)
+        v_no_first_arc = v[1:]
+        idx_for_tamper = d.draw(integers(
+            min_value=0,
+            max_value=len(v_no_first_arc) - 1,
+        ))
+        tampered = list(bytearray(v_no_first_arc))
+        for _ in range(d.draw(integers(min_value=1, max_value=3))):
+            tampered.insert(idx_for_tamper, 0x80)
+        tampered = bytes(bytearray(tampered))
+        tampered = (
+            ObjectIdentifier.tag_default +
+            len_encode(len(tampered)) +
+            tampered
+        )
+        ObjectIdentifier().decode(tampered, ctx={"bered": True})
+        with assertRaisesRegex(self, DecodeError, "non normalized arc encoding"):
+            ObjectIdentifier().decode(tampered)
+
 
 @composite
 def enumerated_values_strategy(draw, schema=None, do_expl=False):