def test_missing_parameterized_type(self): with self.assertRaises(asn1tools.CompileError) as cm: asn1tools.compile_string( 'A DEFINITIONS ::= BEGIN' ' B ::= NULL ' ' B-Integer ::= B { INTEGER } ' 'END ', 'uper') self.assertEqual(str(cm.exception), "Type 'B' in module 'A' is not parameterized.")
def test_wrong_parameterized_type_number_of_parameters(self): with self.assertRaises(asn1tools.CompileError) as cm: asn1tools.compile_string( 'A DEFINITIONS ::= BEGIN' ' B { C, D } ::= SEQUENCE { ' ' a C, ' ' b D ' ' } ' ' B-Integer ::= B { INTEGER } ' 'END ', 'uper') self.assertEqual( str(cm.exception), "Parameterized type 'B' in module 'A' takes 2 parameters, " "but 1 are given in type 'B-Integer' in module 'A'.")
def compile_files(schema_list, asn1_format): try: return asn1tools.compile_files(schema_list, asn1_format) except asn1tools.parser.ParseError: # Parse each file in turn in case there's a syntax error, so we can tell the # user which file has the problem. for path in schema_list: f_contents = open(path).read() try: asn1tools.compile_string(f_contents) except asn1tools.parser.ParseError as exception: print("While parsing %s:" % path) print(exception) sys.exit(1) assert 0
def test_set(self): foo = asn1tools.compile_string( "Foo DEFINITIONS IMPLICIT TAGS ::= " "BEGIN " "A ::= SET { " " a [0] INTEGER, " " b [1] INTEGER " "} " "B ::= SET { " " b [1] INTEGER, " " a [0] INTEGER " "} " "END", 'ber') datas = [('A', { 'a': 3, 'b': 4 }, b'\x31\x06\x80\x01\x03\x81\x01\x04'), ('B', { 'a': 3, 'b': 4 }, b'\x31\x06\x80\x01\x03\x81\x01\x04')] for type_name, decoded, encoded in datas: self.assert_encode_decode(foo, type_name, decoded, encoded)
def test_integer(self): foo = asn1tools.compile_string( "Foo DEFINITIONS ::= " "BEGIN " "A ::= INTEGER " "END", 'der') datas = [ ('A', 32768, b'\x02\x03\x00\x80\x00'), ('A', 32767, b'\x02\x02\x7f\xff'), ('A', 256, b'\x02\x02\x01\x00'), ('A', 255, b'\x02\x02\x00\xff'), ('A', 128, b'\x02\x02\x00\x80'), ('A', 127, b'\x02\x01\x7f'), ('A', 1, b'\x02\x01\x01'), ('A', 0, b'\x02\x01\x00'), ('A', -1, b'\x02\x01\xff'), ('A', -128, b'\x02\x01\x80'), ('A', -129, b'\x02\x02\xff\x7f'), ('A', -256, b'\x02\x02\xff\x00'), ('A', -32768, b'\x02\x02\x80\x00'), ('A', -32769, b'\x02\x03\xff\x7f\xff'), ('A', 1 << 2048, b'\x02\x82\x01\x01\x01' + 256 * b'\x00') ] for type_name, decoded, encoded in datas: self.assert_encode_decode(foo, type_name, decoded, encoded)
def test_choice(self): foo = asn1tools.compile_string( "Foo DEFINITIONS AUTOMATIC TAGS ::= " "BEGIN " "A ::= CHOICE { " " a BOOLEAN, " " b INTEGER " "} " "END", 'jer') datas = [('A', ('a', True), b'{"a": true}'), ('A', ('b', 3), b'{"b": 3}')] for type_name, decoded, encoded in datas: self.assert_encode_decode_string(foo, type_name, decoded, encoded) # Encode error. with self.assertRaises(asn1tools.EncodeError) as cm: foo.encode('A', ('c', None)) self.assertEqual(str(cm.exception), "A: Expected choice 'a' or 'b', but got 'c'.") # Decode error. with self.assertRaises(asn1tools.DecodeError) as cm: foo.decode('A', b'{"c": null}') self.assertEqual(str(cm.exception), "A: Expected choice 'a' or 'b', but got 'c'.")
def test_indent(self): foo = asn1tools.compile_string( "Foo DEFINITIONS AUTOMATIC TAGS ::= " "BEGIN " "A ::= SEQUENCE { " " a SEQUENCE { " " b BOOLEAN, " " c INTEGER " " } " "} " "END", 'jer') datas = [('A', { 'a': { 'b': True, 'c': 5 } }, [ b'{', b' "a": {', b' "c": 5,', b' "c": 5, ', b' "b": true,', b' "b": true, ', b' "c": 5', b' "b": true', b' }', b'}' ])] for type_name, decoded, encoded_lines in datas: encoded = foo.encode(type_name, decoded, indent=4) for line in encoded.splitlines(): self.assertIn(line, encoded_lines)
def test_generalized_time(self): foo = asn1tools.compile_string( "Foo DEFINITIONS AUTOMATIC TAGS ::= " "BEGIN " "A ::= GeneralizedTime " "END", 'der') datas = [ ('A', datetime(2018, 1, 22, 13, 29), b'\x18\x0f\x32\x30\x31\x38\x30\x31\x32\x32\x31\x33\x32\x39\x30' b'\x30\x5a'), ('A', datetime(2018, 1, 22, 13, 0), b'\x18\x0f\x32\x30\x31\x38\x30\x31\x32\x32\x31\x33\x30\x30\x30' b'\x30\x5a'), ('A', datetime(2000, 12, 31, 23, 59, 59), b'\x18\x0f\x32\x30\x30\x30\x31\x32\x33\x31\x32\x33\x35\x39' b'\x35\x39\x5a'), ] for type_name, decoded, encoded in datas: self.assert_encode_decode(foo, type_name, decoded, encoded)
def test_sequence_of(self): all_types = asn1tools.compile_string( "Foo DEFINITIONS AUTOMATIC TAGS ::= " "BEGIN " "A ::= SEQUENCE OF INTEGER " "B ::= SEQUENCE OF A " "C ::= SEQUENCE OF BOOLEAN " "D ::= SEQUENCE OF E " "E ::= BOOLEAN " "F ::= SEQUENCE OF CHOICE { a BOOLEAN, b INTEGER } " "G ::= SEQUENCE OF ENUMERATED { one } " "H ::= SEQUENCE OF SEQUENCE { a INTEGER } " "END", 'xer') datas = [ ('A', [], b'<A />'), ('A', [1, 4], b'<A><INTEGER>1</INTEGER><INTEGER>4</INTEGER></A>'), ('B', [[5]], b'<B><A><INTEGER>5</INTEGER></A></B>'), ('C', [True, False], b'<C><true /><false /></C>'), ('D', [True], b'<D><true /></D>'), ('F', [('a', True), ('b', 1)], b'<F><a><true /></a><b>1</b></F>'), ('G', ['one'], b'<G><one /></G>'), ('H', [{'a': 1}], b'<H><SEQUENCE><a>1</a></SEQUENCE></H>') ] for type_name, decoded, encoded in datas: self.assert_encode_decode_string(all_types, type_name, decoded, encoded)
def test_out_of_data(self): foo = asn1tools.compile_string( "Foo DEFINITIONS AUTOMATIC TAGS ::= " "BEGIN " "A ::= BOOLEAN " "B ::= OCTET STRING " "C ::= SEQUENCE { " " ..., " " a BOOLEAN " "} " "END", 'oer') # Fails trying to read a non-negative number. with self.assertRaises(asn1tools.DecodeError) as cm: foo.decode('A', b'') self.assertEqual(str(cm.exception), "out of data at bit offset 0 (0.0 bytes)") # Fails trying to read 2 bytes, but only one available. with self.assertRaises(asn1tools.DecodeError) as cm: foo.decode('B', b'\x02\x00') self.assertEqual(str(cm.exception), "out of data at bit offset 8 (1.0 bytes)") # Fails trying to read the single additions present bit. with self.assertRaises(asn1tools.DecodeError) as cm: foo.decode('C', b'') self.assertEqual(str(cm.exception), "out of data at bit offset 0 (0.0 bytes)")
def calc_eth_address(pub_key) -> str: SUBJECT_ASN = ''' Key DEFINITIONS ::= BEGIN SubjectPublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier, subjectPublicKey BIT STRING } AlgorithmIdentifier ::= SEQUENCE { algorithm OBJECT IDENTIFIER, parameters ANY DEFINED BY algorithm OPTIONAL } END ''' key = asn1tools.compile_string(SUBJECT_ASN) key_decoded = key.decode('SubjectPublicKeyInfo', pub_key) pub_key_raw = key_decoded['subjectPublicKey'][0] pub_key = pub_key_raw[1:len(pub_key_raw)] # https://www.oreilly.com/library/view/mastering-ethereum/9781491971932/ch04.html hex_address = w3.keccak(bytes(pub_key)).hex() eth_address = '0x{}'.format(hex_address[-40:]) eth_checksum_addr = w3.toChecksumAddress(eth_address) return eth_checksum_addr
def test_sequence(self): foo = asn1tools.compile_string( "Foo DEFINITIONS AUTOMATIC TAGS ::= " "BEGIN " "A ::= SEQUENCE { " " a BOOLEAN, " " b BOOLEAN OPTIONAL " "}" "B ::= SEQUENCE { " " a BOOLEAN DEFAULT TRUE " "}" "END", 'gser') datas = [('A', { 'a': True }, b'a A ::= { a TRUE }'), ('A', { 'a': False, 'b': True }, b'a A ::= { a FALSE, b TRUE }'), ('B', {}, b'b B ::= { }')] for name, decoded, encoded in datas: self.assertEqual(foo.encode(name, decoded), encoded) # Missing member. with self.assertRaises(asn1tools.EncodeError) as cm: foo.encode('A', {}) self.assertEqual(str(cm.exception), "Sequence member 'a' not found in {}.")
def test_integer(self): foo = asn1tools.compile_string( "Foo DEFINITIONS AUTOMATIC TAGS ::= " "BEGIN " "A ::= INTEGER " "B ::= INTEGER (-128..127) " "C ::= INTEGER (-32768..32767) " "D ::= INTEGER (-2147483648..2147483647) " "E ::= INTEGER (-9223372036854775808..9223372036854775807) " "F ::= INTEGER (0..255) " "G ::= INTEGER (0..65536) " "H ::= INTEGER (0..4294967296) " "I ::= INTEGER (0..18446744073709551615) " "J ::= INTEGER (0..18446744073709551616) " "END", 'oer') datas = [('A', 0, b'\x01\x00'), ('A', 128, b'\x02\x00\x80'), ('A', 100000, b'\x03\x01\x86\xa0'), ('A', -255, b'\x02\xff\x01'), ('A', -1234567, b'\x03\xed\x29\x79'), ('B', -2, b'\xfe'), ('C', -2, b'\xff\xfe'), ('D', -2, b'\xff\xff\xff\xfe'), ('E', -2, b'\xff\xff\xff\xff\xff\xff\xff\xfe'), ('B', 1, b'\x01'), ('C', 1, b'\x00\x01'), ('D', 1, b'\x00\x00\x00\x01'), ('E', 1, b'\x00\x00\x00\x00\x00\x00\x00\x01'), ('B', 127, b'\x7f'), ('C', 127, b'\x00\x7f'), ('D', 127, b'\x00\x00\x00\x7f'), ('E', 127, b'\x00\x00\x00\x00\x00\x00\x00\x7f'), ('J', 1, b'\x01\x01')] for type_name, decoded, encoded in datas: self.assert_encode_decode(foo, type_name, decoded, encoded)
def test_sequence(self): foo = asn1tools.compile_string( "Foo DEFINITIONS AUTOMATIC TAGS ::= " "BEGIN " "A ::= SEQUENCE { " " a SEQUENCE OF A OPTIONAL " "} " "B ::= SEQUENCE { " " a INTEGER DEFAULT 4 " "} " "END", 'xer') datas = [('A', {}, b'<A />'), ('A', { 'a': [{}] }, b'<A><a><A /></a></A>'), ('A', { 'a': [{ 'a': [] }] }, b'<A><a><A><a /></A></a></A>')] for type_name, decoded, encoded in datas: self.assert_encode_decode_string(foo, type_name, decoded, encoded) # Non-symmetrical encoding and decoding. self.assertEqual(foo.encode('B', {}), b'<B />') self.assertEqual(foo.decode('B', b'<B />'), {'a': 4})
def test_visible_string(self): foo = asn1tools.compile_string( "Foo DEFINITIONS AUTOMATIC TAGS ::= " "BEGIN " "A ::= VisibleString " "B ::= VisibleString (SIZE (2..5)) " "C ::= VisibleString (FROM (\"a\"..\"j\" | \"u\"..\"w\")) " "D ::= VisibleString (SIZE (2..5, ...)) " "END") # Ok. datas = [('A', '123'), ('B', '12'), ('B', '12345'), ('C', 'abijuvw'), ('D', '123456')] self.assert_encode_decode_ok(foo, datas) # Not ok. datas = [ ('B', '1', 'Expected between 2 and 5 characters, but got 1.'), ('B', '123456', 'Expected between 2 and 5 characters, but got 6.'), ('C', 'k', "Expected a character in 'abcdefghijuvw', but got 'k' (0x6b).") ] self.assert_encode_decode_bad(foo, datas)
def test_sequence_of(self): foo = asn1tools.compile_string( "Foo DEFINITIONS AUTOMATIC TAGS ::= " "BEGIN " "A ::= SEQUENCE (SIZE (2)) OF INTEGER (3..5)" "B ::= SEQUENCE (SIZE (2, ...)) OF INTEGER (3..5)" "C ::= SEQUENCE (SIZE (MIN..2)) OF INTEGER (3..5)" "END") # Ok. datas = [('A', [3, 4]), ('B', [3, 4, 5]), ('C', [3, 4])] self.assert_encode_decode_ok(foo, datas) # Not ok. datas = [ ('A', [3, 4, 5], 'A: Expected a list of between 2 and 2 elements, but got 3.'), ('A', [3, 6], 'A: Expected an integer between 3 and 5, but got 6.'), ('C', [3, 4, 5], 'C: Expected a list of between MIN and 2 elements, but got 3.') ] self.assert_encode_decode_bad(foo, datas)
def test_indent(self): foo = asn1tools.compile_string( "Foo DEFINITIONS AUTOMATIC TAGS ::= " "BEGIN " "A ::= SEQUENCE { " " a SEQUENCE { " " b BOOLEAN, " " c INTEGER " " } " "} " "END", 'xer') datas = [ ('A', {'a': {'b': True, 'c': 5}}, (b'<A>\n' b' <a>\n' b' <b>\n' b' <true />\n' b' </b>\n' b' <c>5</c>\n' b' </a>\n' b'</A>\n')) ] for type_name, decoded, encoded in datas: self.assert_encode_decode_string(foo, type_name, decoded, encoded, indent=4)
def test_enumerated(self): foo = asn1tools.compile_string( "Foo DEFINITIONS AUTOMATIC TAGS ::= " "BEGIN " "A ::= ENUMERATED { a(1) } " "B ::= ENUMERATED { a(128) } " "C ::= ENUMERATED { a(0), b(127) } " "D ::= ENUMERATED { a(0), ..., b(127) } " "E ::= ENUMERATED { a(-1), b(1234) } " "END", 'oer') datas = [('A', 'a', b'\x01'), ('B', 'a', b'\x82\x00\x80'), ('C', 'a', b'\x00'), ('C', 'b', b'\x7f'), ('D', 'a', b'\x00'), ('D', 'b', b'\x7f'), ('E', 'a', b'\x81\xff'), ('E', 'b', b'\x82\x04\xd2')] for type_name, decoded, encoded in datas: self.assert_encode_decode(foo, type_name, decoded, encoded) # Encoding bad enumeration value. with self.assertRaises(asn1tools.EncodeError) as cm: foo.encode('C', 'c') self.assertEqual( str(cm.exception), "Expected enumeration value 'a' or 'b', but got 'c'.") # Decoding bad enumeration value. with self.assertRaises(asn1tools.DecodeError) as cm: foo.decode('A', b'\x02') self.assertEqual(str(cm.exception), "Expected enumeration value 1, but got 2.")
def test_enumerated(self): foo = asn1tools.compile_string( "Foo DEFINITIONS AUTOMATIC TAGS ::= " "BEGIN " "A ::= ENUMERATED { " " a(1), " " b(3) " "} " "END", 'jer') datas = [('A', 'a', b'"a"'), ('A', 'b', b'"b"')] for type_name, decoded, encoded in datas: self.assert_encode_decode_string(foo, type_name, decoded, encoded) # Encode error. with self.assertRaises(asn1tools.EncodeError) as cm: foo.encode('A', 'c') self.assertEqual( str(cm.exception), "A: Expected enumeration value 'a' or 'b', but got 'c'.") # Decode error. with self.assertRaises(asn1tools.DecodeError) as cm: foo.decode('A', b'"c"') self.assertEqual( str(cm.exception), "A: Expected enumeration value 'a' or 'b', but got 'c'.")
def encode_decode_codecs(self, type_spec, decoded, encoded): spec = ("Foo DEFINITIONS AUTOMATIC TAGS ::= " "BEGIN " "A ::= " + type_spec + " " + "END") for codec, encoded_message in zip(ALL_CODECS, encoded): foo = asn1tools.compile_string(spec, codec) self.encode_decode_codec(foo, codec, 'A', decoded, encoded_message)
def encode_decode(codec): spec = asn1tools.compile_string( 'Ber DEFINITIONS ::= BEGIN ' ' A ::= SEQUENCE { ' ' a BOOLEAN, ' ' b INTEGER, ' # ' c REAL, ' ' d NULL, ' ' e BIT STRING, ' ' f OCTET STRING, ' ' g OBJECT IDENTIFIER, ' ' h ENUMERATED {a, b}, ' ' i SEQUENCE {}, ' ' j SEQUENCE OF NULL, ' ' k SET {}, ' ' l SET OF NULL, ' ' m CHOICE {a NULL}, ' ' n UTF8String, ' ' o UTCTime, ' ' p GeneralizedTime ' '} ' 'END', codec) decoded = { 'a': True, 'b': 12345678, # 'c': 3.14159, 'd': None, 'e': (b'\x11\x22\x33\x44\x55\x66\x77', 55), 'f': 10 * b'x11\x22\x33\x44\x55\x66\x77', 'g': '1.4.123.4325.23.1.44.22222', 'h': 'b', 'i': {}, 'j': 5 * [None], 'k': {}, 'l': 5 * [None], 'm': ('a', None), 'n': 40 * 'a', 'o': datetime(2018, 6, 13, 11, 1, 59), 'p': datetime(2018, 6, 13, 11, 1, 58, 5000) } try: encoded = spec.encode('A', decoded) except: return float('inf'), float('inf') def encode(): spec.encode('A', decoded) def decode(): spec.decode('A', encoded) encode_time = timeit.timeit(encode, number=ITERATIONS) decode_time = timeit.timeit(decode, number=ITERATIONS) return encode_time, decode_time
def test_integer(self): foo = asn1tools.compile_string("Foo DEFINITIONS AUTOMATIC TAGS ::= " "BEGIN " "A ::= INTEGER " "B ::= INTEGER (5..99) " "C ::= INTEGER (-10..10) " "D ::= INTEGER (5..99, ...) " "E ::= INTEGER (1000..1000) " "F ::= SEQUENCE { " " a INTEGER (4..4), " " b INTEGER (40..40), " " c INTEGER (400..400) " "} " "G ::= B (6..7) " "H ::= INTEGER (MIN..10) " "I ::= INTEGER (10..MAX) " "J ::= INTEGER (MIN..MAX) " "K ::= INTEGER (1..2 | 4..5) " "END") # Ok. datas = [('A', 32768), ('A', 0), ('A', -32769), ('B', 5), ('B', 6), ('B', 99), ('C', -10), ('C', 10), ('D', 99), ('E', 1000), ('F', { 'a': 4, 'b': 40, 'c': 400 }), ('H', -1000), ('H', 10), ('I', 10), ('I', 1000), ('J', -1000), ('J', 1000), ('K', 1), ('K', 2)] self.assert_encode_decode_ok(foo, datas) # ToDo: These should be good. datas = [('K', 4, 'Expected an integer between 1 and 2, but got 4.'), ('K', 5, 'Expected an integer between 1 and 2, but got 5.')] self.assert_encode_decode_bad(foo, datas) # Not ok. datas = [ ('B', 4, 'Expected an integer between 5 and 99, but got 4.'), ('B', 100, 'Expected an integer between 5 and 99, but got 100.'), ('C', -11, 'Expected an integer between -10 and 10, but got -11.'), ('C', 11, 'Expected an integer between -10 and 10, but got 11.'), ('E', 0, 'Expected an integer between 1000 and 1000, but got 0.'), ('F', { 'a': 4, 'b': 41, 'c': 400 }, 'b: Expected an integer between 40 and 40, but got 41.'), ('H', 11, 'Expected an integer between MIN and 10, but got 11.'), ('I', 9, 'Expected an integer between 10 and MAX, but got 9.'), # ToDo: 4..5 are allowed as well. ('K', 3, 'Expected an integer between 1 and 2, but got 3.') ] self.assert_encode_decode_bad(foo, datas)
def test_graphic_string(self): foo = asn1tools.compile_string("Foo DEFINITIONS AUTOMATIC TAGS ::= " "BEGIN " "A ::= GraphicString " "END") datas = [('A', 'f', b'\x19\x01\x66')] for type_name, decoded, encoded in datas: self.assert_encode_decode(foo, type_name, decoded, encoded)
def test_null(self): foo = asn1tools.compile_string("Foo DEFINITIONS AUTOMATIC TAGS ::= " "BEGIN " "A ::= NULL " "END") # Ok. datas = [('A', None)] self.assert_encode_decode_ok(foo, datas)
def test_enumerated(self): foo = asn1tools.compile_string("Foo DEFINITIONS AUTOMATIC TAGS ::= " "BEGIN " "A ::= ENUMERATED { a, b } " "END") # Ok. datas = [('A', 'a')] self.assert_encode_decode_ok(foo, datas)
def test_integer(self): foo = asn1tools.compile_string( "Foo DEFINITIONS AUTOMATIC TAGS ::= " "BEGIN " "A ::= INTEGER " "B ::= INTEGER (5..99) " "C ::= INTEGER (-10..10) " "D ::= INTEGER (5..99, ...) " "E ::= INTEGER (1000..1000) " "F ::= SEQUENCE { " " a INTEGER (4..4), " " b INTEGER (40..40), " " c INTEGER (400..400) " "} " "G ::= B (6..7) " "END") # Ok. datas = [ ('A', 32768), ('A', 0), ('A', -32769), ('B', 5), ('B', 6), ('B', 99), ('C', -10), ('C', 10), ('D', 99), ('E', 1000), ('F', {'a': 4, 'b': 40, 'c': 400}) ] for type_name, decoded in datas: with self.assertRaises(NotImplementedError): foo.check_constraints(type_name, decoded) # Not ok. datas = [ ('B', 4, ': 4 does not fulfill 5..99'), ('B', 100, ': 100 does not fulfill 5..99'), ('C', -11, ': -11 does not fulfill -10..10'), ('C', 11, ': 11 does not fulfill -10..10'), ('D', 100, ': 100 does not fulfill 5..99'), ('E', 0, ': 0 does not fulfill 1000..1000'), ('F', {'a': 4, 'b': 41, 'c': 400}, 'b: 41 does not fulfill 40..40') ] for type_name, decoded, message in datas: with self.assertRaises(NotImplementedError): with self.assertRaises(asn1tools.ConstraintsError) as cm: foo.check_constraints(type_name, decoded) self.assertEqual(str(cm.exception), message)
def test_choice(self): foo = asn1tools.compile_string( "Foo DEFINITIONS AUTOMATIC TAGS ::= " "BEGIN " "A ::= CHOICE { " " a BOOLEAN " "} " "B ::= CHOICE { " " a BOOLEAN, " " ..., " " b BOOLEAN, " " c INTEGER " "} " "C ::= CHOICE { " " a CHOICE { " " a [3] INTEGER" " } " "} " "D ::= CHOICE { " " a [62] BOOLEAN, " " b [APPLICATION 63] BOOLEAN, " " c [PRIVATE 963] BOOLEAN " "} " "END", 'oer') datas = [ ('A', ('a', True), b'\x80\xff'), ('B', ('a', True), b'\x80\xff'), ('B', ('b', True), b'\x81\x01\xff'), ('B', ('c', 0), b'\x82\x02\x01\x00'), ('B', ('c', 1000), b'\x82\x03\x02\x03\xe8'), ('C', ('a', ('a', 150)), b'\x80\x83\x02\x00\x96'), ('D', ('a', False), b'\xbe\x00'), ('D', ('b', False), b'\x7f\x3f\x00'), ('D', ('c', False), b'\xff\x87\x43\x00') ] for type_name, decoded, encoded in datas: self.assert_encode_decode(foo, type_name, decoded, encoded) # Encode bad value. with self.assertRaises(asn1tools.EncodeError) as cm: foo.encode('B', ('foo', None)) self.assertEqual(str(cm.exception), "B: Expected choice 'a', 'b' or 'c', but got 'foo'.") # Decode bad value. with self.assertRaises(asn1tools.DecodeError) as cm: foo.decode('A', b'\x81\x00\xff') self.assertEqual( str(cm.exception), "A: Expected choice member tag '80', but got '81'.")
def test_duplicated_type(self): """Duplicated types are not part of types dictionary. """ spec = asn1tools.compile_string( "Foo DEFINITIONS ::= BEGIN Fum ::= INTEGER END " "Bar DEFINITIONS ::= BEGIN Fum ::= BOOLEAN END " "Fie DEFINITIONS ::= BEGIN Fum ::= REAL END ") self.assertEqual(spec.types, {})
def test_teletex_string(self): foo = asn1tools.compile_string( "Foo DEFINITIONS AUTOMATIC TAGS ::= " "BEGIN " "A ::= TeletexString " "END", 'oer') datas = [('A', u'123', b'\x03\x31\x32\x33')] for type_name, decoded, encoded in datas: self.assert_encode_decode(foo, type_name, decoded, encoded)
def test_boolean(self): foo = asn1tools.compile_string( "Foo DEFINITIONS AUTOMATIC TAGS ::= " "BEGIN " "A ::= BOOLEAN " "END", 'oer') datas = [('A', True, b'\xff'), ('A', False, b'\x00')] for type_name, decoded, encoded in datas: self.assert_encode_decode(foo, type_name, decoded, encoded)