Index: net/tools/testserver/asn1.py |
diff --git a/net/tools/testserver/asn1.py b/net/tools/testserver/asn1.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6bff256f159d1be5112bdc35cfaf0fa83f82621d |
--- /dev/null |
+++ b/net/tools/testserver/asn1.py |
@@ -0,0 +1,164 @@ |
+# Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+# This file implements very minimal ASN.1, DER serialization. |
+ |
+import types |
+ |
+ |
+def ToDER(obj): |
+ '''ToDER converts the given object into DER encoding''' |
+ if type(obj) == types.NoneType: |
+ # None turns into NULL |
+ return TagAndLength(5, 0) |
+ if type(obj) == types.StringType: |
+ # Strings are PRINTABLESTRING |
+ return TagAndLength(19, len(obj)) + obj |
+ if type(obj) == types.BooleanType: |
+ val = "\x00" |
+ if obj: |
+ val = "\xff" |
+ return TagAndLength(1, 1) + val |
+ if type(obj) == types.IntType or type(obj) == types.LongType: |
+ big_endian = [] |
+ val = obj |
+ while val != 0: |
+ big_endian.append(val & 0xff) |
+ val >>= 8 |
+ |
+ if len(big_endian) == 0 or big_endian[-1] >= 128: |
+ big_endian.append(0) |
+ |
+ big_endian.reverse() |
+ return TagAndLength(2, len(big_endian)) + ToBytes(big_endian) |
+ |
+ return obj.ToDER() |
+ |
+ |
+def ToBytes(array_of_bytes): |
+ '''ToBytes converts the array of byte values into a binary string''' |
+ return ''.join([chr(x) for x in array_of_bytes]) |
+ |
+def TagAndLength(tag, length): |
+ der = [tag] |
+ if length < 128: |
+ der.append(length) |
+ elif length < 256: |
+ der.append(0x81) |
+ der.append(length) |
+ elif length < 65535: |
+ der.append(0x82) |
+ der.append(length >> 8) |
+ der.append(length & 0xff) |
+ else: |
+ assert False |
+ |
+ return ToBytes(der) |
+ |
+ |
+class Raw(object): |
+ '''Raw contains raw DER encoded bytes that are used verbatim''' |
+ def __init__(self, der): |
+ self.der = der |
+ |
+ def ToDER(self): |
+ return self.der |
+ |
+ |
+class Explicit(object): |
+ '''Explicit prepends an explicit tag''' |
+ def __init__(self, tag, child): |
+ self.tag = tag |
+ self.child = child |
+ |
+ def ToDER(self): |
+ der = ToDER(self.child) |
+ tag = self.tag |
+ tag |= 0x80 # content specific |
+ tag |= 0x20 # complex |
+ return TagAndLength(tag, len(der)) + der |
+ |
+ |
+class ENUMERATED(object): |
+ def __init__(self, value): |
+ self.value = value |
+ |
+ def ToDER(self): |
+ return TagAndLength(10, 1) + chr(self.value) |
+ |
+ |
+class SEQUENCE(object): |
+ def __init__(self, children): |
+ self.children = children |
+ |
+ def ToDER(self): |
+ der = ''.join([ToDER(x) for x in self.children]) |
+ return TagAndLength(0x30, len(der)) + der |
+ |
+ |
+class SET(object): |
+ def __init__(self, children): |
+ self.children = children |
+ |
+ def ToDER(self): |
+ der = ''.join([ToDER(x) for x in self.children]) |
+ return TagAndLength(0x31, len(der)) + der |
+ |
+ |
+class OCTETSTRING(object): |
+ def __init__(self, val): |
+ self.val = val |
+ |
+ def ToDER(self): |
+ return TagAndLength(4, len(self.val)) + self.val |
+ |
+ |
+class OID(object): |
+ def __init__(self, parts): |
+ self.parts = parts |
+ |
+ def ToDER(self): |
+ if len(self.parts) < 2 or self.parts[0] > 6 or self.parts[1] >= 40: |
+ assert False |
+ |
+ der = [self.parts[0]*40 + self.parts[1]] |
+ for x in self.parts[2:]: |
+ if x == 0: |
+ der.append(0) |
+ else: |
+ octets = [] |
+ while x != 0: |
+ v = x & 0x7f |
+ if len(octets) > 0: |
+ v |= 0x80 |
+ octets.append(v) |
+ x >>= 7 |
+ octets.reverse() |
+ der = der + octets |
+ |
+ return TagAndLength(6, len(der)) + ToBytes(der) |
+ |
+ |
+class UTCTime(object): |
+ def __init__(self, time_str): |
+ self.time_str = time_str |
+ |
+ def ToDER(self): |
+ return TagAndLength(23, len(self.time_str)) + self.time_str |
+ |
+ |
+class GeneralizedTime(object): |
+ def __init__(self, time_str): |
+ self.time_str = time_str |
+ |
+ def ToDER(self): |
+ return TagAndLength(24, len(self.time_str)) + self.time_str |
+ |
+ |
+class BitString(object): |
+ def __init__(self, bits): |
+ self.bits = bits |
+ |
+ def ToDER(self): |
+ return TagAndLength(3, 1 + len(self.bits)) + "\x00" + self.bits |