1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 """Pure, simple, BER encoding and decoding"""
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 import string
35
36
37
38
39
40
41
42
43
44
45 CLASS_MASK = 0xc0
46 CLASS_UNIVERSAL = 0x00
47 CLASS_APPLICATION = 0x40
48 CLASS_CONTEXT = 0x80
49 CLASS_PRIVATE = 0xc0
50
51 STRUCTURED_MASK = 0x20
52 STRUCTURED = 0x20
53 NOT_STRUCTURED = 0x00
54
55 TAG_MASK = 0x1f
56
57
58
59
60
61
64 Exception.__init__(self)
65 self.tag = tag
66 self.context = context
67
69 return "BERDecoderContext has no tag 0x%02x: %s" \
70 % (self.tag, self.context)
71
72 import UserList
73
75 """
76 Return a tuple of (length, lengthLength).
77 m must be atleast one byte long.
78 """
79 l=ber2int(m[offset+0])
80 ll=1
81 if l&0x80:
82 ll=1+(l&0x7F)
83 need(m, offset+ll)
84 l=ber2int(m[offset+1:offset+ll], signed=0)
85 return (l, ll)
86
88 assert i>=0
89 e=int2ber(i, signed=False)
90 if i <= 127:
91 return e
92 else:
93 l=len(e)
94 assert l>0
95 assert l<=127
96 return chr(0x80|l) + e
97
99 encoded=''
100 while ((signed and (i>127 or i<-128))
101 or (not signed and (i>255))):
102 encoded=chr(i%256)+encoded
103 i=i>>8
104 encoded=chr(i%256)+encoded
105 return encoded
106
108 need(e, 1)
109 v=0L+ord(e[0])
110 if v&0x80 and signed:
111 v=v-256
112 for i in range(1, len(e)):
113 v=(v<<8) | ord(e[i])
114 return v
115
117 tag = None
118
121
125
127 return len(str(self))
128
134
140
146
150
152
154
159
161 tag = 0x02
162 value = None
163
164 - def fromBER(klass, tag, content, berdecoder=None):
169 fromBER = classmethod(fromBER)
170
171 - def __init__(self, value=None, tag=None):
178
184
186 if self.tag==self.__class__.tag:
187 return self.__class__.__name__+"(value=%r)"%self.value
188 else:
189 return self.__class__.__name__+"(value=%r, tag=%d)" \
190 %(self.value, self.tag)
191
193 tag = 0x04
194
195 value = None
196
197 - def fromBER(klass, tag, content, berdecoder=None):
198 assert len(content)>=0
199 r = klass(value=content, tag=tag)
200 return r
201 fromBER = classmethod(fromBER)
202
203 - def __init__(self, value=None, tag=None):
207
213
215 if self.tag==self.__class__.tag:
216 return self.__class__.__name__+"(value=%s)" \
217 %repr(self.value)
218 else:
219 return self.__class__.__name__ \
220 +"(value=%s, tag=%d)" \
221 %(repr(self.value), self.tag)
222
224 tag = 0x05
225
226 - def fromBER(klass, tag, content, berdecoder=None):
227 assert len(content) == 0
228 r = klass(tag=tag)
229 return r
230 fromBER = classmethod(fromBER)
231
234
237
239 if self.tag==self.__class__.tag:
240 return self.__class__.__name__+"()"
241 else:
242 return self.__class__.__name__+"(tag=%d)"%self.tag
243
245 tag = 0x01
246
247 - def fromBER(klass, tag, content, berdecoder=None):
252 fromBER = classmethod(fromBER)
253
254 - def __init__(self, value=None, tag=None):
263
269
271 if self.tag==self.__class__.tag:
272 return self.__class__.__name__+"(value=%d)"%self.value
273 else:
274 return self.__class__.__name__+"(value=%d, tag=%d)" \
275 %(self.value, self.tag)
276
277
280
282
283 tag = 0x10
284
285 - def fromBER(klass, tag, content, berdecoder=None):
289 fromBER = classmethod(fromBER)
290
291 - def __init__(self, value=None, tag=None):
296
300
302 if self.tag==self.__class__.tag:
303 return self.__class__.__name__+"(value=%s)"%repr(self.data)
304 else:
305 return self.__class__.__name__+"(value=%s, tag=%d)" \
306 %(repr(self.data), self.tag)
307
308
311
315
316
317
319 Identities = {
320 BERInteger.tag: BERInteger,
321 BEROctetString.tag: BEROctetString,
322 BERNull.tag: BERNull,
323 BERBoolean.tag: BERBoolean,
324 BEREnumerated.tag: BEREnumerated,
325 BERSequence.tag: BERSequence,
326 BERSet.tag: BERSet,
327 }
328
329 - def __init__(self, fallback=None, inherit=None):
330 self.fallback=fallback
331 self.inherit_context=inherit
332
333 - def lookup_id(self, id):
334 try:
335 return self.Identities[id]
336 except KeyError:
337 if self.fallback:
338 return self.fallback.lookup_id(id)
339 else:
340 return None
341
343 return self.inherit_context or self
344
345 - def __repr__(self):
346 identities = []
347 for tag, class_ in self.Identities.items():
348 identities.append('0x%02x: %s' % (tag, class_.__name__))
349 return "<"+self.__class__.__name__ \
350 +" identities={%s}" % ', '.join(identities) \
351 +" fallback="+repr(self.fallback) \
352 +" inherit="+repr(self.inherit_context) \
353 +">"
354
356 """berDecodeObject(context, string) -> (berobject, bytesUsed)
357 berobject may be None.
358 """
359 while m:
360 need(m, 2)
361 i=ber2int(m[0], signed=0)&(CLASS_MASK|TAG_MASK)
362
363 length, lenlen = berDecodeLength(m, offset=1)
364 need(m, 1+lenlen+length)
365 m2 = m[1+lenlen:1+lenlen+length]
366
367 berclass=context.lookup_id(i)
368 if berclass:
369 inh=context.inherit()
370 assert inh
371 r = berclass.fromBER(tag=i,
372 content=m2,
373 berdecoder=inh)
374 return (r, 1+lenlen+length)
375 else:
376
377 print str(UnknownBERTag(i, context))
378 return (None, 1+lenlen+length)
379 return (None, 0)
380
382 """berDecodeMultiple(content, berdecoder) -> [objects]
383
384 Decodes everything in content and returns a list of decoded
385 objects.
386
387 All of content will be decoded, and content must contain complete
388 BER objects.
389 """
390 l = []
391 while content:
392 n, bytes = berDecodeObject(berdecoder, content)
393 if n is not None:
394 l.append(n)
395 assert bytes <= len(content)
396 content = content[bytes:]
397 return l
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424