summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Matveev <stargrave@stargrave.org>2018-08-15 23:02:16 +0300
committerSergey Matveev <stargrave@stargrave.org>2018-08-15 23:02:16 +0300
commit73db29cf680d46539f651e742acd1942414ce9a1 (patch)
tree7d4d9b7137b4f4fc85f8a54a588b2f8785c6c434
parent979545a22e931824c5ef016fd6ef7c471fc055d3 (diff)
downloadpyderasn-73db29cf680d46539f651e742acd1942414ce9a1.tar.xz
Check that explicit tag is not out-of-bounds3.14
-rw-r--r--VERSION2
-rw-r--r--doc/news.rst9
-rwxr-xr-xpyderasn.py34
-rw-r--r--tests/test_pyderasn.py10
4 files changed, 53 insertions, 2 deletions
diff --git a/VERSION b/VERSION
index 24ee5b1..6324d40 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-3.13
+3.14
diff --git a/doc/news.rst b/doc/news.rst
index 6e2427c..81db4f5 100644
--- a/doc/news.rst
+++ b/doc/news.rst
@@ -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
diff --git a/pyderasn.py b/pyderasn.py
index 92ffc17..6db8017 100755
--- a/pyderasn.py
+++ b/pyderasn.py
@@ -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
@@ -5247,6 +5271,11 @@ def main(): # pragma: no cover
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"),
help="Path to DER file you want to decode",
@@ -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)
diff --git a/tests/test_pyderasn.py b/tests/test_pyderasn.py
index c85a90a..adad7e9 100644
--- a/tests/test_pyderasn.py
+++ b/tests/test_pyderasn.py
@@ -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})