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.
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:
22 return TagAndLength(1, 1) + val
23 if type(obj) == types.IntType or type(obj) == types.LongType:
27 big_endian.append(val & 0xff)
30 if len(big_endian) == 0 or big_endian[-1] >= 128:
34 return TagAndLength(2, len(big_endian)) + ToBytes(big_endian)
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):
53 der.append(length >> 8)
54 der.append(length & 0xff)
62 '''Raw contains raw DER encoded bytes that are used verbatim'''
63 def __init__(self, der):
70 class Explicit(object):
71 '''Explicit prepends an explicit tag'''
72 def __init__(self, tag, child):
77 der = ToDER(self.child)
79 tag |= 0x80 # content specific
81 return TagAndLength(tag, len(der)) + der
84 class ENUMERATED(object):
85 def __init__(self, value):
89 return TagAndLength(10, 1) + chr(self.value)
92 class SEQUENCE(object):
93 def __init__(self, children):
94 self.children = children
97 der = ''.join([ToDER(x) for x in self.children])
98 return TagAndLength(0x30, len(der)) + der
102 def __init__(self, children):
103 self.children = children
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):
115 return TagAndLength(4, len(self.val)) + self.val
119 def __init__(self, parts):
123 if len(self.parts) < 2 or self.parts[0] > 6 or self.parts[1] >= 40:
126 der = [self.parts[0]*40 + self.parts[1]]
127 for x in self.parts[2:]:
141 return TagAndLength(6, len(der)) + ToBytes(der)
144 class UTCTime(object):
145 def __init__(self, time_str):
146 self.time_str = time_str
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
157 return TagAndLength(24, len(self.time_str)) + self.time_str
160 class BitString(object):
161 def __init__(self, bits):
165 return TagAndLength(3, 1 + len(self.bits)) + "\x00" + self.bits