--- /dev/null
+"""COMPLI ASN.1:2008 compliance test suite
+
+COMPLI is a collection of BER-encoded examples that must behave in
+strictly defined way. All of them are to be valid ASN.1 encodings,
+however some of them do not comply with X.690-201508, so PyDERASN
+behaves differently in some tests. PyDERASN does not support REAL
+values too.
+"""
+
+from os import path
+from unittest import skip
+from unittest import TestCase
+
+from six import assertRaisesRegex
+
+from pyderasn import BitString
+from pyderasn import Boolean
+from pyderasn import DecodeError
+from pyderasn import Integer
+from pyderasn import InvalidLength
+from pyderasn import len_decode
+from pyderasn import LenIndefForm
+from pyderasn import NotEnoughData
+from pyderasn import Null
+from pyderasn import ObjectIdentifier
+from pyderasn import OctetString
+from pyderasn import tag_decode
+from pyderasn import tag_strip
+
+
+test_suite_path = path.join(
+ path.dirname(path.abspath(__file__)),
+ "compli_test_suite",
+ "suite",
+)
+
+
+def load_tc(num):
+ with open(path.join(test_suite_path, ("tc%d.ber" % num)), "rb") as fd:
+ return fd.read()
+
+
+class TestTestSuite(TestCase):
+ def test_tc1(self):
+ data = load_tc(1)
+ tag_strip(data)
+ tag_decode(data)
+
+ def test_tc2(self):
+ data = load_tc(2)
+ with assertRaisesRegex(self, DecodeError, "unfinished tag"):
+ tag_strip(data)
+
+ def test_tc3(self):
+ data = load_tc(3)
+ t, _, _ = tag_strip(data)
+ with self.assertRaises(NotEnoughData):
+ OctetString(impl=t).decode(data)
+
+ def test_tc4(self):
+ data = load_tc(4)
+ t, _, lv = tag_strip(data)
+ with self.assertRaises(NotEnoughData):
+ len_decode(lv)
+
+ def test_tc5(self):
+ data = load_tc(5)
+ t, _, lv = tag_strip(data)
+ with assertRaisesRegex(self, DecodeError, "long form instead of"):
+ len_decode(lv)
+
+ @skip("PyDERASN does not support REAL")
+ def test_tc6(self):
+ pass
+
+ @skip("PyDERASN does not support REAL")
+ def test_tc7(self):
+ pass
+
+ @skip("PyDERASN does not support REAL")
+ def test_tc8(self):
+ pass
+
+ @skip("PyDERASN does not support REAL")
+ def test_tc9(self):
+ pass
+
+ @skip("PyDERASN does not support REAL")
+ def test_tc10(self):
+ pass
+
+ @skip("PyDERASN does not support REAL")
+ def test_tc11(self):
+ pass
+
+ @skip("PyDERASN does not support REAL")
+ def test_tc12(self):
+ pass
+
+ @skip("PyDERASN does not support REAL")
+ def test_tc13(self):
+ pass
+
+ @skip("PyDERASN does not support REAL")
+ def test_tc14(self):
+ pass
+
+ @skip("PyDERASN does not support REAL")
+ def test_tc15(self):
+ pass
+
+ @skip("PyDERASN does not support REAL")
+ def test_tc16(self):
+ pass
+
+ @skip("PyDERASN does not support REAL")
+ def test_tc17(self):
+ pass
+
+ def test_tc18(self):
+ data = load_tc(18)
+ with assertRaisesRegex(self, DecodeError, "non normalized"):
+ Integer().decode(data)
+
+ def test_tc19(self):
+ data = load_tc(19)
+ with self.assertRaises(NotEnoughData):
+ Integer().decode(data)
+
+ def test_tc20(self):
+ data = load_tc(20)
+ Integer().decode(data)
+
+ def test_tc21(self):
+ data = load_tc(21)
+ with assertRaisesRegex(self, DecodeError, "non normalized"):
+ ObjectIdentifier().decode(data)
+ ObjectIdentifier().decode(data, ctx={"bered": True})
+
+ def test_tc22(self):
+ data = load_tc(22)
+ ObjectIdentifier().decode(data)
+
+ def test_tc23(self):
+ data = load_tc(23)
+ with self.assertRaises(NotEnoughData):
+ ObjectIdentifier().decode(data)
+
+ def test_tc24(self):
+ data = load_tc(24)
+ ObjectIdentifier().decode(data)
+
+ def test_tc25(self):
+ # X.690-201508 8.2.1: The encoding of a boolean value shall be
+ # primitive. The contents octets shall consist of a single octet.
+ data = load_tc(25)
+ with self.assertRaises(InvalidLength):
+ Boolean().decode(data)
+ with self.assertRaises(InvalidLength):
+ Boolean().decode(data, ctx={"bered": True})
+
+ def test_tc26(self):
+ # X.690-201508 8.2.1: The encoding of a boolean value shall be
+ # primitive. The contents octets shall consist of a single octet.
+ data = load_tc(26)
+ with self.assertRaises(InvalidLength):
+ Boolean().decode(data)
+ with self.assertRaises(InvalidLength):
+ Boolean().decode(data, ctx={"bered": True})
+
+ def test_tc27(self):
+ data = load_tc(27)
+ with self.assertRaises(InvalidLength):
+ Boolean().decode(data)
+
+ def test_tc28(self):
+ data = load_tc(28)
+ self.assertTrue(bool(Boolean().decode(data)[0]))
+
+ def test_tc29(self):
+ data = load_tc(29)
+ self.assertFalse(bool(Boolean().decode(data)[0]))
+
+ def test_tc30(self):
+ data = load_tc(30)
+ with self.assertRaises(InvalidLength):
+ Null().decode(data)
+
+ def test_tc31(self):
+ data = load_tc(31)
+ with self.assertRaises(InvalidLength):
+ Null().decode(data)
+
+ def test_tc32(self):
+ data = load_tc(32)
+ Null().decode(data)
+
+ def test_tc33(self):
+ data = load_tc(33)
+ with assertRaisesRegex(self, DecodeError, "too big pad"):
+ BitString().decode(data)
+ with assertRaisesRegex(self, DecodeError, "too big pad"):
+ BitString().decode(data, ctx={"bered": True})
+
+ def test_tc34(self):
+ data = load_tc(34)
+ with self.assertRaises(NotEnoughData):
+ BitString().decode(data)
+
+ def test_tc35(self):
+ data = load_tc(35)
+ with assertRaisesRegex(self, DecodeError, "expected BitString encoded chunk"):
+ BitString().decode(data, ctx={"bered": True})
+
+ def test_tc36(self):
+ data = load_tc(36)
+ with assertRaisesRegex(self, DecodeError, "invalid pad"):
+ BitString().decode(data, ctx={"bered": True})
+
+ def test_tc37(self):
+ # X.690-201508 8.6.4: To encode a bitstring value in this way,
+ # it is segmented. Each segment shall consist of a series of
+ # consecutive bits of the value, and with the possible exception
+ # of the last, shall contain a number of bits which is a
+ # multiple of eight.
+ data = load_tc(37)
+ with assertRaisesRegex(self, DecodeError, "invalid pad"):
+ BitString().decode(data, ctx={"bered": True})
+
+ def test_tc38(self):
+ data = load_tc(38)
+ BitString().decode(data, ctx={"bered": True})
+
+ def test_tc39(self):
+ # X.690-201508 8.6.2: The contents octets for the primitive
+ # encoding shall contain an initial octet followed by zero, one
+ # or more subsequent octets.
+ # X.690-201508 8.6.2.3: If the bitstring is empty, there shall
+ # be no subsequent octets, and the initial octet shall be zero.
+ data = load_tc(39)
+ with self.assertRaises(NotEnoughData):
+ BitString().decode(data, ctx={"bered": True})
+
+ def test_tc40(self):
+ # X.690-201508 8.6.2: The contents octets for the primitive
+ # encoding shall contain an initial octet followed by zero, one
+ # or more subsequent octets.
+ # X.690-201508 8.6.2.3: If the bitstring is empty, there shall
+ # be no subsequent octets, and the initial octet shall be zero.
+ data = load_tc(40)
+ with self.assertRaises(NotEnoughData):
+ BitString().decode(data, ctx={"bered": True})
+
+ def test_tc41(self):
+ data = load_tc(41)
+ with assertRaisesRegex(self, DecodeError, "expected OctetString encoded chunk"):
+ OctetString().decode(data, ctx={"bered": True})
+
+ def test_tc42(self):
+ data = load_tc(42)
+ with self.assertRaises(NotEnoughData):
+ OctetString().decode(data, ctx={"bered": True})
+
+ def test_tc43(self):
+ data = load_tc(43)
+ with self.assertRaises(NotEnoughData):
+ OctetString().decode(data, ctx={"bered": True})
+
+ def test_tc44(self):
+ data = load_tc(44)
+ OctetString().decode(data)
+
+ def test_tc45(self):
+ data = load_tc(45)
+ OctetString().decode(data, ctx={"bered": True})
+
+ def test_tc46(self):
+ data = load_tc(46)
+ with self.assertRaises(LenIndefForm):
+ BitString().decode(data, ctx={"bered": True})
+
+ def test_tc47(self):
+ data = load_tc(47)
+ with assertRaisesRegex(self, DecodeError, "expected BitString encoded chunk"):
+ BitString().decode(data, ctx={"bered": True})
+
+ def test_tc48(self):
+ data = load_tc(48)
+ with assertRaisesRegex(self, DecodeError, "too big pad"):
+ BitString().decode(data, ctx={"bered": True})