1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 from paramiko.common import max_byte, zero_byte
19 from paramiko.py3compat import b, byte_ord, byte_chr, long
20
21 import paramiko.util as util
22
23
26
27
29 """
30 Robey's tiny little attempt at a BER decoder.
31 """
32
34 self.content = b(content)
35 self.idx = 0
36
39
42
44 return 'BER(\'' + repr(self.content) + '\')'
45
48
50 if self.idx >= len(self.content):
51 return None
52 ident = byte_ord(self.content[self.idx])
53 self.idx += 1
54 if (ident & 31) == 31:
55
56 ident = 0
57 while self.idx < len(self.content):
58 t = byte_ord(self.content[self.idx])
59 self.idx += 1
60 ident = (ident << 7) | (t & 0x7f)
61 if not (t & 0x80):
62 break
63 if self.idx >= len(self.content):
64 return None
65
66 size = byte_ord(self.content[self.idx])
67 self.idx += 1
68 if size & 0x80:
69
70
71 t = size & 0x7f
72 if self.idx + t > len(self.content):
73 return None
74 size = util.inflate_long(self.content[self.idx: self.idx + t], True)
75 self.idx += t
76 if self.idx + size > len(self.content):
77
78 return None
79 data = self.content[self.idx: self.idx + size]
80 self.idx += size
81
82 if ident == 0x30:
83
84 return self.decode_sequence(data)
85 elif ident == 2:
86
87 return util.inflate_long(data)
88 else:
89
90 raise BERException('Unknown ber encoding type %d (robey is lazy)' % ident)
91
93 out = []
94 ber = BER(data)
95 while True:
96 x = ber.decode_next()
97 if x is None:
98 break
99 out.append(x)
100 return out
101 decode_sequence = staticmethod(decode_sequence)
102
104
105 self.content += byte_chr(ident)
106 if len(val) > 0x7f:
107 lenstr = util.deflate_long(len(val))
108 self.content += byte_chr(0x80 + len(lenstr)) + lenstr
109 else:
110 self.content += byte_chr(len(val))
111 self.content += val
112
127
133 encode_sequence = staticmethod(encode_sequence)
134