1
|
|
|
# BER decoder |
2
|
|
|
from pyasn1.type import tag, base, univ, char, useful, tagmap |
3
|
|
|
from pyasn1.codec.ber import eoo |
4
|
|
|
from pyasn1.compat.octets import oct2int, octs2ints |
5
|
|
|
from pyasn1 import error |
6
|
|
|
|
7
|
|
|
class AbstractDecoder: |
8
|
|
|
protoComponent = None |
9
|
|
|
def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, |
10
|
|
|
length, state, decodeFun): |
11
|
|
|
raise error.PyAsn1Error('Decoder not implemented for %s' % tagSet) |
12
|
|
|
|
13
|
|
|
def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, |
14
|
|
|
length, state, decodeFun): |
15
|
|
|
raise error.PyAsn1Error('Indefinite length mode decoder not implemented for %s' % tagSet) |
16
|
|
|
|
17
|
|
|
class AbstractSimpleDecoder(AbstractDecoder): |
18
|
|
|
def _createComponent(self, asn1Spec, tagSet, value=None): |
19
|
|
|
if asn1Spec is None: |
20
|
|
|
return self.protoComponent.clone(value, tagSet) |
21
|
|
|
elif value is None: |
22
|
|
|
return asn1Spec |
23
|
|
|
else: |
24
|
|
|
return asn1Spec.clone(value) |
25
|
|
|
|
26
|
|
|
class AbstractConstructedDecoder(AbstractDecoder): |
27
|
|
|
def _createComponent(self, asn1Spec, tagSet, value=None): |
28
|
|
|
if asn1Spec is None: |
29
|
|
|
return self.protoComponent.clone(tagSet) |
30
|
|
|
else: |
31
|
|
|
return asn1Spec.clone() |
32
|
|
|
|
33
|
|
|
class EndOfOctetsDecoder(AbstractSimpleDecoder): |
34
|
|
|
def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, |
35
|
|
|
length, state, decodeFun): |
36
|
|
|
return eoo.endOfOctets, substrate[:length] |
37
|
|
|
|
38
|
|
|
class ExplicitTagDecoder(AbstractSimpleDecoder): |
39
|
|
|
def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, |
40
|
|
|
length, state, decodeFun): |
41
|
|
|
return decodeFun(substrate[:length], asn1Spec, tagSet, length) |
42
|
|
|
|
43
|
|
|
def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, |
44
|
|
|
length, state, decodeFun): |
45
|
|
|
value, substrate = decodeFun(substrate, asn1Spec, tagSet, length) |
46
|
|
|
terminator, substrate = decodeFun(substrate) |
47
|
|
|
if terminator == eoo.endOfOctets: |
48
|
|
|
return value, substrate |
49
|
|
|
else: |
50
|
|
|
raise error.PyAsn1Error('Missing end-of-octets terminator') |
51
|
|
|
|
52
|
|
|
explicitTagDecoder = ExplicitTagDecoder() |
53
|
|
|
|
54
|
|
|
class IntegerDecoder(AbstractSimpleDecoder): |
55
|
|
|
protoComponent = univ.Integer(0) |
56
|
|
|
precomputedValues = { |
57
|
|
|
'\x00': 0, |
58
|
|
|
'\x01': 1, |
59
|
|
|
'\x02': 2, |
60
|
|
|
'\x03': 3, |
61
|
|
|
'\x04': 4, |
62
|
|
|
'\x05': 5, |
63
|
|
|
'\x06': 6, |
64
|
|
|
'\x07': 7, |
65
|
|
|
'\x08': 8, |
66
|
|
|
'\x09': 9, |
67
|
|
|
'\xff': -1, |
68
|
|
|
'\xfe': -2, |
69
|
|
|
'\xfd': -3, |
70
|
|
|
'\xfc': -4, |
71
|
|
|
'\xfb': -5 |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
def _valueFilter(self, value): |
75
|
|
|
try: |
76
|
|
|
return int(value) |
77
|
|
|
except OverflowError: |
78
|
|
|
return value |
79
|
|
|
|
80
|
|
|
def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length, |
81
|
|
|
state, decodeFun): |
82
|
|
|
substrate = substrate[:length] |
83
|
|
|
if not substrate: |
84
|
|
|
raise error.PyAsn1Error('Empty substrate') |
85
|
|
|
if substrate in self.precomputedValues: |
86
|
|
|
value = self.precomputedValues[substrate] |
87
|
|
|
else: |
88
|
|
|
firstOctet = oct2int(substrate[0]) |
89
|
|
|
if firstOctet & 0x80: |
90
|
|
|
value = -1 |
91
|
|
|
else: |
92
|
|
|
value = 0 |
93
|
|
|
for octet in substrate: |
94
|
|
|
value = value << 8 | oct2int(octet) |
95
|
|
|
value = self._valueFilter(value) |
96
|
|
|
return self._createComponent(asn1Spec, tagSet, value), substrate |
97
|
|
|
|
98
|
|
|
class BooleanDecoder(IntegerDecoder): |
99
|
|
|
protoComponent = univ.Boolean(0) |
100
|
|
|
def _valueFilter(self, value): |
101
|
|
|
if value: |
102
|
|
|
return 1 |
103
|
|
|
else: |
104
|
|
|
return 0 |
105
|
|
|
|
106
|
|
|
class BitStringDecoder(AbstractSimpleDecoder): |
107
|
|
|
protoComponent = univ.BitString(()) |
108
|
|
|
def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length, |
109
|
|
|
state, decodeFun): |
110
|
|
|
substrate = substrate[:length] |
111
|
|
|
if tagSet[0][1] == tag.tagFormatSimple: # XXX what tag to check? |
112
|
|
|
if not substrate: |
113
|
|
|
raise error.PyAsn1Error('Missing initial octet') |
114
|
|
|
trailingBits = oct2int(substrate[0]) |
115
|
|
|
if trailingBits > 7: |
116
|
|
|
raise error.PyAsn1Error( |
117
|
|
|
'Trailing bits overflow %s' % trailingBits |
118
|
|
|
) |
119
|
|
|
substrate = substrate[1:] |
120
|
|
|
lsb = p = 0; l = len(substrate)-1; b = () |
121
|
|
|
while p <= l: |
122
|
|
|
if p == l: |
123
|
|
|
lsb = trailingBits |
124
|
|
|
j = 7 |
125
|
|
|
o = oct2int(substrate[p]) |
126
|
|
|
while j >= lsb: |
127
|
|
|
b = b + ((o>>j)&0x01,) |
128
|
|
|
j = j - 1 |
129
|
|
|
p = p + 1 |
130
|
|
|
return self._createComponent(asn1Spec, tagSet, b), '' |
131
|
|
|
r = self._createComponent(asn1Spec, tagSet, ()) |
132
|
|
|
if not decodeFun: |
133
|
|
|
return r, substrate |
134
|
|
|
while substrate: |
135
|
|
|
component, substrate = decodeFun(substrate) |
136
|
|
|
r = r + component |
137
|
|
|
return r, substrate |
138
|
|
|
|
139
|
|
View Code Duplication |
def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, |
|
|
|
|
140
|
|
|
length, state, decodeFun): |
141
|
|
|
r = self._createComponent(asn1Spec, tagSet, '') |
142
|
|
|
if not decodeFun: |
143
|
|
|
return r, substrate |
144
|
|
|
while substrate: |
145
|
|
|
component, substrate = decodeFun(substrate) |
146
|
|
|
if component == eoo.endOfOctets: |
147
|
|
|
break |
148
|
|
|
r = r + component |
149
|
|
|
else: |
150
|
|
|
raise error.SubstrateUnderrunError( |
151
|
|
|
'No EOO seen before substrate ends' |
152
|
|
|
) |
153
|
|
|
return r, substrate |
154
|
|
|
|
155
|
|
|
class OctetStringDecoder(AbstractSimpleDecoder): |
156
|
|
|
protoComponent = univ.OctetString('') |
157
|
|
|
def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length, |
158
|
|
|
state, decodeFun): |
159
|
|
|
substrate = substrate[:length] |
160
|
|
|
if tagSet[0][1] == tag.tagFormatSimple: # XXX what tag to check? |
161
|
|
|
return self._createComponent(asn1Spec, tagSet, substrate), '' |
162
|
|
|
r = self._createComponent(asn1Spec, tagSet, '') |
163
|
|
|
if not decodeFun: |
164
|
|
|
return r, substrate |
165
|
|
|
while substrate: |
166
|
|
|
component, substrate = decodeFun(substrate) |
167
|
|
|
r = r + component |
168
|
|
|
return r, substrate |
169
|
|
|
|
170
|
|
View Code Duplication |
def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, |
|
|
|
|
171
|
|
|
length, state, decodeFun): |
172
|
|
|
r = self._createComponent(asn1Spec, tagSet, '') |
173
|
|
|
if not decodeFun: |
174
|
|
|
return r, substrate |
175
|
|
|
while substrate: |
176
|
|
|
component, substrate = decodeFun(substrate) |
177
|
|
|
if component == eoo.endOfOctets: |
178
|
|
|
break |
179
|
|
|
r = r + component |
180
|
|
|
else: |
181
|
|
|
raise error.SubstrateUnderrunError( |
182
|
|
|
'No EOO seen before substrate ends' |
183
|
|
|
) |
184
|
|
|
return r, substrate |
185
|
|
|
|
186
|
|
|
class NullDecoder(AbstractSimpleDecoder): |
187
|
|
|
protoComponent = univ.Null('') |
188
|
|
|
def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, |
189
|
|
|
length, state, decodeFun): |
190
|
|
|
substrate = substrate[:length] |
191
|
|
|
r = self._createComponent(asn1Spec, tagSet) |
192
|
|
|
if substrate: |
193
|
|
|
raise error.PyAsn1Error('Unexpected substrate for Null') |
194
|
|
|
return r, substrate |
195
|
|
|
|
196
|
|
|
class ObjectIdentifierDecoder(AbstractSimpleDecoder): |
197
|
|
|
protoComponent = univ.ObjectIdentifier(()) |
198
|
|
|
def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length, |
199
|
|
|
state, decodeFun): |
200
|
|
|
substrate = substrate[:length] |
201
|
|
|
if not substrate: |
202
|
|
|
raise error.PyAsn1Error('Empty substrate') |
203
|
|
|
oid = (); index = 0 |
204
|
|
|
# Get the first subid |
205
|
|
|
subId = oct2int(substrate[index]) |
206
|
|
|
oid = oid + divmod(subId, 40) |
207
|
|
|
|
208
|
|
|
index = index + 1 |
209
|
|
|
substrateLen = len(substrate) |
210
|
|
|
|
211
|
|
|
while index < substrateLen: |
212
|
|
|
subId = oct2int(substrate[index]) |
213
|
|
|
if subId < 128: |
214
|
|
|
oid = oid + (subId,) |
215
|
|
|
index = index + 1 |
216
|
|
|
else: |
217
|
|
|
# Construct subid from a number of octets |
218
|
|
|
nextSubId = subId |
219
|
|
|
subId = 0 |
220
|
|
|
while nextSubId >= 128 and index < substrateLen: |
221
|
|
|
subId = (subId << 7) + (nextSubId & 0x7F) |
222
|
|
|
index = index + 1 |
223
|
|
|
nextSubId = oct2int(substrate[index]) |
224
|
|
|
if index == substrateLen: |
225
|
|
|
raise error.SubstrateUnderrunError( |
226
|
|
|
'Short substrate for OID %s' % oid |
227
|
|
|
) |
228
|
|
|
subId = (subId << 7) + nextSubId |
229
|
|
|
oid = oid + (subId,) |
230
|
|
|
index = index + 1 |
231
|
|
|
return self._createComponent(asn1Spec, tagSet, oid), substrate[index:] |
232
|
|
|
|
233
|
|
|
class RealDecoder(AbstractSimpleDecoder): |
234
|
|
|
protoComponent = univ.Real() |
235
|
|
|
def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, |
236
|
|
|
length, state, decodeFun): |
237
|
|
|
substrate = substrate[:length] |
238
|
|
|
if not length: |
239
|
|
|
raise error.SubstrateUnderrunError('Short substrate for Real') |
240
|
|
|
fo = oct2int(substrate[0]); substrate = substrate[1:] |
241
|
|
|
if fo & 0x40: # infinite value |
242
|
|
|
value = fo & 0x01 and '-inf' or 'inf' |
243
|
|
|
elif fo & 0x80: # binary enoding |
244
|
|
|
if fo & 0x11 == 0: |
245
|
|
|
n = 1 |
246
|
|
|
elif fo & 0x01: |
247
|
|
|
n = 2 |
248
|
|
|
elif fo & 0x02: |
249
|
|
|
n = 3 |
250
|
|
|
else: |
251
|
|
|
n = oct2int(substrate[0]) |
252
|
|
|
eo, substrate = substrate[:n], substrate[n:] |
253
|
|
|
if not eo or not substrate: |
254
|
|
|
raise error.PyAsn1Error('Real exponent screwed') |
255
|
|
|
e = 0 |
256
|
|
|
while eo: # exponent |
257
|
|
|
e <<= 8 |
258
|
|
|
e |= oct2int(eo[0]) |
259
|
|
|
eo = eo[1:] |
260
|
|
|
p = 0 |
261
|
|
|
while substrate: # value |
262
|
|
|
p <<= 8 |
263
|
|
|
p |= oct2int(substrate[0]) |
264
|
|
|
substrate = substrate[1:] |
265
|
|
|
if fo & 0x40: # sign bit |
266
|
|
|
p = -p |
267
|
|
|
value = (p, 2, e) |
268
|
|
|
elif fo & 0xc0 == 0: # character encoding |
269
|
|
|
try: |
270
|
|
|
if fo & 0x3 == 0x1: # NR1 |
271
|
|
|
value = (int(substrate), 10, 0) |
272
|
|
|
elif fo & 0x3 == 0x2: # NR2 |
273
|
|
|
value = float(substrate) |
274
|
|
|
elif fo & 0x3 == 0x3: # NR3 |
275
|
|
|
value = float(substrate) |
276
|
|
|
else: |
277
|
|
|
raise error.SubstrateUnderrunError( |
278
|
|
|
'Unknown NR (tag %s)' % fo |
279
|
|
|
) |
280
|
|
|
except ValueError: |
281
|
|
|
raise error.SubstrateUnderrunError( |
282
|
|
|
'Bad character Real syntax' |
283
|
|
|
) |
284
|
|
|
elif fo & 0xc0 == 0x40: # special real value |
285
|
|
|
pass |
286
|
|
|
else: |
287
|
|
|
raise error.SubstrateUnderrunError( |
288
|
|
|
'Unknown encoding (tag %s)' % fo |
289
|
|
|
) |
290
|
|
|
return self._createComponent(asn1Spec, tagSet, value), substrate |
|
|
|
|
291
|
|
|
|
292
|
|
|
class SequenceDecoder(AbstractConstructedDecoder): |
293
|
|
|
protoComponent = univ.Sequence() |
294
|
|
|
def _getComponentTagMap(self, r, idx): |
295
|
|
|
try: |
296
|
|
|
return r.getComponentTagMapNearPosition(idx) |
297
|
|
|
except error.PyAsn1Error: |
298
|
|
|
return |
299
|
|
|
|
300
|
|
|
def _getComponentPositionByType(self, r, t, idx): |
301
|
|
|
return r.getComponentPositionNearType(t, idx) |
302
|
|
|
|
303
|
|
|
def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, |
304
|
|
|
length, state, decodeFun): |
305
|
|
|
substrate = substrate[:length] |
306
|
|
|
r = self._createComponent(asn1Spec, tagSet) |
307
|
|
|
idx = 0 |
308
|
|
|
if not decodeFun: |
309
|
|
|
return r, substrate |
310
|
|
|
while substrate: |
311
|
|
|
asn1Spec = self._getComponentTagMap(r, idx) |
312
|
|
|
component, substrate = decodeFun( |
313
|
|
|
substrate, asn1Spec |
314
|
|
|
) |
315
|
|
|
idx = self._getComponentPositionByType( |
316
|
|
|
r, component.getEffectiveTagSet(), idx |
317
|
|
|
) |
318
|
|
|
r.setComponentByPosition(idx, component, asn1Spec is None) |
319
|
|
|
idx = idx + 1 |
320
|
|
|
r.setDefaultComponents() |
321
|
|
|
r.verifySizeSpec() |
322
|
|
|
return r, substrate |
323
|
|
|
|
324
|
|
|
def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, |
325
|
|
|
length, state, decodeFun): |
326
|
|
|
r = self._createComponent(asn1Spec, tagSet) |
327
|
|
|
idx = 0 |
328
|
|
|
while substrate: |
329
|
|
|
asn1Spec = self._getComponentTagMap(r, idx) |
330
|
|
|
if not decodeFun: |
331
|
|
|
return r, substrate |
332
|
|
|
component, substrate = decodeFun(substrate, asn1Spec) |
333
|
|
|
if component == eoo.endOfOctets: |
334
|
|
|
break |
335
|
|
|
idx = self._getComponentPositionByType( |
336
|
|
|
r, component.getEffectiveTagSet(), idx |
337
|
|
|
) |
338
|
|
|
r.setComponentByPosition(idx, component, asn1Spec is None) |
339
|
|
|
idx = idx + 1 |
340
|
|
|
else: |
341
|
|
|
raise error.SubstrateUnderrunError( |
342
|
|
|
'No EOO seen before substrate ends' |
343
|
|
|
) |
344
|
|
|
r.setDefaultComponents() |
345
|
|
|
r.verifySizeSpec() |
346
|
|
|
return r, substrate |
347
|
|
|
|
348
|
|
|
class SequenceOfDecoder(AbstractConstructedDecoder): |
349
|
|
|
protoComponent = univ.SequenceOf() |
350
|
|
|
def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, |
351
|
|
|
length, state, decodeFun): |
352
|
|
|
substrate = substrate[:length] |
353
|
|
|
r = self._createComponent(asn1Spec, tagSet) |
354
|
|
|
asn1Spec = r.getComponentType() |
355
|
|
|
idx = 0 |
356
|
|
|
if not decodeFun: |
357
|
|
|
return r, substrate |
358
|
|
|
while substrate: |
359
|
|
|
component, substrate = decodeFun( |
360
|
|
|
substrate, asn1Spec |
361
|
|
|
) |
362
|
|
|
r.setComponentByPosition(idx, component, asn1Spec is None) |
363
|
|
|
idx = idx + 1 |
364
|
|
|
r.verifySizeSpec() |
365
|
|
|
return r, substrate |
366
|
|
|
|
367
|
|
|
def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, |
368
|
|
|
length, state, decodeFun): |
369
|
|
|
r = self._createComponent(asn1Spec, tagSet) |
370
|
|
|
asn1Spec = r.getComponentType() |
371
|
|
|
idx = 0 |
372
|
|
|
if not decodeFun: |
373
|
|
|
return r, substrate |
374
|
|
|
while substrate: |
375
|
|
|
component, substrate = decodeFun(substrate, asn1Spec) |
376
|
|
|
if component == eoo.endOfOctets: |
377
|
|
|
break |
378
|
|
|
r.setComponentByPosition(idx, component, asn1Spec is None) |
379
|
|
|
idx = idx + 1 |
380
|
|
|
else: |
381
|
|
|
raise error.SubstrateUnderrunError( |
382
|
|
|
'No EOO seen before substrate ends' |
383
|
|
|
) |
384
|
|
|
r.verifySizeSpec() |
385
|
|
|
return r, substrate |
386
|
|
|
|
387
|
|
|
class SetDecoder(SequenceDecoder): |
388
|
|
|
protoComponent = univ.Set() |
389
|
|
|
def _getComponentTagMap(self, r, idx): |
390
|
|
|
return r.getComponentTagMap() |
391
|
|
|
|
392
|
|
|
def _getComponentPositionByType(self, r, t, idx): |
393
|
|
|
nextIdx = r.getComponentPositionByType(t) |
394
|
|
|
if nextIdx is None: |
395
|
|
|
return idx |
396
|
|
|
else: |
397
|
|
|
return nextIdx |
398
|
|
|
|
399
|
|
|
class SetOfDecoder(SequenceOfDecoder): |
400
|
|
|
protoComponent = univ.SetOf() |
401
|
|
|
|
402
|
|
|
class ChoiceDecoder(AbstractConstructedDecoder): |
403
|
|
|
protoComponent = univ.Choice() |
404
|
|
|
def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, |
405
|
|
|
length, state, decodeFun): |
406
|
|
|
substrate = substrate[:length] |
407
|
|
|
r = self._createComponent(asn1Spec, tagSet) |
408
|
|
|
if not decodeFun: |
409
|
|
|
return r, substrate |
410
|
|
|
if r.getTagSet() == tagSet: # explicitly tagged Choice |
411
|
|
|
component, substrate = decodeFun( |
412
|
|
|
substrate, r.getComponentTagMap() |
413
|
|
|
) |
414
|
|
|
else: |
415
|
|
|
component, substrate = decodeFun( |
416
|
|
|
substrate, r.getComponentTagMap(), tagSet, length, state |
417
|
|
|
) |
418
|
|
|
if isinstance(component, univ.Choice): |
419
|
|
|
effectiveTagSet = component.getEffectiveTagSet() |
420
|
|
|
else: |
421
|
|
|
effectiveTagSet = component.getTagSet() |
422
|
|
|
r.setComponentByType(effectiveTagSet, component, 0, asn1Spec is None) |
423
|
|
|
return r, substrate |
424
|
|
|
|
425
|
|
|
indefLenValueDecoder = valueDecoder |
426
|
|
|
|
427
|
|
|
class AnyDecoder(AbstractSimpleDecoder): |
428
|
|
|
protoComponent = univ.Any() |
429
|
|
|
def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, |
430
|
|
|
length, state, decodeFun): |
431
|
|
|
if asn1Spec is None or \ |
432
|
|
|
asn1Spec is not None and tagSet != asn1Spec.getTagSet(): |
433
|
|
|
# untagged Any container, recover inner header substrate |
434
|
|
|
length = length + len(fullSubstrate) - len(substrate) |
435
|
|
|
substrate = fullSubstrate |
436
|
|
|
substrate = substrate[:length] |
437
|
|
|
return self._createComponent(asn1Spec, tagSet, value=substrate), '' |
438
|
|
|
|
439
|
|
|
def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, |
440
|
|
|
length, state, decodeFun): |
441
|
|
|
if asn1Spec is not None and tagSet == asn1Spec.getTagSet(): |
442
|
|
|
# tagged Any type -- consume header substrate |
443
|
|
|
header = '' |
444
|
|
|
else: |
445
|
|
|
# untagged Any, recover header substrate |
446
|
|
|
header = fullSubstrate[:-len(substrate)] |
447
|
|
|
|
448
|
|
|
r = self._createComponent(asn1Spec, tagSet, header) |
449
|
|
|
|
450
|
|
|
# Any components do not inherit initial tag |
451
|
|
|
asn1Spec = self.protoComponent |
452
|
|
|
|
453
|
|
|
if not decodeFun: |
454
|
|
|
return r, substrate |
455
|
|
|
while substrate: |
456
|
|
|
component, substrate = decodeFun(substrate, asn1Spec) |
457
|
|
|
if component == eoo.endOfOctets: |
458
|
|
|
break |
459
|
|
|
r = r + component |
460
|
|
|
else: |
461
|
|
|
raise error.SubstrateUnderrunError( |
462
|
|
|
'No EOO seen before substrate ends' |
463
|
|
|
) |
464
|
|
|
return r, substrate |
465
|
|
|
|
466
|
|
|
# character string types |
467
|
|
|
class UTF8StringDecoder(OctetStringDecoder): |
468
|
|
|
protoComponent = char.UTF8String() |
469
|
|
|
class NumericStringDecoder(OctetStringDecoder): |
470
|
|
|
protoComponent = char.NumericString() |
471
|
|
|
class PrintableStringDecoder(OctetStringDecoder): |
472
|
|
|
protoComponent = char.PrintableString() |
473
|
|
|
class TeletexStringDecoder(OctetStringDecoder): |
474
|
|
|
protoComponent = char.TeletexString() |
475
|
|
|
class VideotexStringDecoder(OctetStringDecoder): |
476
|
|
|
protoComponent = char.VideotexString() |
477
|
|
|
class IA5StringDecoder(OctetStringDecoder): |
478
|
|
|
protoComponent = char.IA5String() |
479
|
|
|
class GraphicStringDecoder(OctetStringDecoder): |
480
|
|
|
protoComponent = char.GraphicString() |
481
|
|
|
class VisibleStringDecoder(OctetStringDecoder): |
482
|
|
|
protoComponent = char.VisibleString() |
483
|
|
|
class GeneralStringDecoder(OctetStringDecoder): |
484
|
|
|
protoComponent = char.GeneralString() |
485
|
|
|
class UniversalStringDecoder(OctetStringDecoder): |
486
|
|
|
protoComponent = char.UniversalString() |
487
|
|
|
class BMPStringDecoder(OctetStringDecoder): |
488
|
|
|
protoComponent = char.BMPString() |
489
|
|
|
|
490
|
|
|
# "useful" types |
491
|
|
|
class GeneralizedTimeDecoder(OctetStringDecoder): |
492
|
|
|
protoComponent = useful.GeneralizedTime() |
493
|
|
|
class UTCTimeDecoder(OctetStringDecoder): |
494
|
|
|
protoComponent = useful.UTCTime() |
495
|
|
|
|
496
|
|
|
tagMap = { |
497
|
|
|
eoo.endOfOctets.tagSet: EndOfOctetsDecoder(), |
498
|
|
|
univ.Integer.tagSet: IntegerDecoder(), |
499
|
|
|
univ.Boolean.tagSet: BooleanDecoder(), |
500
|
|
|
univ.BitString.tagSet: BitStringDecoder(), |
501
|
|
|
univ.OctetString.tagSet: OctetStringDecoder(), |
502
|
|
|
univ.Null.tagSet: NullDecoder(), |
503
|
|
|
univ.ObjectIdentifier.tagSet: ObjectIdentifierDecoder(), |
504
|
|
|
univ.Enumerated.tagSet: IntegerDecoder(), |
505
|
|
|
univ.Real.tagSet: RealDecoder(), |
506
|
|
|
univ.Sequence.tagSet: SequenceDecoder(), # conflicts with SequenceOf |
507
|
|
|
univ.Set.tagSet: SetDecoder(), # conflicts with SetOf |
508
|
|
|
univ.Choice.tagSet: ChoiceDecoder(), # conflicts with Any |
509
|
|
|
# character string types |
510
|
|
|
char.UTF8String.tagSet: UTF8StringDecoder(), |
511
|
|
|
char.NumericString.tagSet: NumericStringDecoder(), |
512
|
|
|
char.PrintableString.tagSet: PrintableStringDecoder(), |
513
|
|
|
char.TeletexString.tagSet: TeletexStringDecoder(), |
514
|
|
|
char.VideotexString.tagSet: VideotexStringDecoder(), |
515
|
|
|
char.IA5String.tagSet: IA5StringDecoder(), |
516
|
|
|
char.GraphicString.tagSet: GraphicStringDecoder(), |
517
|
|
|
char.VisibleString.tagSet: VisibleStringDecoder(), |
518
|
|
|
char.GeneralString.tagSet: GeneralStringDecoder(), |
519
|
|
|
char.UniversalString.tagSet: UniversalStringDecoder(), |
520
|
|
|
char.BMPString.tagSet: BMPStringDecoder(), |
521
|
|
|
# useful types |
522
|
|
|
useful.GeneralizedTime.tagSet: GeneralizedTimeDecoder(), |
523
|
|
|
useful.UTCTime.tagSet: UTCTimeDecoder() |
524
|
|
|
} |
525
|
|
|
|
526
|
|
|
# Type-to-codec map for ambiguous ASN.1 types |
527
|
|
|
typeMap = { |
528
|
|
|
univ.Set.typeId: SetDecoder(), |
529
|
|
|
univ.SetOf.typeId: SetOfDecoder(), |
530
|
|
|
univ.Sequence.typeId: SequenceDecoder(), |
531
|
|
|
univ.SequenceOf.typeId: SequenceOfDecoder(), |
532
|
|
|
univ.Choice.typeId: ChoiceDecoder(), |
533
|
|
|
univ.Any.typeId: AnyDecoder() |
534
|
|
|
} |
535
|
|
|
|
536
|
|
|
( stDecodeTag, stDecodeLength, stGetValueDecoder, stGetValueDecoderByAsn1Spec, |
537
|
|
|
stGetValueDecoderByTag, stTryAsExplicitTag, stDecodeValue, |
538
|
|
|
stDumpRawValue, stErrorCondition, stStop ) = [x for x in range(10)] |
539
|
|
|
|
540
|
|
|
class Decoder: |
541
|
|
|
defaultErrorState = stErrorCondition |
542
|
|
|
# defaultErrorState = stDumpRawValue |
543
|
|
|
defaultRawDecoder = AnyDecoder() |
544
|
|
|
def __init__(self, tagMap, typeMap={}): |
545
|
|
|
self.__tagMap = tagMap |
546
|
|
|
self.__typeMap = typeMap |
547
|
|
|
self.__endOfOctetsTagSet = eoo.endOfOctets.getTagSet() |
548
|
|
|
# Tag & TagSet objects caches |
549
|
|
|
self.__tagCache = {} |
550
|
|
|
self.__tagSetCache = {} |
551
|
|
|
|
552
|
|
|
def __call__(self, substrate, asn1Spec=None, tagSet=None, |
553
|
|
|
length=None, state=stDecodeTag, recursiveFlag=1): |
554
|
|
|
fullSubstrate = substrate |
555
|
|
|
while state != stStop: |
556
|
|
|
if state == stDecodeTag: |
557
|
|
|
# Decode tag |
558
|
|
|
if not substrate: |
559
|
|
|
raise error.SubstrateUnderrunError( |
560
|
|
|
'Short octet stream on tag decoding' |
561
|
|
|
) |
562
|
|
|
|
563
|
|
|
firstOctet = substrate[0] |
564
|
|
|
substrate = substrate[1:] |
565
|
|
|
if firstOctet in self.__tagCache: |
566
|
|
|
lastTag = self.__tagCache[firstOctet] |
567
|
|
|
else: |
568
|
|
|
t = oct2int(firstOctet) |
569
|
|
|
tagClass = t&0xC0 |
570
|
|
|
tagFormat = t&0x20 |
571
|
|
|
tagId = t&0x1F |
572
|
|
|
if tagId == 0x1F: |
573
|
|
|
tagId = 0 |
574
|
|
|
while 1: |
575
|
|
|
if not substrate: |
576
|
|
|
raise error.SubstrateUnderrunError( |
577
|
|
|
'Short octet stream on long tag decoding' |
578
|
|
|
) |
579
|
|
|
t = oct2int(substrate[0]) |
580
|
|
|
tagId = tagId << 7 | (t&0x7F) |
581
|
|
|
substrate = substrate[1:] |
582
|
|
|
if not t&0x80: |
583
|
|
|
break |
584
|
|
|
lastTag = tag.Tag( |
585
|
|
|
tagClass=tagClass, tagFormat=tagFormat, tagId=tagId |
586
|
|
|
) |
587
|
|
|
if tagId < 31: |
588
|
|
|
# cache short tags |
589
|
|
|
self.__tagCache[firstOctet] = lastTag |
590
|
|
|
if tagSet is None: |
591
|
|
|
if firstOctet in self.__tagSetCache: |
592
|
|
|
tagSet = self.__tagSetCache[firstOctet] |
593
|
|
|
else: |
594
|
|
|
# base tag not recovered |
595
|
|
|
tagSet = tag.TagSet((), lastTag) |
596
|
|
|
if firstOctet in self.__tagCache: |
597
|
|
|
self.__tagSetCache[firstOctet] = tagSet |
598
|
|
|
else: |
599
|
|
|
tagSet = lastTag + tagSet |
600
|
|
|
state = stDecodeLength |
601
|
|
|
if state == stDecodeLength: |
602
|
|
|
# Decode length |
603
|
|
|
if not substrate: |
604
|
|
|
raise error.SubstrateUnderrunError( |
605
|
|
|
'Short octet stream on length decoding' |
606
|
|
|
) |
607
|
|
|
firstOctet = oct2int(substrate[0]) |
608
|
|
|
if firstOctet == 128: |
609
|
|
|
size = 1 |
610
|
|
|
length = -1 |
611
|
|
|
elif firstOctet < 128: |
612
|
|
|
length, size = firstOctet, 1 |
613
|
|
|
else: |
614
|
|
|
size = firstOctet & 0x7F |
615
|
|
|
# encoded in size bytes |
616
|
|
|
length = 0 |
617
|
|
|
lengthString = substrate[1:size+1] |
618
|
|
|
# missing check on maximum size, which shouldn't be a |
619
|
|
|
# problem, we can handle more than is possible |
620
|
|
|
if len(lengthString) != size: |
621
|
|
|
raise error.SubstrateUnderrunError( |
622
|
|
|
'%s<%s at %s' % |
623
|
|
|
(size, len(lengthString), tagSet) |
624
|
|
|
) |
625
|
|
|
for char in lengthString: |
626
|
|
|
length = (length << 8) | oct2int(char) |
627
|
|
|
size = size + 1 |
628
|
|
|
state = stGetValueDecoder |
629
|
|
|
substrate = substrate[size:] |
630
|
|
|
if length != -1 and len(substrate) < length: |
631
|
|
|
raise error.SubstrateUnderrunError( |
632
|
|
|
'%d-octet short' % (length - len(substrate)) |
633
|
|
|
) |
634
|
|
|
if state == stGetValueDecoder: |
635
|
|
|
if asn1Spec is None: |
636
|
|
|
state = stGetValueDecoderByTag |
637
|
|
|
else: |
638
|
|
|
state = stGetValueDecoderByAsn1Spec |
639
|
|
|
# |
640
|
|
|
# There're two ways of creating subtypes in ASN.1 what influences |
641
|
|
|
# decoder operation. These methods are: |
642
|
|
|
# 1) Either base types used in or no IMPLICIT tagging has been |
643
|
|
|
# applied on subtyping. |
644
|
|
|
# 2) Subtype syntax drops base type information (by means of |
645
|
|
|
# IMPLICIT tagging. |
646
|
|
|
# The first case allows for complete tag recovery from substrate |
647
|
|
|
# while the second one requires original ASN.1 type spec for |
648
|
|
|
# decoding. |
649
|
|
|
# |
650
|
|
|
# In either case a set of tags (tagSet) is coming from substrate |
651
|
|
|
# in an incremental, tag-by-tag fashion (this is the case of |
652
|
|
|
# EXPLICIT tag which is most basic). Outermost tag comes first |
653
|
|
|
# from the wire. |
654
|
|
|
# |
655
|
|
|
if state == stGetValueDecoderByTag: |
656
|
|
|
if tagSet in self.__tagMap: |
657
|
|
|
concreteDecoder = self.__tagMap[tagSet] |
658
|
|
|
else: |
659
|
|
|
concreteDecoder = None |
660
|
|
|
if concreteDecoder: |
661
|
|
|
state = stDecodeValue |
662
|
|
|
else: |
663
|
|
|
_k = tagSet[:1] |
664
|
|
|
if _k in self.__tagMap: |
665
|
|
|
concreteDecoder = self.__tagMap[_k] |
666
|
|
|
else: |
667
|
|
|
concreteDecoder = None |
668
|
|
|
if concreteDecoder: |
669
|
|
|
state = stDecodeValue |
670
|
|
|
else: |
671
|
|
|
state = stTryAsExplicitTag |
672
|
|
|
if state == stGetValueDecoderByAsn1Spec: |
673
|
|
|
if isinstance(asn1Spec, (dict, tagmap.TagMap)): |
674
|
|
|
if tagSet in asn1Spec: |
675
|
|
|
__chosenSpec = asn1Spec[tagSet] |
676
|
|
|
else: |
677
|
|
|
__chosenSpec = None |
678
|
|
|
else: |
679
|
|
|
__chosenSpec = asn1Spec |
680
|
|
|
if __chosenSpec is not None and ( |
681
|
|
|
tagSet == __chosenSpec.getTagSet() or \ |
682
|
|
|
tagSet in __chosenSpec.getTagMap() |
683
|
|
|
): |
684
|
|
|
# use base type for codec lookup to recover untagged types |
685
|
|
|
baseTagSet = __chosenSpec.baseTagSet |
686
|
|
|
if __chosenSpec.typeId is not None and \ |
687
|
|
|
__chosenSpec.typeId in self.__typeMap: |
688
|
|
|
# ambiguous type |
689
|
|
|
concreteDecoder = self.__typeMap[__chosenSpec.typeId] |
690
|
|
|
elif baseTagSet in self.__tagMap: |
691
|
|
|
# base type or tagged subtype |
692
|
|
|
concreteDecoder = self.__tagMap[baseTagSet] |
693
|
|
|
else: |
694
|
|
|
concreteDecoder = None |
695
|
|
|
if concreteDecoder: |
696
|
|
|
asn1Spec = __chosenSpec |
697
|
|
|
state = stDecodeValue |
698
|
|
|
else: |
699
|
|
|
state = stTryAsExplicitTag |
700
|
|
|
elif tagSet == self.__endOfOctetsTagSet: |
701
|
|
|
concreteDecoder = self.__tagMap[tagSet] |
702
|
|
|
state = stDecodeValue |
703
|
|
|
else: |
704
|
|
|
state = stTryAsExplicitTag |
705
|
|
|
if state == stTryAsExplicitTag: |
706
|
|
|
if tagSet and \ |
707
|
|
|
tagSet[0][1] == tag.tagFormatConstructed and \ |
708
|
|
|
tagSet[0][0] != tag.tagClassUniversal: |
709
|
|
|
# Assume explicit tagging |
710
|
|
|
concreteDecoder = explicitTagDecoder |
711
|
|
|
state = stDecodeValue |
712
|
|
|
else: |
713
|
|
|
state = self.defaultErrorState |
714
|
|
|
if state == stDumpRawValue: |
715
|
|
|
concreteDecoder = self.defaultRawDecoder |
716
|
|
|
state = stDecodeValue |
717
|
|
|
if state == stDecodeValue: |
718
|
|
|
if recursiveFlag: |
719
|
|
|
decodeFun = self |
720
|
|
|
else: |
721
|
|
|
decodeFun = None |
722
|
|
|
if length == -1: # indef length |
723
|
|
|
value, substrate = concreteDecoder.indefLenValueDecoder( |
|
|
|
|
724
|
|
|
fullSubstrate, substrate, asn1Spec, tagSet, length, |
725
|
|
|
stGetValueDecoder, decodeFun |
726
|
|
|
) |
727
|
|
|
else: |
728
|
|
|
value, _substrate = concreteDecoder.valueDecoder( |
729
|
|
|
fullSubstrate, substrate, asn1Spec, tagSet, length, |
730
|
|
|
stGetValueDecoder, decodeFun |
731
|
|
|
) |
732
|
|
|
if recursiveFlag: |
733
|
|
|
substrate = substrate[length:] |
734
|
|
|
else: |
735
|
|
|
substrate = _substrate |
736
|
|
|
state = stStop |
737
|
|
|
if state == stErrorCondition: |
738
|
|
|
raise error.PyAsn1Error( |
739
|
|
|
'%s not in asn1Spec: %s' % (tagSet, repr(asn1Spec)) |
740
|
|
|
) |
741
|
|
|
return value, substrate |
|
|
|
|
742
|
|
|
|
743
|
|
|
decode = Decoder(tagMap, typeMap) |
744
|
|
|
|
745
|
|
|
# XXX |
746
|
|
|
# non-recursive decoding; return position rather than substrate |
747
|
|
|
|