import repository from arizona
[raven.git] / lib / ravenlib / files / asn1.py
1 # ASN1 routines
2 # Description: Write various things out in ASN.1 DER format
3 # Author: Scott Baker
4 # Project: Raven, http://raven.cs.arizona.edu/
5
6 class asn1_base:
7     def __init__(self):
8         pass
9
10     def encode(self):
11         return ""
12
13     def hexencode(self):
14         s = self.encode()
15         lst = []
16         for ch in s:\r
17             hv = hex(ord(ch)).replace('0x', '')\r
18             if len(hv) == 1:\r
19                 hv = '0'+hv\r
20             lst.append(hv)\r
21 \r
22         return reduce(lambda x,y:x+y, lst)
23
24     def length_encode(self,x):
25         if len(x)<128:
26             return chr(len(x)) + x
27         elif len(x)<256:
28             return chr(0x81) + chr(len(x)) + x
29         else:
30             return chr(0x82) + chr(len(x)>>8) + chr(len(x) & 0xFF) + x
31
32     def base128_encode(self,v):
33         parts=[]
34         isLsb=True
35         while (v > 0) or (parts==[]):
36             cur = v % 128
37             v = v / 128
38             if isLsb:
39                isLsb=False
40             else:
41                cur = cur + 128
42             parts.append(cur)
43         parts.reverse()
44         result = ""
45         for part in parts:
46             result = result + chr(part)
47         return result
48
49 class asn1_sequence(asn1_base):
50     def __init__(self, children=[]):
51         asn1_base.__init__(self)
52         self.children = children
53
54     def encode(self):
55         result = ""
56         l = 0
57         for child in self.children:
58             child_str = child.encode()
59             l = l + len(child_str)
60             result = result + child_str
61
62         result = chr(0x30) + self.length_encode(result)
63         return result
64
65 class asn1_bigint(asn1_base):
66     def __init__(self, value="00"):
67         asn1_base.__init__(self)
68         self.value = value
69
70     def encode(self):
71         return chr(0x02) + self.length_encode(self.value)
72
73 class asn1_object(asn1_base):
74     def __init__(self, values=[1,2]):
75         asn1_base.__init__(self)
76         self.value = chr(40*values[0] + values[1])
77         for value in values[2:]:
78             self.value = self.value + self.base128_encode(value)
79
80     def encode(self):
81         return chr(0x06) + self.length_encode(self.value)
82
83 class asn1_dsa_object(asn1_object):
84     def __init__(self):
85         asn1_object.__init__(self, [1, 2, 840, 10040, 4, 1])
86
87 class asn1_rsa_object(asn1_object):
88     def __init__(self):
89         asn1_object.__init__(self, [1, 2, 840, 113549, 1, 1, 1])
90
91 class asn1_bitstring(asn1_base):
92     def __init__(self, value=""):
93         asn1_base.__init__(self)
94         self.value = value
95
96     def encode(self):
97         return chr(0x03) + self.length_encode(chr(0) + self.value)
98
99 class asn1_null(asn1_base):
100     def __init__(self):
101         asn1_base.__init__(self)
102
103     def encode(self):
104         return chr(05) + chr(00)
105
106 class dsa_pubkey(asn1_sequence):
107     def __init__(self, p, q, g, pk):
108         asn1_sequence.__init__(self,
109                                [asn1_sequence([asn1_dsa_object(),
110                                                asn1_sequence([asn1_bigint(p),
111                                                               asn1_bigint(q),
112                                                               asn1_bigint(g)])]),
113                                 asn1_bitstring(asn1_bigint(pk).encode())])
114
115 class rsa_pubkey(asn1_sequence):
116     def __init__(self, n,e):
117         asn1_sequence.__init__(self,
118                                [asn1_sequence([asn1_rsa_object(),
119                                                asn1_null()]),
120                                 asn1_bitstring(asn1_sequence([asn1_bigint(n),asn1_bigint(e)]).encode()) ])
121
122