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