OLD | NEW |
| (Empty) |
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 # Use of this source code is governed by a BSD-style license that can be | |
3 # found in the LICENSE file. | |
4 | |
5 # This file implements very minimal ASN.1, DER serialization. | |
6 | |
7 import types | |
8 | |
9 | |
10 def ToDER(obj): | |
11 '''ToDER converts the given object into DER encoding''' | |
12 if type(obj) == types.NoneType: | |
13 # None turns into NULL | |
14 return TagAndLength(5, 0) | |
15 if type(obj) == types.StringType: | |
16 # Strings are PRINTABLESTRING | |
17 return TagAndLength(19, len(obj)) + obj | |
18 if type(obj) == types.BooleanType: | |
19 val = "\x00" | |
20 if obj: | |
21 val = "\xff" | |
22 return TagAndLength(1, 1) + val | |
23 if type(obj) == types.IntType or type(obj) == types.LongType: | |
24 big_endian = [] | |
25 val = obj | |
26 while val != 0: | |
27 big_endian.append(val & 0xff) | |
28 val >>= 8 | |
29 | |
30 if len(big_endian) == 0 or big_endian[-1] >= 128: | |
31 big_endian.append(0) | |
32 | |
33 big_endian.reverse() | |
34 return TagAndLength(2, len(big_endian)) + ToBytes(big_endian) | |
35 | |
36 return obj.ToDER() | |
37 | |
38 | |
39 def ToBytes(array_of_bytes): | |
40 '''ToBytes converts the array of byte values into a binary string''' | |
41 return ''.join([chr(x) for x in array_of_bytes]) | |
42 | |
43 | |
44 def TagAndLength(tag, length): | |
45 der = [tag] | |
46 if length < 128: | |
47 der.append(length) | |
48 elif length < 256: | |
49 der.append(0x81) | |
50 der.append(length) | |
51 elif length < 65535: | |
52 der.append(0x82) | |
53 der.append(length >> 8) | |
54 der.append(length & 0xff) | |
55 else: | |
56 assert False | |
57 | |
58 return ToBytes(der) | |
59 | |
60 | |
61 class Raw(object): | |
62 '''Raw contains raw DER encoded bytes that are used verbatim''' | |
63 def __init__(self, der): | |
64 self.der = der | |
65 | |
66 def ToDER(self): | |
67 return self.der | |
68 | |
69 | |
70 class Explicit(object): | |
71 '''Explicit prepends an explicit tag''' | |
72 def __init__(self, tag, child): | |
73 self.tag = tag | |
74 self.child = child | |
75 | |
76 def ToDER(self): | |
77 der = ToDER(self.child) | |
78 tag = self.tag | |
79 tag |= 0x80 # content specific | |
80 tag |= 0x20 # complex | |
81 return TagAndLength(tag, len(der)) + der | |
82 | |
83 | |
84 class ENUMERATED(object): | |
85 def __init__(self, value): | |
86 self.value = value | |
87 | |
88 def ToDER(self): | |
89 return TagAndLength(10, 1) + chr(self.value) | |
90 | |
91 | |
92 class SEQUENCE(object): | |
93 def __init__(self, children): | |
94 self.children = children | |
95 | |
96 def ToDER(self): | |
97 der = ''.join([ToDER(x) for x in self.children]) | |
98 return TagAndLength(0x30, len(der)) + der | |
99 | |
100 | |
101 class SET(object): | |
102 def __init__(self, children): | |
103 self.children = children | |
104 | |
105 def ToDER(self): | |
106 der = ''.join([ToDER(x) for x in self.children]) | |
107 return TagAndLength(0x31, len(der)) + der | |
108 | |
109 | |
110 class OCTETSTRING(object): | |
111 def __init__(self, val): | |
112 self.val = val | |
113 | |
114 def ToDER(self): | |
115 return TagAndLength(4, len(self.val)) + self.val | |
116 | |
117 | |
118 class OID(object): | |
119 def __init__(self, parts): | |
120 self.parts = parts | |
121 | |
122 def ToDER(self): | |
123 if len(self.parts) < 2 or self.parts[0] > 6 or self.parts[1] >= 40: | |
124 assert False | |
125 | |
126 der = [self.parts[0]*40 + self.parts[1]] | |
127 for x in self.parts[2:]: | |
128 if x == 0: | |
129 der.append(0) | |
130 else: | |
131 octets = [] | |
132 while x != 0: | |
133 v = x & 0x7f | |
134 if len(octets) > 0: | |
135 v |= 0x80 | |
136 octets.append(v) | |
137 x >>= 7 | |
138 octets.reverse() | |
139 der = der + octets | |
140 | |
141 return TagAndLength(6, len(der)) + ToBytes(der) | |
142 | |
143 | |
144 class UTCTime(object): | |
145 def __init__(self, time_str): | |
146 self.time_str = time_str | |
147 | |
148 def ToDER(self): | |
149 return TagAndLength(23, len(self.time_str)) + self.time_str | |
150 | |
151 | |
152 class GeneralizedTime(object): | |
153 def __init__(self, time_str): | |
154 self.time_str = time_str | |
155 | |
156 def ToDER(self): | |
157 return TagAndLength(24, len(self.time_str)) + self.time_str | |
158 | |
159 | |
160 class BitString(object): | |
161 def __init__(self, bits): | |
162 self.bits = bits | |
163 | |
164 def ToDER(self): | |
165 return TagAndLength(3, 1 + len(self.bits)) + "\x00" + self.bits | |
OLD | NEW |