diff options
Diffstat (limited to 'tests/codec')
-rw-r--r-- | tests/codec/__init__.py | 1 | ||||
-rw-r--r-- | tests/codec/__main__.py | 22 | ||||
-rw-r--r-- | tests/codec/ber/__init__.py | 1 | ||||
-rw-r--r-- | tests/codec/ber/__main__.py | 20 | ||||
-rw-r--r-- | tests/codec/ber/test_decoder.py | 817 | ||||
-rw-r--r-- | tests/codec/ber/test_encoder.py | 536 | ||||
-rw-r--r-- | tests/codec/cer/__init__.py | 1 | ||||
-rw-r--r-- | tests/codec/cer/__main__.py | 20 | ||||
-rw-r--r-- | tests/codec/cer/test_decoder.py | 68 | ||||
-rw-r--r-- | tests/codec/cer/test_encoder.py | 193 | ||||
-rw-r--r-- | tests/codec/der/__init__.py | 1 | ||||
-rw-r--r-- | tests/codec/der/__main__.py | 20 | ||||
-rw-r--r-- | tests/codec/der/test_decoder.py | 75 | ||||
-rw-r--r-- | tests/codec/der/test_encoder.py | 70 | ||||
-rw-r--r-- | tests/codec/native/__init__.py | 1 | ||||
-rw-r--r-- | tests/codec/native/__main__.py | 19 | ||||
-rw-r--r-- | tests/codec/native/test_decoder.py | 114 | ||||
-rw-r--r-- | tests/codec/native/test_encoder.py | 130 |
18 files changed, 2109 insertions, 0 deletions
diff --git a/tests/codec/__init__.py b/tests/codec/__init__.py new file mode 100644 index 0000000..8c3066b --- /dev/null +++ b/tests/codec/__init__.py @@ -0,0 +1 @@ +# This file is necessary to make this directory a package. diff --git a/tests/codec/__main__.py b/tests/codec/__main__.py new file mode 100644 index 0000000..bcfd96f --- /dev/null +++ b/tests/codec/__main__.py @@ -0,0 +1,22 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +try: + import unittest2 as unittest + +except ImportError: + import unittest + +suite = unittest.TestLoader().loadTestsFromNames( + ['tests.codec.ber.__main__.suite', + 'tests.codec.cer.__main__.suite', + 'tests.codec.der.__main__.suite', + 'tests.codec.native.__main__.suite'] +) + + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/ber/__init__.py b/tests/codec/ber/__init__.py new file mode 100644 index 0000000..8c3066b --- /dev/null +++ b/tests/codec/ber/__init__.py @@ -0,0 +1 @@ +# This file is necessary to make this directory a package. diff --git a/tests/codec/ber/__main__.py b/tests/codec/ber/__main__.py new file mode 100644 index 0000000..2909628 --- /dev/null +++ b/tests/codec/ber/__main__.py @@ -0,0 +1,20 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +try: + import unittest2 as unittest + +except ImportError: + import unittest + +suite = unittest.TestLoader().loadTestsFromNames( + ['tests.codec.ber.test_encoder.suite', + 'tests.codec.ber.test_decoder.suite'] +) + + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/ber/test_decoder.py b/tests/codec/ber/test_decoder.py new file mode 100644 index 0000000..c1852c4 --- /dev/null +++ b/tests/codec/ber/test_decoder.py @@ -0,0 +1,817 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +import sys +try: + import unittest2 as unittest +except ImportError: + import unittest + +from pyasn1.type import tag, namedtype, univ, char +from pyasn1.codec.ber import decoder, eoo +from pyasn1.compat.octets import ints2octs, str2octs, null +from pyasn1.error import PyAsn1Error + + +class BadAsn1SpecTestCase(unittest.TestCase): + def testBadSpec(self): + try: + decoder.decode(ints2octs((48, 2, 5, 0)), asn1Spec='not an Asn1Item') + except PyAsn1Error: + pass + else: + assert 0, 'Invalid asn1Spec accepted' + + +class LargeTagDecoderTestCase(unittest.TestCase): + def testLargeTag(self): + assert decoder.decode(ints2octs((127, 141, 245, 182, 253, 47, 3, 2, 1, 1))) == (1, null) + + def testLongTag(self): + assert decoder.decode(ints2octs((0x1f, 2, 1, 0)))[0].tagSet == univ.Integer.tagSet + + def testTagsEquivalence(self): + integer = univ.Integer(2, tag.TagSet((), tag.Tag(tag.tagClassContext, 0, 0))) + assert decoder.decode(ints2octs((0x9f, 0x80, 0x00, 0x02, 0x01, 0x02)), asn1Spec=integer) == decoder.decode( + ints2octs((0x9f, 0x00, 0x02, 0x01, 0x02)), asn1Spec=integer) + + +class DecoderCacheTestCase(unittest.TestCase): + def testCache(self): + assert decoder.decode(ints2octs((0x1f, 2, 1, 0))) == decoder.decode(ints2octs((0x1f, 2, 1, 0))) + + +class IntegerDecoderTestCase(unittest.TestCase): + def testPosInt(self): + assert decoder.decode(ints2octs((2, 1, 12))) == (12, null) + + def testNegInt(self): + assert decoder.decode(ints2octs((2, 1, 244))) == (-12, null) + + def testZero(self): + assert decoder.decode(ints2octs((2, 0))) == (0, null) + + def testZeroLong(self): + assert decoder.decode(ints2octs((2, 1, 0))) == (0, null) + + def testMinusOne(self): + assert decoder.decode(ints2octs((2, 1, 255))) == (-1, null) + + def testPosLong(self): + assert decoder.decode( + ints2octs((2, 9, 0, 255, 255, 255, 255, 255, 255, 255, 255)) + ) == (0xffffffffffffffff, null) + + def testNegLong(self): + assert decoder.decode( + ints2octs((2, 9, 255, 0, 0, 0, 0, 0, 0, 0, 1)) + ) == (-0xffffffffffffffff, null) + + def testSpec(self): + try: + decoder.decode( + ints2octs((2, 1, 12)), asn1Spec=univ.Null() + ) == (12, null) + except PyAsn1Error: + pass + else: + assert 0, 'wrong asn1Spec worked out' + assert decoder.decode( + ints2octs((2, 1, 12)), asn1Spec=univ.Integer() + ) == (12, null) + + def testTagFormat(self): + try: + decoder.decode(ints2octs((34, 1, 12))) + except PyAsn1Error: + pass + else: + assert 0, 'wrong tagFormat worked out' + + +class BooleanDecoderTestCase(unittest.TestCase): + def testTrue(self): + assert decoder.decode(ints2octs((1, 1, 1))) == (1, null) + + def testTrueNeg(self): + assert decoder.decode(ints2octs((1, 1, 255))) == (1, null) + + def testExtraTrue(self): + assert decoder.decode(ints2octs((1, 1, 1, 0, 120, 50, 50))) == (1, ints2octs((0, 120, 50, 50))) + + def testFalse(self): + assert decoder.decode(ints2octs((1, 1, 0))) == (0, null) + + def testTagFormat(self): + try: + decoder.decode(ints2octs((33, 1, 1))) + except PyAsn1Error: + pass + else: + assert 0, 'wrong tagFormat worked out' + + +class BitStringDecoderTestCase(unittest.TestCase): + def testDefMode(self): + assert decoder.decode( + ints2octs((3, 3, 1, 169, 138)) + ) == ((1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1), null) + + def testIndefMode(self): + assert decoder.decode( + ints2octs((3, 3, 1, 169, 138)) + ) == ((1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1), null) + + def testDefModeChunked(self): + assert decoder.decode( + ints2octs((35, 8, 3, 2, 0, 169, 3, 2, 1, 138)) + ) == ((1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1), null) + + def testIndefModeChunked(self): + assert decoder.decode( + ints2octs((35, 128, 3, 2, 0, 169, 3, 2, 1, 138, 0, 0)) + ) == ((1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1), null) + + def testDefModeChunkedSubst(self): + assert decoder.decode( + ints2octs((35, 8, 3, 2, 0, 169, 3, 2, 1, 138)), + substrateFun=lambda a, b, c: (b, c) + ) == (ints2octs((3, 2, 0, 169, 3, 2, 1, 138)), 8) + + def testIndefModeChunkedSubst(self): + assert decoder.decode( + ints2octs((35, 128, 3, 2, 0, 169, 3, 2, 1, 138, 0, 0)), + substrateFun=lambda a, b, c: (b, c) + ) == (ints2octs((3, 2, 0, 169, 3, 2, 1, 138, 0, 0)), -1) + + def testTypeChecking(self): + try: + decoder.decode(ints2octs((35, 4, 2, 2, 42, 42))) + except PyAsn1Error: + pass + else: + assert 0, 'accepted mis-encoded bit-string constructed out of an integer' + + +class OctetStringDecoderTestCase(unittest.TestCase): + def testDefMode(self): + assert decoder.decode( + ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)) + ) == (str2octs('Quick brown fox'), null) + + def testIndefMode(self): + assert decoder.decode( + ints2octs((36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0)) + ) == (str2octs('Quick brown fox'), null) + + def testDefModeChunked(self): + assert decoder.decode( + ints2octs( + (36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120)) + ) == (str2octs('Quick brown fox'), null) + + def testIndefModeChunked(self): + assert decoder.decode( + ints2octs((36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, + 120, 0, 0)) + ) == (str2octs('Quick brown fox'), null) + + def testDefModeChunkedSubst(self): + assert decoder.decode( + ints2octs( + (36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120)), + substrateFun=lambda a, b, c: (b, c) + ) == (ints2octs((4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120)), + 23) + + def testIndefModeChunkedSubst(self): + assert decoder.decode( + ints2octs((36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, + 120, 0, 0)), + substrateFun=lambda a, b, c: (b, c) + ) == (ints2octs( + (4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120, 0, 0)), -1) + + +class ExpTaggedOctetStringDecoderTestCase(unittest.TestCase): + def setUp(self): + self.o = univ.OctetString( + 'Quick brown fox', + tagSet=univ.OctetString.tagSet.tagExplicitly( + tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 5) + )) + + def testDefMode(self): + assert self.o.isSameTypeWith(decoder.decode( + ints2octs((101, 17, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)) + )[0]) + + def testIndefMode(self): + v, s = decoder.decode(ints2octs(( + 101, 128, 36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, + 102, 111, 120, 0, 0, 0, 0))) + assert self.o.isSameTypeWith(v) + assert not s + + def testDefModeChunked(self): + v, s = decoder.decode(ints2octs(( + 101, 25, 36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, + 110, 32, 4, 3, 102, 111, 120))) + assert self.o.isSameTypeWith(v) + assert not s + + def testIndefModeChunked(self): + v, s = decoder.decode(ints2octs((101, 128, 36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, + 119, 110, 32, 4, 3, 102, 111, 120, 0, 0, 0, 0))) + assert self.o.isSameTypeWith(v) + assert not s + + def testDefModeSubst(self): + assert decoder.decode( + ints2octs((101, 17, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)), + substrateFun=lambda a, b, c: (b, c) + ) == (ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)), 17) + + def testIndefModeSubst(self): + assert decoder.decode( + ints2octs(( + 101, 128, 36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, + 0, 0, 0)), + substrateFun=lambda a, b, c: (b, c) + ) == (ints2octs( + (36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0, 0, 0)), -1) + + +class NullDecoderTestCase(unittest.TestCase): + def testNull(self): + assert decoder.decode(ints2octs((5, 0))) == (null, null) + + def testTagFormat(self): + try: + decoder.decode(ints2octs((37, 0))) + except PyAsn1Error: + pass + else: + assert 0, 'wrong tagFormat worked out' + + +# Useful analysis of OID encoding issues could be found here: +# http://www.viathinksoft.de/~daniel-marschall/asn.1/oid_facts.html +class ObjectIdentifierDecoderTestCase(unittest.TestCase): + def testOne(self): + assert decoder.decode( + ints2octs((6, 6, 43, 6, 0, 191, 255, 126)) + ) == ((1, 3, 6, 0, 0xffffe), null) + + def testEdge1(self): + assert decoder.decode( + ints2octs((6, 1, 39)) + ) == ((0, 39), null) + + def testEdge2(self): + assert decoder.decode( + ints2octs((6, 1, 79)) + ) == ((1, 39), null) + + def testEdge3(self): + assert decoder.decode( + ints2octs((6, 1, 120)) + ) == ((2, 40), null) + + def testEdge4(self): + assert decoder.decode( + ints2octs((6, 5, 0x90, 0x80, 0x80, 0x80, 0x4F)) + ) == ((2, 0xffffffff), null) + + def testEdge5(self): + assert decoder.decode( + ints2octs((6, 1, 0x7F)) + ) == ((2, 47), null) + + def testEdge6(self): + assert decoder.decode( + ints2octs((6, 2, 0x81, 0x00)) + ) == ((2, 48), null) + + def testEdge7(self): + assert decoder.decode( + ints2octs((6, 3, 0x81, 0x34, 0x03)) + ) == ((2, 100, 3), null) + + def testEdge8(self): + assert decoder.decode( + ints2octs((6, 2, 133, 0)) + ) == ((2, 560), null) + + def testEdge9(self): + assert decoder.decode( + ints2octs((6, 4, 0x88, 0x84, 0x87, 0x02)) + ) == ((2, 16843570), null) + + def testNonLeading0x80(self): + assert decoder.decode( + ints2octs((6, 5, 85, 4, 129, 128, 0)), + ) == ((2, 5, 4, 16384), null) + + def testLeading0x80Case1(self): + try: + decoder.decode( + ints2octs((6, 5, 85, 4, 128, 129, 0)) + ) + except PyAsn1Error: + pass + else: + assert 0, 'Leading 0x80 tolarated' + + def testLeading0x80Case2(self): + try: + decoder.decode( + ints2octs((6, 7, 1, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7F)) + ) + except PyAsn1Error: + pass + else: + assert 0, 'Leading 0x80 tolarated' + + def testLeading0x80Case3(self): + try: + decoder.decode( + ints2octs((6, 2, 0x80, 1)) + ) + except PyAsn1Error: + pass + else: + assert 0, 'Leading 0x80 tolarated' + + def testLeading0x80Case4(self): + try: + decoder.decode( + ints2octs((6, 2, 0x80, 0x7F)) + ) + except PyAsn1Error: + pass + else: + assert 0, 'Leading 0x80 tolarated' + + def testTagFormat(self): + try: + decoder.decode(ints2octs((38, 1, 239))) + except PyAsn1Error: + pass + else: + assert 0, 'wrong tagFormat worked out' + + def testZeroLength(self): + try: + decoder.decode(ints2octs((6, 0, 0))) + except PyAsn1Error: + pass + else: + assert 0, 'zero length tolarated' + + def testIndefiniteLength(self): + try: + decoder.decode(ints2octs((6, 128, 0))) + except PyAsn1Error: + pass + else: + assert 0, 'indefinite length tolarated' + + def testReservedLength(self): + try: + decoder.decode(ints2octs((6, 255, 0))) + except PyAsn1Error: + pass + else: + assert 0, 'reserved length tolerated' + + def testLarge1(self): + assert decoder.decode( + ints2octs((0x06, 0x11, 0x83, 0xC6, 0xDF, 0xD4, 0xCC, 0xB3, 0xFF, 0xFF, 0xFE, 0xF0, 0xB8, 0xD6, 0xB8, 0xCB, + 0xE2, 0xB7, 0x17)) + ) == ((2, 18446744073709551535184467440737095), null) + + def testLarge2(self): + assert decoder.decode( + ints2octs((0x06, 0x13, 0x88, 0x37, 0x83, 0xC6, 0xDF, 0xD4, 0xCC, 0xB3, 0xFF, 0xFF, 0xFE, 0xF0, 0xB8, 0xD6, + 0xB8, 0xCB, 0xE2, 0xB6, 0x47)) + ) == ((2, 999, 18446744073709551535184467440737095), null) + + +class RealDecoderTestCase(unittest.TestCase): + def testChar(self): + assert decoder.decode( + ints2octs((9, 7, 3, 49, 50, 51, 69, 49, 49)) + ) == (univ.Real((123, 10, 11)), null) + + def testBin1(self): # check base = 2 + assert decoder.decode( # (0.5, 2, 0) encoded with base = 2 + ints2octs((9, 3, 128, 255, 1)) + ) == (univ.Real((1, 2, -1)), null) + + def testBin2(self): # check base = 2 and scale factor + assert decoder.decode( # (3.25, 2, 0) encoded with base = 8 + ints2octs((9, 3, 148, 255, 13)) + ) == (univ.Real((26, 2, -3)), null) + + def testBin3(self): # check base = 16 + assert decoder.decode( # (0.00390625, 2, 0) encoded with base = 16 + ints2octs((9, 3, 160, 254, 1)) + ) == (univ.Real((1, 2, -8)), null) + + def testBin4(self): # check exponenta = 0 + assert decoder.decode( # (1, 2, 0) encoded with base = 2 + ints2octs((9, 3, 128, 0, 1)) + ) == (univ.Real((1, 2, 0)), null) + + def testBin5(self): # case of 2 octs for exponenta and negative exponenta + assert decoder.decode( # (3, 2, -1020) encoded with base = 16 + ints2octs((9, 4, 161, 255, 1, 3)) + ) == (univ.Real((3, 2, -1020)), null) + + def testPlusInf(self): + assert decoder.decode( + ints2octs((9, 1, 64)) + ) == (univ.Real('inf'), null) + + def testMinusInf(self): + assert decoder.decode( + ints2octs((9, 1, 65)) + ) == (univ.Real('-inf'), null) + + def testEmpty(self): + assert decoder.decode( + ints2octs((9, 0)) + ) == (univ.Real(0.0), null) + + def testTagFormat(self): + try: + decoder.decode(ints2octs((41, 0))) + except PyAsn1Error: + pass + else: + assert 0, 'wrong tagFormat worked out' + + def testShortEncoding(self): + try: + decoder.decode(ints2octs((9, 1, 131))) + except PyAsn1Error: + pass + else: + assert 0, 'accepted too-short real' + + +if sys.version_info[0:2] > (2, 5): + class UniversalStringDecoderTestCase(unittest.TestCase): + def testDecoder(self): + assert decoder.decode(ints2octs((28, 12, 0, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, 99))) == (char.UniversalString(sys.version_info[0] == 3 and 'abc' or unicode('abc')), null) + + +class BMPStringDecoderTestCase(unittest.TestCase): + def testDecoder(self): + assert decoder.decode(ints2octs((30, 6, 0, 97, 0, 98, 0, 99))) == (char.BMPString(sys.version_info[0] == 3 and 'abc' or unicode('abc')), null) + + +class UTF8StringDecoderTestCase(unittest.TestCase): + def testDecoder(self): + assert decoder.decode(ints2octs((12, 3, 97, 98, 99))) == (char.UTF8String(sys.version_info[0] == 3 and 'abc' or unicode('abc')), null) + + +class SequenceDecoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Sequence(componentType=namedtype.NamedTypes( + namedtype.NamedType('place-holder', univ.Null(null)), + namedtype.NamedType('first-name', univ.OctetString(null)), + namedtype.NamedType('age', univ.Integer(33))) + ) + self.s.setComponentByPosition(0, univ.Null(null)) + self.s.setComponentByPosition(1, univ.OctetString('quick brown')) + self.s.setComponentByPosition(2, univ.Integer(1)) + self.s.setDefaultComponents() + + def testWithOptionalAndDefaultedDefMode(self): + assert decoder.decode( + ints2octs((48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)) + ) == (self.s, null) + + def testWithOptionalAndDefaultedIndefMode(self): + assert decoder.decode( + ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, + 0, 0)) + ) == (self.s, null) + + def testWithOptionalAndDefaultedDefModeChunked(self): + assert decoder.decode( + ints2octs( + (48, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1)) + ) == (self.s, null) + + def testWithOptionalAndDefaultedIndefModeChunked(self): + assert decoder.decode( + ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, + 0, 2, 1, 1, 0, 0)) + ) == (self.s, null) + + def testWithOptionalAndDefaultedDefModeSubst(self): + assert decoder.decode( + ints2octs((48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)), + substrateFun=lambda a, b, c: (b, c) + ) == (ints2octs((5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)), 18) + + def testWithOptionalAndDefaultedIndefModeSubst(self): + assert decoder.decode( + ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, + 0, 0)), + substrateFun=lambda a, b, c: (b, c) + ) == (ints2octs( + (5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), -1) + + def testTagFormat(self): + try: + decoder.decode( + ints2octs((16, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)) + ) + except PyAsn1Error: + pass + else: + assert 0, 'wrong tagFormat worked out' + + +class GuidedSequenceDecoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Sequence(componentType=namedtype.NamedTypes( + namedtype.NamedType('place-holder', univ.Null(null)), + namedtype.OptionalNamedType('first-name', univ.OctetString(null)), + namedtype.DefaultedNamedType('age', univ.Integer(33)), + )) + + def __init(self): + self.s.clear() + self.s.setComponentByPosition(0, univ.Null(null)) + self.s.setDefaultComponents() + + def __initWithOptional(self): + self.s.clear() + self.s.setComponentByPosition(0, univ.Null(null)) + self.s.setComponentByPosition(1, univ.OctetString('quick brown')) + self.s.setDefaultComponents() + + def __initWithDefaulted(self): + self.s.clear() + self.s.setComponentByPosition(0, univ.Null(null)) + self.s.setComponentByPosition(2, univ.Integer(1)) + self.s.setDefaultComponents() + + def __initWithOptionalAndDefaulted(self): + self.s.clear() + self.s.setComponentByPosition(0, univ.Null(null)) + self.s.setComponentByPosition(1, univ.OctetString('quick brown')) + self.s.setComponentByPosition(2, univ.Integer(1)) + self.s.setDefaultComponents() + + def testDefMode(self): + self.__init() + assert decoder.decode( + ints2octs((48, 128, 5, 0, 0, 0)), asn1Spec=self.s + ) == (self.s, null) + + def testIndefMode(self): + self.__init() + assert decoder.decode( + ints2octs((48, 128, 5, 0, 0, 0)), asn1Spec=self.s + ) == (self.s, null) + + def testDefModeChunked(self): + self.__init() + assert decoder.decode( + ints2octs((48, 2, 5, 0)), asn1Spec=self.s + ) == (self.s, null) + + def testIndefModeChunked(self): + self.__init() + assert decoder.decode( + ints2octs((48, 128, 5, 0, 0, 0)), asn1Spec=self.s + ) == (self.s, null) + + def testWithOptionalDefMode(self): + self.__initWithOptional() + assert decoder.decode( + ints2octs((48, 15, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)), asn1Spec=self.s + ) == (self.s, null) + + def testWithOptionaIndefMode(self): + self.__initWithOptional() + assert decoder.decode( + ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 0, 0)), + asn1Spec=self.s + ) == (self.s, null) + + def testWithOptionalDefModeChunked(self): + self.__initWithOptional() + assert decoder.decode( + ints2octs((48, 21, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110)), + asn1Spec=self.s + ) == (self.s, null) + + def testWithOptionalIndefModeChunked(self): + self.__initWithOptional() + assert decoder.decode( + ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, + 0, 0, 0)), + asn1Spec=self.s + ) == (self.s, null) + + def testWithDefaultedDefMode(self): + self.__initWithDefaulted() + assert decoder.decode( + ints2octs((48, 5, 5, 0, 2, 1, 1)), asn1Spec=self.s + ) == (self.s, null) + + def testWithDefaultedIndefMode(self): + self.__initWithDefaulted() + assert decoder.decode( + ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s + ) == (self.s, null) + + def testWithDefaultedDefModeChunked(self): + self.__initWithDefaulted() + assert decoder.decode( + ints2octs((48, 5, 5, 0, 2, 1, 1)), asn1Spec=self.s + ) == (self.s, null) + + def testWithDefaultedIndefModeChunked(self): + self.__initWithDefaulted() + assert decoder.decode( + ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s + ) == (self.s, null) + + def testWithOptionalAndDefaultedDefMode(self): + self.__initWithOptionalAndDefaulted() + assert decoder.decode( + ints2octs((48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)), + asn1Spec=self.s + ) == (self.s, null) + + def testWithOptionalAndDefaultedIndefMode(self): + self.__initWithOptionalAndDefaulted() + assert decoder.decode( + ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, + 0, 0)), asn1Spec=self.s + ) == (self.s, null) + + def testWithOptionalAndDefaultedDefModeChunked(self): + self.__initWithOptionalAndDefaulted() + assert decoder.decode( + ints2octs( + (48, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1)), + asn1Spec=self.s + ) == (self.s, null) + + def testWithOptionalAndDefaultedIndefModeChunked(self): + self.__initWithOptionalAndDefaulted() + assert decoder.decode( + ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, + 0, 2, 1, 1, 0, 0)), asn1Spec=self.s + ) == (self.s, null) + + +class ChoiceDecoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Choice(componentType=namedtype.NamedTypes( + namedtype.NamedType('place-holder', univ.Null(null)), + namedtype.NamedType('number', univ.Integer(0)), + namedtype.NamedType('string', univ.OctetString()) + )) + + def testBySpec(self): + self.s.setComponentByPosition(0, univ.Null(null)) + assert decoder.decode( + ints2octs((5, 0)), asn1Spec=self.s + ) == (self.s, null) + + def testWithoutSpec(self): + self.s.setComponentByPosition(0, univ.Null(null)) + assert decoder.decode(ints2octs((5, 0))) == (self.s, null) + assert decoder.decode(ints2octs((5, 0))) == (univ.Null(null), null) + + def testUndefLength(self): + self.s.setComponentByPosition(2, univ.OctetString('abcdefgh')) + assert decoder.decode(ints2octs((36, 128, 4, 3, 97, 98, 99, 4, 3, 100, 101, 102, 4, 2, 103, 104, 0, 0)), + asn1Spec=self.s) == (self.s, null) + + def testExplicitTag(self): + s = self.s.subtype(explicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatConstructed, 4)) + s.setComponentByPosition(0, univ.Null(null)) + assert decoder.decode(ints2octs((164, 2, 5, 0)), asn1Spec=s) == (s, null) + + def testExplicitTagUndefLength(self): + s = self.s.subtype(explicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatConstructed, 4)) + s.setComponentByPosition(0, univ.Null(null)) + assert decoder.decode(ints2octs((164, 128, 5, 0, 0, 0)), asn1Spec=s) == (s, null) + + +class AnyDecoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Any() + + def testByUntagged(self): + assert decoder.decode( + ints2octs((4, 3, 102, 111, 120)), asn1Spec=self.s + ) == (univ.Any('\004\003fox'), null) + + def testTaggedEx(self): + s = univ.Any('\004\003fox').subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4)) + assert decoder.decode(ints2octs((164, 5, 4, 3, 102, 111, 120)), asn1Spec=s) == (s, null) + + def testTaggedIm(self): + s = univ.Any('\004\003fox').subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4)) + assert decoder.decode(ints2octs((132, 5, 4, 3, 102, 111, 120)), asn1Spec=s) == (s, null) + + def testByUntaggedIndefMode(self): + assert decoder.decode( + ints2octs((4, 3, 102, 111, 120)), asn1Spec=self.s + ) == (univ.Any('\004\003fox'), null) + + def testTaggedExIndefMode(self): + s = univ.Any('\004\003fox').subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4)) + assert decoder.decode(ints2octs((164, 128, 4, 3, 102, 111, 120, 0, 0)), asn1Spec=s) == (s, null) + + def testTaggedImIndefMode(self): + s = univ.Any('\004\003fox').subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4)) + assert decoder.decode(ints2octs((164, 128, 4, 3, 102, 111, 120, 0, 0)), asn1Spec=s) == (s, null) + + def testByUntaggedSubst(self): + assert decoder.decode( + ints2octs((4, 3, 102, 111, 120)), + asn1Spec=self.s, + substrateFun=lambda a, b, c: (b, c) + ) == (ints2octs((4, 3, 102, 111, 120)), 5) + + def testTaggedExSubst(self): + assert decoder.decode( + ints2octs((164, 5, 4, 3, 102, 111, 120)), + asn1Spec=self.s, + substrateFun=lambda a, b, c: (b, c) + ) == (ints2octs((164, 5, 4, 3, 102, 111, 120)), 7) + + +class EndOfOctetsTestCase(unittest.TestCase): + def testUnexpectedEoo(self): + try: + decoder.decode(ints2octs((0, 0))) + except PyAsn1Error: + pass + else: + assert 0, 'end-of-contents octets accepted at top level' + + def testExpectedEoo(self): + result, remainder = decoder.decode(ints2octs((0, 0)), allowEoo=True) + assert eoo.endOfOctets.isSameTypeWith(result) and result == eoo.endOfOctets + assert remainder == null + + def testDefiniteNoEoo(self): + try: + decoder.decode(ints2octs((0x23, 0x02, 0x00, 0x00))) + except PyAsn1Error: + pass + else: + assert 0, 'end-of-contents octets accepted inside definite-length encoding' + + def testIndefiniteEoo(self): + result, remainder = decoder.decode(ints2octs((0x23, 0x80, 0x00, 0x00))) + assert result == () and remainder == null, 'incorrect decoding of indefinite length end-of-octets' + + def testNoLongFormEoo(self): + try: + decoder.decode(ints2octs((0x23, 0x80, 0x00, 0x81, 0x00))) + except PyAsn1Error: + pass + else: + assert 0, 'end-of-contents octets accepted with invalid long-form length' + + def testNoConstructedEoo(self): + try: + decoder.decode(ints2octs((0x23, 0x80, 0x20, 0x00))) + except PyAsn1Error: + pass + else: + assert 0, 'end-of-contents octets accepted with invalid constructed encoding' + + def testNoEooData(self): + try: + decoder.decode(ints2octs((0x23, 0x80, 0x00, 0x01, 0x00))) + except PyAsn1Error: + pass + else: + assert 0, 'end-of-contents octets accepted with unexpected data' + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/ber/test_encoder.py b/tests/codec/ber/test_encoder.py new file mode 100644 index 0000000..48a916b --- /dev/null +++ b/tests/codec/ber/test_encoder.py @@ -0,0 +1,536 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +import sys +try: + import unittest2 as unittest +except ImportError: + import unittest + +from pyasn1.type import tag, namedtype, univ, char +from pyasn1.codec.ber import encoder +from pyasn1.compat.octets import ints2octs +from pyasn1.error import PyAsn1Error +from sys import version_info + + +class BadAsn1SpecTestCase(unittest.TestCase): + def testBadValueType(self): + try: + encoder.encode('not an Asn1Item') + except PyAsn1Error: + pass + else: + assert 0, 'Invalid value type accepted' + + +class LargeTagEncoderTestCase(unittest.TestCase): + def setUp(self): + self.o = univ.Integer().subtype( + value=1, explicitTag=tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 0xdeadbeaf) + ) + + def testEncoder(self): + assert encoder.encode(self.o) == ints2octs((127, 141, 245, 182, 253, 47, 3, 2, 1, 1)) + + +class IntegerEncoderTestCase(unittest.TestCase): + def testPosInt(self): + assert encoder.encode(univ.Integer(12)) == ints2octs((2, 1, 12)) + + def testNegInt(self): + assert encoder.encode(univ.Integer(-12)) == ints2octs((2, 1, 244)) + + def testZero(self): + assert encoder.encode(univ.Integer(0)) == ints2octs((2, 1, 0)) + + def testCompactZero(self): + encoder.IntegerEncoder.supportCompactZero = True + substrate = encoder.encode(univ.Integer(0)) + encoder.IntegerEncoder.supportCompactZero = False + assert substrate == ints2octs((2, 0)) + + def testMinusOne(self): + assert encoder.encode(univ.Integer(-1)) == ints2octs((2, 1, 255)) + + def testPosLong(self): + assert encoder.encode( + univ.Integer(0xffffffffffffffff) + ) == ints2octs((2, 9, 0, 255, 255, 255, 255, 255, 255, 255, 255)) + + def testNegLong(self): + assert encoder.encode( + univ.Integer(-0xffffffffffffffff) + ) == ints2octs((2, 9, 255, 0, 0, 0, 0, 0, 0, 0, 1)) + + +class BooleanEncoderTestCase(unittest.TestCase): + def testTrue(self): + assert encoder.encode(univ.Boolean(1)) == ints2octs((1, 1, 1)) + + def testFalse(self): + assert encoder.encode(univ.Boolean(0)) == ints2octs((1, 1, 0)) + + +class BitStringEncoderTestCase(unittest.TestCase): + def setUp(self): + self.b = univ.BitString((1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1)) + + def testDefMode(self): + assert encoder.encode(self.b) == ints2octs((3, 3, 1, 169, 138)) + + def testIndefMode(self): + assert encoder.encode( + self.b, defMode=0 + ) == ints2octs((3, 3, 1, 169, 138)) + + def testDefModeChunked(self): + assert encoder.encode( + self.b, maxChunkSize=1 + ) == ints2octs((35, 8, 3, 2, 0, 169, 3, 2, 1, 138)) + + def testIndefModeChunked(self): + assert encoder.encode( + self.b, defMode=0, maxChunkSize=1 + ) == ints2octs((35, 128, 3, 2, 0, 169, 3, 2, 1, 138, 0, 0)) + + def testEmptyValue(self): + assert encoder.encode(univ.BitString(())) == ints2octs((3, 1, 0)) + + +class OctetStringEncoderTestCase(unittest.TestCase): + def setUp(self): + self.o = univ.OctetString('Quick brown fox') + + def testDefMode(self): + assert encoder.encode(self.o) == ints2octs( + (4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)) + + def testIndefMode(self): + assert encoder.encode( + self.o, defMode=0 + ) == ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)) + + def testDefModeChunked(self): + assert encoder.encode( + self.o, maxChunkSize=4 + ) == ints2octs( + (36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120)) + + def testIndefModeChunked(self): + assert encoder.encode( + self.o, defMode=0, maxChunkSize=4 + ) == ints2octs(( + 36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, + 120, 0, 0)) + + +class ExpTaggedOctetStringEncoderTestCase(unittest.TestCase): + def setUp(self): + self.o = univ.OctetString().subtype( + value='Quick brown fox', + explicitTag=tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 5) + ) + + def testDefMode(self): + assert encoder.encode(self.o) == ints2octs( + (101, 17, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)) + + def testIndefMode(self): + assert encoder.encode( + self.o, defMode=0 + ) == ints2octs((101, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0)) + + def testDefModeChunked(self): + assert encoder.encode( + self.o, defMode=1, maxChunkSize=4 + ) == ints2octs((101, 25, 36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, + 102, 111, 120)) + + def testIndefModeChunked(self): + assert encoder.encode( + self.o, defMode=0, maxChunkSize=4 + ) == ints2octs(( + 101, 128, 36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, + 102, 111, 120, 0, 0, 0, 0)) + + +class NullEncoderTestCase(unittest.TestCase): + def testNull(self): + assert encoder.encode(univ.Null('')) == ints2octs((5, 0)) + + +class ObjectIdentifierEncoderTestCase(unittest.TestCase): + def testOne(self): + assert encoder.encode( + univ.ObjectIdentifier((1, 3, 6, 0, 0xffffe)) + ) == ints2octs((6, 6, 43, 6, 0, 191, 255, 126)) + + def testEdge1(self): + assert encoder.encode( + univ.ObjectIdentifier((0, 39)) + ) == ints2octs((6, 1, 39)) + + def testEdge2(self): + assert encoder.encode( + univ.ObjectIdentifier((1, 39)) + ) == ints2octs((6, 1, 79)) + + def testEdge3(self): + # 01111111 + assert encoder.encode( + univ.ObjectIdentifier((2, 40)) + ) == ints2octs((6, 1, 120)) + + def testEdge4(self): + # 10010000|10000000|10000000|10000000|01001111 + assert encoder.encode( + univ.ObjectIdentifier((2, 0xffffffff)) + ) == ints2octs((6, 5, 0x90, 0x80, 0x80, 0x80, 0x4F)) + + def testEdge5(self): + # 01111111 + assert encoder.encode( + univ.ObjectIdentifier((2, 47)) + ) == ints2octs((6, 1, 0x7F)) + + def testEdge6(self): + # 10000001|00000000 + assert encoder.encode( + univ.ObjectIdentifier((2, 48)) + ) == ints2octs((6, 2, 0x81, 0x00)) + + def testEdge7(self): + # 10000001|00110100|00000003 + assert encoder.encode( + univ.ObjectIdentifier((2, 100, 3)) + ) == ints2octs((6, 3, 0x81, 0x34, 0x03)) + + def testEdge8(self): + # 10000101|00000000 + assert encoder.encode( + univ.ObjectIdentifier((2, 560)) + ) == ints2octs((6, 2, 133, 0)) + + def testEdge9(self): + # 10001000|10000100|10000111|0000010 + assert encoder.encode( + univ.ObjectIdentifier((2, 16843570)) + ) == ints2octs((6, 4, 0x88, 0x84, 0x87, 0x02)) + + def testImpossible1(self): + try: + encoder.encode(univ.ObjectIdentifier((3, 1, 2))) + except PyAsn1Error: + pass + else: + assert 0, 'impossible leading arc tolerated' + + def testImpossible2(self): + try: + encoder.encode(univ.ObjectIdentifier((0,))) + except PyAsn1Error: + pass + else: + assert 0, 'single arc OID tolerated' + + def testImpossible3(self): + try: + encoder.encode(univ.ObjectIdentifier((0, 40))) + except PyAsn1Error: + pass + else: + assert 0, 'second arc overflow tolerated' + + def testImpossible4(self): + try: + encoder.encode(univ.ObjectIdentifier((1, 40))) + except PyAsn1Error: + pass + else: + assert 0, 'second arc overflow tolerated' + + def testLarge1(self): + assert encoder.encode( + univ.ObjectIdentifier((2, 18446744073709551535184467440737095)) + ) == ints2octs((0x06, 0x11, 0x83, 0xC6, 0xDF, 0xD4, 0xCC, 0xB3, 0xFF, 0xFF, 0xFE, 0xF0, 0xB8, 0xD6, 0xB8, 0xCB, + 0xE2, 0xB7, 0x17)) + + def testLarge2(self): + assert encoder.encode( + univ.ObjectIdentifier((2, 999, 18446744073709551535184467440737095)) + ) == ints2octs((0x06, 0x13, 0x88, 0x37, 0x83, 0xC6, 0xDF, 0xD4, 0xCC, 0xB3, 0xFF, 0xFF, 0xFE, 0xF0, 0xB8, 0xD6, + 0xB8, 0xCB, 0xE2, 0xB6, 0x47)) + + +class RealEncoderTestCase(unittest.TestCase): + def testChar(self): + assert encoder.encode( + univ.Real((123, 10, 11)) + ) == ints2octs((9, 7, 3, 49, 50, 51, 69, 49, 49)) + + def testBin1(self): + assert encoder.encode( # default binEncBase = 2 + univ.Real((0.5, 2, 0)) # check encbase = 2 and exponenta = -1 + ) == ints2octs((9, 3, 128, 255, 1)) + + def testBin2(self): + r = univ.Real((3.25, 2, 0)) + r.binEncBase = 8 # change binEncBase only for this instance of Real + assert encoder.encode( + r # check encbase = 8 + ) == ints2octs((9, 3, 148, 255, 13)) + + def testBin3(self): + # change binEncBase in the RealEncoder instance => for all further Reals + encoder.tagMap[univ.Real.tagSet].binEncBase = 16 + assert encoder.encode( + univ.Real((0.00390625, 2, 0)) # check encbase = 16 + ) == ints2octs((9, 3, 160, 254, 1)) + + def testBin4(self): + # choose binEncBase automatically for all further Reals (testBin[4-7]) + encoder.tagMap[univ.Real.tagSet].binEncBase = None + assert encoder.encode( + univ.Real((1, 2, 0)) # check exponenta = 0 + ) == ints2octs((9, 3, 128, 0, 1)) + + def testBin5(self): + assert encoder.encode( + univ.Real((3, 2, -1020)) # case of 2 octs for exponenta and + # negative exponenta and abs(exponenta) is + # all 1's and fills the whole octet(s) + ) == ints2octs((9, 4, 161, 255, 1, 3)) + + def testBin6(self): + assert encoder.encode( + univ.Real((1, 2, 262140)) # case of 3 octs for exponenta and + # check that first 9 bits for exponenta + # are not all 1's + ) == ints2octs((9, 5, 162, 0, 255, 255, 1)) + + def testBin7(self): + assert encoder.encode( + univ.Real((-1, 2, 76354972)) # case of >3 octs for exponenta and + # mantissa < 0 + ) == ints2octs((9, 7, 227, 4, 1, 35, 69, 103, 1)) + + def testPlusInf(self): + assert encoder.encode(univ.Real('inf')) == ints2octs((9, 1, 64)) + + def testMinusInf(self): + assert encoder.encode(univ.Real('-inf')) == ints2octs((9, 1, 65)) + + def testZero(self): + assert encoder.encode(univ.Real(0)) == ints2octs((9, 0)) + + +if version_info[0:2] > (2, 5): + class UniversalStringEncoderTestCase(unittest.TestCase): + def testEncoding(self): + assert encoder.encode(char.UniversalString(version_info[0] == 3 and 'abc' or unicode('abc'))) == ints2octs( + (28, 12, 0, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, 99)), 'Incorrect encoding' + + +class BMPStringEncoderTestCase(unittest.TestCase): + def testEncoding(self): + assert encoder.encode(char.BMPString(version_info[0] == 3 and 'abc' or unicode('abc'))) == ints2octs( + (30, 6, 0, 97, 0, 98, 0, 99)), 'Incorrect encoding' + + +class UTF8StringEncoderTestCase(unittest.TestCase): + def testEncoding(self): + assert encoder.encode(char.UTF8String(version_info[0] == 3 and 'abc' or unicode('abc'))) == ints2octs( + (12, 3, 97, 98, 99)), 'Incorrect encoding' + + +class SequenceEncoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Sequence(componentType=namedtype.NamedTypes( + namedtype.NamedType('place-holder', univ.Null('')), + namedtype.OptionalNamedType('first-name', univ.OctetString('')), + namedtype.DefaultedNamedType('age', univ.Integer(33)), + )) + + def __init(self): + self.s.clear() + self.s.setComponentByPosition(0) + + def __initWithOptional(self): + self.s.clear() + self.s.setComponentByPosition(0) + self.s.setComponentByPosition(1, 'quick brown') + + def __initWithDefaulted(self): + self.s.clear() + self.s.setComponentByPosition(0) + self.s.setComponentByPosition(2, 1) + + def __initWithOptionalAndDefaulted(self): + self.s.clear() + self.s.setComponentByPosition(0, univ.Null('')) + self.s.setComponentByPosition(1, univ.OctetString('quick brown')) + self.s.setComponentByPosition(2, univ.Integer(1)) + + def testDefMode(self): + self.__init() + assert encoder.encode(self.s) == ints2octs((48, 2, 5, 0)) + + def testIndefMode(self): + self.__init() + assert encoder.encode( + self.s, defMode=0 + ) == ints2octs((48, 128, 5, 0, 0, 0)) + + def testDefModeChunked(self): + self.__init() + assert encoder.encode( + self.s, defMode=1, maxChunkSize=4 + ) == ints2octs((48, 2, 5, 0)) + + def testIndefModeChunked(self): + self.__init() + assert encoder.encode( + self.s, defMode=0, maxChunkSize=4 + ) == ints2octs((48, 128, 5, 0, 0, 0)) + + def testWithOptionalDefMode(self): + self.__initWithOptional() + assert encoder.encode(self.s) == ints2octs( + (48, 15, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)) + + def testWithOptionalIndefMode(self): + self.__initWithOptional() + assert encoder.encode( + self.s, defMode=0 + ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0)) + + def testWithOptionalDefModeChunked(self): + self.__initWithOptional() + assert encoder.encode( + self.s, defMode=1, maxChunkSize=4 + ) == ints2octs((48, 21, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110)) + + def testWithOptionalIndefModeChunked(self): + self.__initWithOptional() + assert encoder.encode( + self.s, defMode=0, maxChunkSize=4 + ) == ints2octs( + (48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0)) + + def testWithDefaultedDefMode(self): + self.__initWithDefaulted() + assert encoder.encode(self.s) == ints2octs((48, 5, 5, 0, 2, 1, 1)) + + def testWithDefaultedIndefMode(self): + self.__initWithDefaulted() + assert encoder.encode( + self.s, defMode=0 + ) == ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0)) + + def testWithDefaultedDefModeChunked(self): + self.__initWithDefaulted() + assert encoder.encode( + self.s, defMode=1, maxChunkSize=4 + ) == ints2octs((48, 5, 5, 0, 2, 1, 1)) + + def testWithDefaultedIndefModeChunked(self): + self.__initWithDefaulted() + assert encoder.encode( + self.s, defMode=0, maxChunkSize=4 + ) == ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0)) + + def testWithOptionalAndDefaultedDefMode(self): + self.__initWithOptionalAndDefaulted() + assert encoder.encode(self.s) == ints2octs( + (48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)) + + def testWithOptionalAndDefaultedIndefMode(self): + self.__initWithOptionalAndDefaulted() + assert encoder.encode( + self.s, defMode=0 + ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1, 0, 0)) + + def testWithOptionalAndDefaultedDefModeChunked(self): + self.__initWithOptionalAndDefaulted() + assert encoder.encode( + self.s, defMode=1, maxChunkSize=4 + ) == ints2octs( + (48, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1)) + + def testWithOptionalAndDefaultedIndefModeChunked(self): + self.__initWithOptionalAndDefaulted() + assert encoder.encode( + self.s, defMode=0, maxChunkSize=4 + ) == ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, + 0, 2, 1, 1, 0, 0)) + + +class ChoiceEncoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Choice(componentType=namedtype.NamedTypes( + namedtype.NamedType('place-holder', univ.Null('')), + namedtype.NamedType('number', univ.Integer(0)), + namedtype.NamedType('string', univ.OctetString()) + )) + + def testEmpty(self): + try: + encoder.encode(self.s) + except PyAsn1Error: + pass + else: + assert 0, 'encoded unset choice' + + def testFilled(self): + self.s.setComponentByPosition(0, univ.Null('')) + assert encoder.encode(self.s) == ints2octs((5, 0)) + + def testTagged(self): + s = self.s.subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 4) + ) + s.setComponentByPosition(0, univ.Null('')) + assert encoder.encode(s) == ints2octs((164, 2, 5, 0)) + + def testUndefLength(self): + self.s.setComponentByPosition(2, univ.OctetString('abcdefgh')) + assert encoder.encode(self.s, defMode=False, maxChunkSize=3) == ints2octs( + (36, 128, 4, 3, 97, 98, 99, 4, 3, 100, 101, 102, 4, 2, 103, 104, 0, 0)) + + def testTaggedUndefLength(self): + s = self.s.subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 4) + ) + s.setComponentByPosition(2, univ.OctetString('abcdefgh')) + assert encoder.encode(s, defMode=False, maxChunkSize=3) == ints2octs( + (164, 128, 36, 128, 4, 3, 97, 98, 99, 4, 3, 100, 101, 102, 4, 2, 103, 104, 0, 0, 0, 0)) + + +class AnyEncoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Any(encoder.encode(univ.OctetString('fox'))) + + def testUntagged(self): + assert encoder.encode(self.s) == ints2octs((4, 3, 102, 111, 120)) + + def testTaggedEx(self): + s = self.s.subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4) + ) + assert encoder.encode(s) == ints2octs((164, 5, 4, 3, 102, 111, 120)) + + def testTaggedIm(self): + s = self.s.subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4) + ) + assert encoder.encode(s) == ints2octs((132, 5, 4, 3, 102, 111, 120)) + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/cer/__init__.py b/tests/codec/cer/__init__.py new file mode 100644 index 0000000..8c3066b --- /dev/null +++ b/tests/codec/cer/__init__.py @@ -0,0 +1 @@ +# This file is necessary to make this directory a package. diff --git a/tests/codec/cer/__main__.py b/tests/codec/cer/__main__.py new file mode 100644 index 0000000..f641b82 --- /dev/null +++ b/tests/codec/cer/__main__.py @@ -0,0 +1,20 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +try: + import unittest2 as unittest + +except ImportError: + import unittest + +suite = unittest.TestLoader().loadTestsFromNames( + ['tests.codec.cer.test_encoder.suite', + 'tests.codec.cer.test_decoder.suite'] +) + + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/cer/test_decoder.py b/tests/codec/cer/test_decoder.py new file mode 100644 index 0000000..3ae1f99 --- /dev/null +++ b/tests/codec/cer/test_decoder.py @@ -0,0 +1,68 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +import sys +try: + import unittest2 as unittest +except ImportError: + import unittest + +from pyasn1.codec.cer import decoder +from pyasn1.compat.octets import ints2octs, str2octs, null +from pyasn1.error import PyAsn1Error + + +class BooleanDecoderTestCase(unittest.TestCase): + def testTrue(self): + assert decoder.decode(ints2octs((1, 1, 255))) == (1, null) + + def testFalse(self): + assert decoder.decode(ints2octs((1, 1, 0))) == (0, null) + + def testEmpty(self): + try: + decoder.decode(ints2octs((1, 0))) + except PyAsn1Error: + pass + + def testOverflow(self): + try: + decoder.decode(ints2octs((1, 2, 0, 0))) + except PyAsn1Error: + pass + +class BitStringDecoderTestCase(unittest.TestCase): + def testShortMode(self): + assert decoder.decode( + ints2octs((3, 3, 6, 170, 128)) + ) == (((1, 0) * 5), null) + + def testLongMode(self): + assert decoder.decode( + ints2octs((3, 127, 6) + (170,) * 125 + (128,)) + ) == (((1, 0) * 501), null) + + # TODO: test failures on short chunked and long unchunked substrate samples + + +class OctetStringDecoderTestCase(unittest.TestCase): + def testShortMode(self): + assert decoder.decode( + ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)), + ) == (str2octs('Quick brown fox'), null) + + def testLongMode(self): + assert decoder.decode( + ints2octs((36, 128, 4, 130, 3, 232) + (81,) * 1000 + (4, 1, 81, 0, 0)) + ) == (str2octs('Q' * 1001), null) + + # TODO: test failures on short chunked and long unchunked substrate samples + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/cer/test_encoder.py b/tests/codec/cer/test_encoder.py new file mode 100644 index 0000000..0ced510 --- /dev/null +++ b/tests/codec/cer/test_encoder.py @@ -0,0 +1,193 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +import sys +try: + import unittest2 as unittest +except ImportError: + import unittest + +from pyasn1.type import namedtype, univ, useful +from pyasn1.codec.cer import encoder +from pyasn1.compat.octets import ints2octs +from pyasn1.error import PyAsn1Error + + +class BooleanEncoderTestCase(unittest.TestCase): + def testTrue(self): + assert encoder.encode(univ.Boolean(1)) == ints2octs((1, 1, 255)) + + def testFalse(self): + assert encoder.encode(univ.Boolean(0)) == ints2octs((1, 1, 0)) + + +class BitStringEncoderTestCase(unittest.TestCase): + def testShortMode(self): + assert encoder.encode( + univ.BitString((1, 0) * 5) + ) == ints2octs((3, 3, 6, 170, 128)) + + def testLongMode(self): + assert encoder.encode( + univ.BitString((1, 0) * 501) + ) == ints2octs((3, 127, 6) + (170,) * 125 + (128,)) + + +class OctetStringEncoderTestCase(unittest.TestCase): + def testShortMode(self): + assert encoder.encode( + univ.OctetString('Quick brown fox') + ) == ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)) + + def testLongMode(self): + assert encoder.encode( + univ.OctetString('Q' * 1001) + ) == ints2octs((36, 128, 4, 130, 3, 232) + (81,) * 1000 + (4, 1, 81, 0, 0)) + + +class SetEncoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Set(componentType=namedtype.NamedTypes( + namedtype.NamedType('place-holder', univ.Null('')), + namedtype.OptionalNamedType('first-name', univ.OctetString('')), + namedtype.DefaultedNamedType('age', univ.Integer(33)) + )) + + def __init(self): + self.s.clear() + self.s.setComponentByPosition(0) + + def __initWithOptional(self): + self.s.clear() + self.s.setComponentByPosition(0) + self.s.setComponentByPosition(1, 'quick brown') + + def __initWithDefaulted(self): + self.s.clear() + self.s.setComponentByPosition(0) + self.s.setComponentByPosition(2, 1) + + def __initWithOptionalAndDefaulted(self): + self.s.clear() + self.s.setComponentByPosition(0, univ.Null('')) + self.s.setComponentByPosition(1, univ.OctetString('quick brown')) + self.s.setComponentByPosition(2, univ.Integer(1)) + + def testIndefMode(self): + self.__init() + assert encoder.encode(self.s) == ints2octs((49, 128, 5, 0, 0, 0)) + + def testWithOptionalIndefMode(self): + self.__initWithOptional() + assert encoder.encode( + self.s + ) == ints2octs((49, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0)) + + def testWithDefaultedIndefMode(self): + self.__initWithDefaulted() + assert encoder.encode( + self.s + ) == ints2octs((49, 128, 2, 1, 1, 5, 0, 0, 0)) + + def testWithOptionalAndDefaultedIndefMode(self): + self.__initWithOptionalAndDefaulted() + assert encoder.encode( + self.s + ) == ints2octs((49, 128, 2, 1, 1, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0)) + + +class SetWithChoiceEncoderTestCase(unittest.TestCase): + def setUp(self): + c = univ.Choice(componentType=namedtype.NamedTypes( + namedtype.NamedType('actual', univ.Boolean(0)) + )) + self.s = univ.Set(componentType=namedtype.NamedTypes( + namedtype.NamedType('place-holder', univ.Null('')), + namedtype.NamedType('status', c) + )) + + def testIndefMode(self): + self.s.setComponentByPosition(0) + self.s.setComponentByName('status') + self.s.getComponentByName('status').setComponentByPosition(0, 1) + assert encoder.encode(self.s) == ints2octs((49, 128, 1, 1, 255, 5, 0, 0, 0)) + + +class GeneralizedTimeEncoderTestCase(unittest.TestCase): + # def testExtraZeroInSeconds(self): + # try: + # assert encoder.encode( + # useful.GeneralizedTime('20150501120112.10Z') + # ) + # except PyAsn1Error: + # pass + # else: + # assert 0, 'Meaningless trailing zero in fraction part tolerated' + + def testLocalTimezone(self): + try: + assert encoder.encode( + useful.GeneralizedTime('20150501120112.1+0200') + ) + except PyAsn1Error: + pass + else: + assert 0, 'Local timezone tolerated' + + def testMissingTimezone(self): + try: + assert encoder.encode( + useful.GeneralizedTime('20150501120112.1') + ) + except PyAsn1Error: + pass + else: + assert 0, 'Missing timezone tolerated' + + +# When enabled, this breaks many existing encodings +# +# def testDecimalPoint(self): +# try: +# assert encoder.encode( +# useful.GeneralizedTime('20150501120112Z') +# ) +# except PyAsn1Error: +# pass +# else: +# assert 0, 'Missing decimal point tolerated' + +class UTCTimeEncoderTestCase(unittest.TestCase): + def testFractionOfSecond(self): + try: + assert encoder.encode( + useful.UTCTime('150501120112.10Z') + ) + except PyAsn1Error: + pass + else: + assert 0, 'Decimal point tolerated' + + def testMissingTimezone(self): + assert encoder.encode( + useful.UTCTime('150501120112') + ) == ints2octs((23, 13, 49, 53, 48, 53, 48, 49, 49, 50, 48, 49, 49, 50, 90)), 'Missing timezone not added' + + def testLocalTimezone(self): + try: + assert encoder.encode( + useful.UTCTime('150501120112+0200') + ) + except PyAsn1Error: + pass + else: + assert 0, 'Local timezone tolerated' + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/der/__init__.py b/tests/codec/der/__init__.py new file mode 100644 index 0000000..8c3066b --- /dev/null +++ b/tests/codec/der/__init__.py @@ -0,0 +1 @@ +# This file is necessary to make this directory a package. diff --git a/tests/codec/der/__main__.py b/tests/codec/der/__main__.py new file mode 100644 index 0000000..0db3904 --- /dev/null +++ b/tests/codec/der/__main__.py @@ -0,0 +1,20 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +try: + import unittest2 as unittest + +except ImportError: + import unittest + +suite = unittest.TestLoader().loadTestsFromNames( + ['tests.codec.der.test_encoder.suite', + 'tests.codec.der.test_decoder.suite'] +) + + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/der/test_decoder.py b/tests/codec/der/test_decoder.py new file mode 100644 index 0000000..3fd55c3 --- /dev/null +++ b/tests/codec/der/test_decoder.py @@ -0,0 +1,75 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +import sys +try: + import unittest2 as unittest +except ImportError: + import unittest + +from pyasn1.codec.der import decoder +from pyasn1.compat.octets import ints2octs, null +from pyasn1.error import PyAsn1Error + + +class BitStringDecoderTestCase(unittest.TestCase): + def testShortMode(self): + assert decoder.decode( + ints2octs((3, 127, 6) + (170,) * 125 + (128,)) + ) == (((1, 0) * 501), null) + + def testIndefMode(self): + try: + decoder.decode( + ints2octs((35, 128, 3, 2, 0, 169, 3, 2, 1, 138, 0, 0)) + ) + except PyAsn1Error: + pass + else: + assert 0, 'indefinite length encoding tolerated' + + def testDefModeChunked(self): + try: + assert decoder.decode( + ints2octs((35, 8, 3, 2, 0, 169, 3, 2, 1, 138)) + ) + except PyAsn1Error: + pass + else: + assert 0, 'chunked encoding tolerated' + + +class OctetStringDecoderTestCase(unittest.TestCase): + def testShortMode(self): + assert decoder.decode( + '\004\017Quick brown fox'.encode() + ) == ('Quick brown fox'.encode(), ''.encode()) + + def testIndefMode(self): + try: + decoder.decode( + ints2octs((36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0)) + ) + except PyAsn1Error: + pass + else: + assert 0, 'indefinite length encoding tolerated' + + def testChunkedMode(self): + try: + decoder.decode( + ints2octs((36, 23, 4, 2, 81, 117, 4, 2, 105, 99, 4, 2, 107, 32, 4, 2, 98, 114, 4, 2, 111, 119, 4, 1, 110)) + ) + except PyAsn1Error: + pass + else: + assert 0, 'chunked encoding tolerated' + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/der/test_encoder.py b/tests/codec/der/test_encoder.py new file mode 100644 index 0000000..b514e3b --- /dev/null +++ b/tests/codec/der/test_encoder.py @@ -0,0 +1,70 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +import sys +try: + import unittest2 as unittest +except ImportError: + import unittest + +from pyasn1.type import namedtype, univ +from pyasn1.codec.der import encoder +from pyasn1.compat.octets import ints2octs +from pyasn1.error import PyAsn1Error + + +class OctetStringEncoderTestCase(unittest.TestCase): + def testShortMode(self): + assert encoder.encode( + univ.OctetString('Quick brown fox') + ) == ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)) + + def testIndefMode(self): + try: + encoder.encode(univ.OctetString('Quick brown'), defMode=0) + except PyAsn1Error: + pass + else: + assert 0, 'Indefinite length encoding tolerated' + + def testChunkedMode(self): + try: + x = encoder.encode(univ.OctetString('Quick brown'), maxChunkSize=2) + except PyAsn1Error: + pass + else: + assert 0, 'Chunked encoding tolerated' + + +class BitStringEncoderTestCase(unittest.TestCase): + def testShortMode(self): + assert encoder.encode( + univ.BitString((1,)) + ) == ints2octs((3, 2, 7, 128)) + + +class SetWithChoiceEncoderTestCase(unittest.TestCase): + def setUp(self): + c = univ.Choice(componentType=namedtype.NamedTypes( + namedtype.NamedType('name', univ.OctetString('')), + namedtype.NamedType('amount', univ.Integer(0))) + ) + self.s = univ.Set(componentType=namedtype.NamedTypes( + namedtype.NamedType('place-holder', univ.Null('')), + namedtype.NamedType('status', c)) + ) + + def testDefMode(self): + self.s.setComponentByPosition(0) + self.s.setComponentByName('status') + self.s.getComponentByName('status').setComponentByPosition(0, 'ann') + assert encoder.encode(self.s) == ints2octs((49, 7, 4, 3, 97, 110, 110, 5, 0)) + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/native/__init__.py b/tests/codec/native/__init__.py new file mode 100644 index 0000000..8c3066b --- /dev/null +++ b/tests/codec/native/__init__.py @@ -0,0 +1 @@ +# This file is necessary to make this directory a package. diff --git a/tests/codec/native/__main__.py b/tests/codec/native/__main__.py new file mode 100644 index 0000000..89f0e06 --- /dev/null +++ b/tests/codec/native/__main__.py @@ -0,0 +1,19 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +try: + import unittest2 as unittest + +except ImportError: + import unittest + +suite = unittest.TestLoader().loadTestsFromNames( + ['tests.codec.native.test_encoder.suite', + 'tests.codec.native.test_decoder.suite'] +) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/native/test_decoder.py b/tests/codec/native/test_decoder.py new file mode 100644 index 0000000..16fddfc --- /dev/null +++ b/tests/codec/native/test_decoder.py @@ -0,0 +1,114 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +import sys +try: + import unittest2 as unittest +except ImportError: + import unittest + +from pyasn1.type import tag, namedtype, univ, char +from pyasn1.codec.native import decoder +from pyasn1.error import PyAsn1Error + + +class BadAsn1SpecTestCase(unittest.TestCase): + def testBadSpec(self): + try: + decoder.decode('', asn1Spec='not an Asn1Item') + except PyAsn1Error: + pass + else: + assert 0, 'Invalid asn1Spec accepted' + + +class IntegerDecoderTestCase(unittest.TestCase): + def testPosInt(self): + assert decoder.decode(12, asn1Spec=univ.Integer()) == univ.Integer(12) + + def testNegInt(self): + assert decoder.decode(-12, asn1Spec=univ.Integer()) == univ.Integer(-12) + + +class BooleanDecoderTestCase(unittest.TestCase): + def testTrue(self): + assert decoder.decode(True, asn1Spec=univ.Boolean()) == univ.Boolean(True) + + def testTrueNeg(self): + assert decoder.decode(False, asn1Spec=univ.Boolean()) == univ.Boolean(False) + + +class BitStringDecoderTestCase(unittest.TestCase): + def testSimple(self): + assert decoder.decode('11111111', asn1Spec=univ.BitString()) == univ.BitString(hexValue='ff') + + +class OctetStringDecoderTestCase(unittest.TestCase): + def testSimple(self): + assert decoder.decode('Quick brown fox', asn1Spec=univ.OctetString()) == univ.OctetString('Quick brown fox') + + +class NullDecoderTestCase(unittest.TestCase): + def testNull(self): + assert decoder.decode(None, asn1Spec=univ.Null()) == univ.Null() + + +class ObjectIdentifierDecoderTestCase(unittest.TestCase): + def testOne(self): + assert decoder.decode('1.3.6.11', asn1Spec=univ.ObjectIdentifier()) == univ.ObjectIdentifier('1.3.6.11') + + +class RealDecoderTestCase(unittest.TestCase): + def testSimple(self): + assert decoder.decode(1.33, asn1Spec=univ.Real()) == univ.Real(1.33) + + +class SequenceDecoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('place-holder', univ.Null()), + namedtype.NamedType('first-name', univ.OctetString()), + namedtype.NamedType('age', univ.Integer(33)) + ) + ) + + def testSimple(self): + s = self.s.clone() + s[0] = univ.Null() + s[1] = univ.OctetString('xx') + s[2] = univ.Integer(33) + assert decoder.decode({'place-holder': None, 'first-name': 'xx', 'age': 33}, asn1Spec=self.s) == s + + +class ChoiceDecoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Choice( + componentType=namedtype.NamedTypes( + namedtype.NamedType('place-holder', univ.Null()), + namedtype.NamedType('first-name', univ.OctetString()), + namedtype.NamedType('age', univ.Integer(33)) + ) + ) + + def testSimple(self): + s = self.s.clone() + s[1] = univ.OctetString('xx') + assert decoder.decode({'first-name': 'xx'}, asn1Spec=self.s) == s + + +class AnyDecoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Any() + + def testSimple(self): + assert decoder.decode('fox', asn1Spec=univ.Any()) == univ.Any('fox') + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/native/test_encoder.py b/tests/codec/native/test_encoder.py new file mode 100644 index 0000000..a1d9efc --- /dev/null +++ b/tests/codec/native/test_encoder.py @@ -0,0 +1,130 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +import sys +try: + import unittest2 as unittest +except ImportError: + import unittest + +from pyasn1.type import tag, namedtype, univ +from pyasn1.codec.native import encoder +from pyasn1.compat.octets import str2octs +from pyasn1.error import PyAsn1Error + + +class BadAsn1SpecTestCase(unittest.TestCase): + def testBadValueType(self): + try: + encoder.encode('not an Asn1Item') + except PyAsn1Error: + pass + else: + assert 0, 'Invalid value type accepted' + + +class IntegerEncoderTestCase(unittest.TestCase): + def testPosInt(self): + assert encoder.encode(univ.Integer(12)) == 12 + + def testNegInt(self): + assert encoder.encode(univ.Integer(-12)) == -12 + + +class BooleanEncoderTestCase(unittest.TestCase): + def testTrue(self): + assert encoder.encode(univ.Boolean(1)) is True + + def testFalse(self): + assert encoder.encode(univ.Boolean(0)) is False + + +class BitStringEncoderTestCase(unittest.TestCase): + def setUp(self): + self.b = univ.BitString((1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1)) + + def testValue(self): + assert encoder.encode(self.b) == '101010011000101' + + +class OctetStringEncoderTestCase(unittest.TestCase): + def setUp(self): + self.o = univ.OctetString('Quick brown fox') + + def testValue(self): + assert encoder.encode(self.o) == str2octs('Quick brown fox') + + +class NullEncoderTestCase(unittest.TestCase): + def testNull(self): + assert encoder.encode(univ.Null('')) is None + + +class ObjectIdentifierEncoderTestCase(unittest.TestCase): + def testOne(self): + assert encoder.encode(univ.ObjectIdentifier((1, 3, 6, 0, 12345))) == '1.3.6.0.12345' + + +class RealEncoderTestCase(unittest.TestCase): + def testChar(self): + assert encoder.encode(univ.Real((123, 10, 11))) == 1.23e+13 + + def testPlusInf(self): + assert encoder.encode(univ.Real('inf')) == float('inf') + + def testMinusInf(self): + assert encoder.encode(univ.Real('-inf')) == float('-inf') + + +class SequenceEncoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Sequence(componentType=namedtype.NamedTypes( + namedtype.NamedType('place-holder', univ.Null('')), + namedtype.OptionalNamedType('first-name', univ.OctetString('')), + namedtype.DefaultedNamedType('age', univ.Integer(33)), + )) + + def testSimple(self): + s = self.s.clone() + s[0] = univ.Null('') + s[1] = 'abc' + s[2] = 123 + assert encoder.encode(s) == {'place-holder': None, 'first-name': str2octs('abc'), 'age': 123} + + +class ChoiceEncoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Choice(componentType=namedtype.NamedTypes( + namedtype.NamedType('place-holder', univ.Null('')), + namedtype.NamedType('number', univ.Integer(0)), + namedtype.NamedType('string', univ.OctetString()) + )) + + def testEmpty(self): + try: + encoder.encode(self.s) + except PyAsn1Error: + pass + else: + assert False, 'encoded unset choice' + + def testFilled(self): + self.s.setComponentByPosition(0, univ.Null('')) + assert encoder.encode(self.s) == {'place-holder': None} + + +class AnyEncoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Any(encoder.encode(univ.OctetString('fox'))) + + def testSimple(self): + assert encoder.encode(self.s) == str2octs('fox') + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) |