OLD | NEW |
| (Empty) |
1 # Copyright (c) 2001-2004 Twisted Matrix Laboratories. | |
2 # See LICENSE for details. | |
3 | |
4 # | |
5 | |
6 """ | |
7 A basic ASN.1 parser to parse private SSH keys. | |
8 | |
9 Maintainer: U{Paul Swartz<mailto:z3p@twistedmatrix.com>} | |
10 """ | |
11 | |
12 from Crypto.Util import number | |
13 | |
14 def parse(data): | |
15 things = [] | |
16 while data: | |
17 t = ord(data[0]) | |
18 assert (t & 0xc0) == 0, 'not a universal value: 0x%02x' % t | |
19 #assert t & 0x20, 'not a constructed value: 0x%02x' % t | |
20 l = ord(data[1]) | |
21 assert data != 0x80, "shouldn't be an indefinite length" | |
22 if l & 0x80: # long form | |
23 ll = l & 0x7f | |
24 l = number.bytes_to_long(data[2:2+ll]) | |
25 s = 2 + ll | |
26 else: | |
27 s = 2 | |
28 body, data = data[s:s+l], data[s+l:] | |
29 t = t&(~0x20) | |
30 assert t in (SEQUENCE, INTEGER), 'bad type: 0x%02x' % t | |
31 if t == SEQUENCE: | |
32 things.append(parse(body)) | |
33 elif t == INTEGER: | |
34 #assert (ord(body[0])&0x80) == 0, "shouldn't have negative number" | |
35 things.append(number.bytes_to_long(body)) | |
36 if len(things) == 1: | |
37 return things[0] | |
38 return things | |
39 | |
40 def pack(data): | |
41 ret = '' | |
42 for part in data: | |
43 if type(part) in (type(()), type([])): | |
44 partData = pack(part) | |
45 partType = SEQUENCE|0x20 | |
46 elif type(part) in (type(1), type(1L)): | |
47 partData = number.long_to_bytes(part) | |
48 if ord(partData[0])&(0x80): | |
49 partData = '\x00' + partData | |
50 partType = INTEGER | |
51 else: | |
52 raise ValueError('unknown type %s' % (type(part),)) | |
53 | |
54 ret += chr(partType) | |
55 if len(partData) > 127: | |
56 l = number.long_to_bytes(len(partData)) | |
57 ret += chr(len(l)|0x80) + l | |
58 else: | |
59 ret += chr(len(partData)) | |
60 ret += partData | |
61 return ret | |
62 | |
63 INTEGER = 0x02 | |
64 SEQUENCE = 0x10 | |
65 | |
OLD | NEW |