Switch global error menu icon to vectorized MD asset
[chromium-blink-merge.git] / net / tools / testserver / asn1.py
blobc0e0398626c0869a4f796825ef5c0a3c61e08ba7
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.
5 # This file implements very minimal ASN.1, DER serialization.
7 import types
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
30 if len(big_endian) == 0 or big_endian[-1] >= 128:
31 big_endian.append(0)
33 big_endian.reverse()
34 return TagAndLength(2, len(big_endian)) + ToBytes(big_endian)
36 return obj.ToDER()
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])
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
58 return ToBytes(der)
61 class Raw(object):
62 '''Raw contains raw DER encoded bytes that are used verbatim'''
63 def __init__(self, der):
64 self.der = der
66 def ToDER(self):
67 return self.der
70 class Explicit(object):
71 '''Explicit prepends an explicit tag'''
72 def __init__(self, tag, child):
73 self.tag = tag
74 self.child = child
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
84 class ENUMERATED(object):
85 def __init__(self, value):
86 self.value = value
88 def ToDER(self):
89 return TagAndLength(10, 1) + chr(self.value)
92 class SEQUENCE(object):
93 def __init__(self, children):
94 self.children = children
96 def ToDER(self):
97 der = ''.join([ToDER(x) for x in self.children])
98 return TagAndLength(0x30, len(der)) + der
101 class SET(object):
102 def __init__(self, children):
103 self.children = children
105 def ToDER(self):
106 der = ''.join([ToDER(x) for x in self.children])
107 return TagAndLength(0x31, len(der)) + der
110 class OCTETSTRING(object):
111 def __init__(self, val):
112 self.val = val
114 def ToDER(self):
115 return TagAndLength(4, len(self.val)) + self.val
118 class OID(object):
119 def __init__(self, parts):
120 self.parts = parts
122 def ToDER(self):
123 if len(self.parts) < 2 or self.parts[0] > 6 or self.parts[1] >= 40:
124 assert False
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
141 return TagAndLength(6, len(der)) + ToBytes(der)
144 class UTCTime(object):
145 def __init__(self, time_str):
146 self.time_str = time_str
148 def ToDER(self):
149 return TagAndLength(23, len(self.time_str)) + self.time_str
152 class GeneralizedTime(object):
153 def __init__(self, time_str):
154 self.time_str = time_str
156 def ToDER(self):
157 return TagAndLength(24, len(self.time_str)) + self.time_str
160 class BitString(object):
161 def __init__(self, bits):
162 self.bits = bits
164 def ToDER(self):
165 return TagAndLength(3, 1 + len(self.bits)) + "\x00" + self.bits