]> Cypherpunks.ru repositories - pyderasn.git/commitdiff
Check that explicit tag is not out-of-bounds 3.14
authorSergey Matveev <stargrave@stargrave.org>
Wed, 15 Aug 2018 20:02:16 +0000 (23:02 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Wed, 15 Aug 2018 20:02:16 +0000 (23:02 +0300)
VERSION
doc/news.rst
pyderasn.py
tests/test_pyderasn.py

diff --git a/VERSION b/VERSION
index 24ee5b1be9961e38a503c8e764b7385dbb6ba124..6324d401a069f4020efcf0ff07442724b52f47c2 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-3.13
+3.14
index 6e2427c90021bb4c7913d42977c29b5a8365212d..81db4f5c87a7a79b0cfafa838166b16599e5847c 100644 (file)
@@ -1,6 +1,15 @@
 News
 ====
 
+.. _release3.14:
+
+3.14
+----
+* Additional encoding validness check: explicit tag must contain exactly
+  one object inside. Throw DecodeError otherwise
+* ``allow_expl_oob`` context and command-line options allow skipping of
+  that check
+
 .. _release3.13:
 
 3.13
index 92ffc17cd06e8ef16db431d0a399b376f2d7c2a8..6db8017e12a60a7d7ddfa4202514c31f808bd39e 100755 (executable)
@@ -213,6 +213,7 @@ decoding process.
 
 Currently available context options:
 
+* :ref:`allow_expl_oob <allow_expl_oob_ctx>`
 * :ref:`bered <bered_ctx>`
 * :ref:`defines_by_path <defines_by_path_ctx>`
 * :ref:`strict_default_existence <strict_default_existence_ctx>`
@@ -393,6 +394,22 @@ constructed primitive types should be parsed successfully.
 EOC (end-of-contents) token's length is taken in advance in object's
 value length.
 
+.. _allow_expl_oob_ctx:
+
+Allow explicit tag out-of-bound
+-------------------------------
+
+Invalid BER encoding could contain ``EXPLICIT`` tag containing more than
+one value, more than one object. If you set ``allow_expl_oob`` context
+option to True, then no error will be raised and that invalid encoding
+will be silently further processed. But pay attention that offsets and
+lengths will be invalid in that case.
+
+.. warning::
+
+   This option should be used only for skipping some decode errors, just
+   to see the decoded structure somehow.
+
 Primitive types
 ---------------
 
@@ -1092,6 +1109,13 @@ class Obj(object):
                 if tag_only:
                     return
                 obj, tail = result
+                if obj.tlvlen < l and not ctx.get("allow_expl_oob", False):
+                    raise DecodeError(
+                        "explicit tag out-of-bound, longer than data",
+                        klass=self.__class__,
+                        decode_path=decode_path,
+                        offset=offset,
+                    )
         return obj, (tail if leavemm else tail.tobytes())
 
     @property
@@ -5246,6 +5270,11 @@ def main():  # pragma: no cover
         "--decode-path-only",
         help="Print only specified decode path",
     )
+    parser.add_argument(
+        "--allow-expl-oob",
+        action="store_true",
+        help="Allow explicit tag out-of-bound",
+    )
     parser.add_argument(
         "DERFile",
         type=argparse.FileType("rb"),
@@ -5262,7 +5291,10 @@ def main():  # pragma: no cover
         pprinter = partial(pprint, big_blobs=True)
     else:
         schema, pprinter = generic_decoder()
-    ctx = {"bered": not args.nobered}
+    ctx = {
+        "bered": not args.nobered,
+        "allow_expl_oob": args.allow_expl_oob,
+    }
     if args.defines_by_path is not None:
         ctx["defines_by_path"] = obj_by_path(args.defines_by_path)
     obj, tail = schema().decode(der, ctx=ctx)
index c85a90a3e3e4dc737a553b3eb98aa97126e3e8f1..adad7e9b88f9ef475e7e56b1d2f7931b836b7541 100644 (file)
@@ -5922,3 +5922,13 @@ class TestX690PrefixedType(TestCase):
             VisibleString("Jones", impl=tag_ctxp(2)).encode(),
             hexdec("82054A6F6E6573"),
         )
+
+
+class TestExplOOB(TestCase):
+    def runTest(self):
+        expl = tag_ctxc(123)
+        raw = Integer(123).encode() + Integer(234).encode()
+        raw = b"".join((expl, len_encode(len(raw)), raw))
+        with assertRaisesRegex(self, DecodeError, "explicit tag out-of-bound"):
+            Integer(expl=expl).decode(raw)
+        Integer(expl=expl).decode(raw, ctx={"allow_expl_oob": True})