1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 __all__ = [
23 'asn1_build',
24 'asn1_parse',
25 'ASN1FormatError',
26 'BIT_STRING',
27 'INTEGER',
28 'SEQUENCE',
29 'OBJECT_IDENTIFIER',
30 'OCTET_STRING',
31 'NULL',
32 ]
33
34 INTEGER = 0x02
35 BIT_STRING = 0x03
36 OCTET_STRING = 0x04
37 NULL = 0x05
38 OBJECT_IDENTIFIER = 0x06
39 SEQUENCE = 0x30
40
41
44
45
47 """Parse a data structure according to an ASN.1 template.
48
49 @param template: tuples comprising the ASN.1 template
50 @param data: byte string data to parse
51 @return: decoded structure
52 """
53 data = bytearray(data)
54 r = []
55 i = 0
56 try:
57 for t in template:
58 tag = data[i]
59 i += 1
60 if tag == t[0]:
61 length = data[i]
62 i += 1
63 if length & 0x80:
64 n = length & 0x7f
65 length = 0
66 for j in range(n):
67 length = (length << 8) | data[i]
68 i += 1
69 if tag == INTEGER:
70 n = 0
71 for j in range(length):
72 n = (n << 8) | data[i]
73 i += 1
74 r.append(n)
75 elif tag == BIT_STRING:
76 r.append(data[i:i+length])
77 i += length
78 elif tag == NULL:
79 assert length == 0
80 r.append(None)
81 elif tag == OBJECT_IDENTIFIER:
82 r.append(data[i:i+length])
83 i += length
84 elif tag == SEQUENCE:
85 r.append(asn1_parse(t[1], data[i:i+length]))
86 i += length
87 else:
88 raise ASN1FormatError(
89 "Unexpected tag in template: %02x" % tag)
90 else:
91 raise ASN1FormatError(
92 "Unexpected tag (got %02x, expecting %02x)" % (tag, t[0]))
93 return r
94 except IndexError:
95 raise ASN1FormatError("Data truncated at byte %d"%i)
96
98 """Return a string representing a field length in ASN.1 format.
99
100 @param n: integer field length
101 @return: ASN.1 field length
102 """
103 assert n >= 0
104 if n < 0x7f:
105 return bytearray([n])
106 r = bytearray()
107 while n > 0:
108 r.insert(n & 0xff)
109 n >>= 8
110 return r
111
112
114 length = asn1_length(len(data))
115 length.insert(0, type)
116 length.extend(data)
117 return length
118
119
140