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