Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 

1655 rader
57 KiB

  1. #
  2. # This file is part of pyasn1 software.
  3. #
  4. # Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
  5. # License: http://snmplabs.com/pyasn1/license.html
  6. #
  7. from pyasn1 import debug
  8. from pyasn1 import error
  9. from pyasn1.codec.ber import eoo
  10. from pyasn1.compat.integer import from_bytes
  11. from pyasn1.compat.octets import oct2int, octs2ints, ints2octs, null
  12. from pyasn1.type import base
  13. from pyasn1.type import char
  14. from pyasn1.type import tag
  15. from pyasn1.type import tagmap
  16. from pyasn1.type import univ
  17. from pyasn1.type import useful
  18. __all__ = ['decode']
  19. LOG = debug.registerLoggee(__name__, flags=debug.DEBUG_DECODER)
  20. noValue = base.noValue
  21. class AbstractDecoder(object):
  22. protoComponent = None
  23. def valueDecoder(self, substrate, asn1Spec,
  24. tagSet=None, length=None, state=None,
  25. decodeFun=None, substrateFun=None,
  26. **options):
  27. raise error.PyAsn1Error('Decoder not implemented for %s' % (tagSet,))
  28. def indefLenValueDecoder(self, substrate, asn1Spec,
  29. tagSet=None, length=None, state=None,
  30. decodeFun=None, substrateFun=None,
  31. **options):
  32. raise error.PyAsn1Error('Indefinite length mode decoder not implemented for %s' % (tagSet,))
  33. class AbstractSimpleDecoder(AbstractDecoder):
  34. @staticmethod
  35. def substrateCollector(asn1Object, substrate, length):
  36. return substrate[:length], substrate[length:]
  37. def _createComponent(self, asn1Spec, tagSet, value, **options):
  38. if options.get('native'):
  39. return value
  40. elif asn1Spec is None:
  41. return self.protoComponent.clone(value, tagSet=tagSet)
  42. elif value is noValue:
  43. return asn1Spec
  44. else:
  45. return asn1Spec.clone(value)
  46. class ExplicitTagDecoder(AbstractSimpleDecoder):
  47. protoComponent = univ.Any('')
  48. def valueDecoder(self, substrate, asn1Spec,
  49. tagSet=None, length=None, state=None,
  50. decodeFun=None, substrateFun=None,
  51. **options):
  52. if substrateFun:
  53. return substrateFun(
  54. self._createComponent(asn1Spec, tagSet, '', **options),
  55. substrate, length
  56. )
  57. head, tail = substrate[:length], substrate[length:]
  58. value, _ = decodeFun(head, asn1Spec, tagSet, length, **options)
  59. if LOG:
  60. LOG('explicit tag container carries %d octets of trailing payload '
  61. '(will be lost!): %s' % (len(_), debug.hexdump(_)))
  62. return value, tail
  63. def indefLenValueDecoder(self, substrate, asn1Spec,
  64. tagSet=None, length=None, state=None,
  65. decodeFun=None, substrateFun=None,
  66. **options):
  67. if substrateFun:
  68. return substrateFun(
  69. self._createComponent(asn1Spec, tagSet, '', **options),
  70. substrate, length
  71. )
  72. value, substrate = decodeFun(substrate, asn1Spec, tagSet, length, **options)
  73. eooMarker, substrate = decodeFun(substrate, allowEoo=True, **options)
  74. if eooMarker is eoo.endOfOctets:
  75. return value, substrate
  76. else:
  77. raise error.PyAsn1Error('Missing end-of-octets terminator')
  78. explicitTagDecoder = ExplicitTagDecoder()
  79. class IntegerDecoder(AbstractSimpleDecoder):
  80. protoComponent = univ.Integer(0)
  81. def valueDecoder(self, substrate, asn1Spec,
  82. tagSet=None, length=None, state=None,
  83. decodeFun=None, substrateFun=None,
  84. **options):
  85. if tagSet[0].tagFormat != tag.tagFormatSimple:
  86. raise error.PyAsn1Error('Simple tag format expected')
  87. head, tail = substrate[:length], substrate[length:]
  88. if not head:
  89. return self._createComponent(asn1Spec, tagSet, 0, **options), tail
  90. value = from_bytes(head, signed=True)
  91. return self._createComponent(asn1Spec, tagSet, value, **options), tail
  92. class BooleanDecoder(IntegerDecoder):
  93. protoComponent = univ.Boolean(0)
  94. def _createComponent(self, asn1Spec, tagSet, value, **options):
  95. return IntegerDecoder._createComponent(
  96. self, asn1Spec, tagSet, value and 1 or 0, **options)
  97. class BitStringDecoder(AbstractSimpleDecoder):
  98. protoComponent = univ.BitString(())
  99. supportConstructedForm = True
  100. def valueDecoder(self, substrate, asn1Spec,
  101. tagSet=None, length=None, state=None,
  102. decodeFun=None, substrateFun=None,
  103. **options):
  104. head, tail = substrate[:length], substrate[length:]
  105. if substrateFun:
  106. return substrateFun(self._createComponent(
  107. asn1Spec, tagSet, noValue, **options), substrate, length)
  108. if not head:
  109. raise error.PyAsn1Error('Empty BIT STRING substrate')
  110. if tagSet[0].tagFormat == tag.tagFormatSimple: # XXX what tag to check?
  111. trailingBits = oct2int(head[0])
  112. if trailingBits > 7:
  113. raise error.PyAsn1Error(
  114. 'Trailing bits overflow %s' % trailingBits
  115. )
  116. value = self.protoComponent.fromOctetString(
  117. head[1:], internalFormat=True, padding=trailingBits)
  118. return self._createComponent(asn1Spec, tagSet, value, **options), tail
  119. if not self.supportConstructedForm:
  120. raise error.PyAsn1Error('Constructed encoding form prohibited '
  121. 'at %s' % self.__class__.__name__)
  122. if LOG:
  123. LOG('assembling constructed serialization')
  124. # All inner fragments are of the same type, treat them as octet string
  125. substrateFun = self.substrateCollector
  126. bitString = self.protoComponent.fromOctetString(null, internalFormat=True)
  127. while head:
  128. component, head = decodeFun(head, self.protoComponent,
  129. substrateFun=substrateFun, **options)
  130. trailingBits = oct2int(component[0])
  131. if trailingBits > 7:
  132. raise error.PyAsn1Error(
  133. 'Trailing bits overflow %s' % trailingBits
  134. )
  135. bitString = self.protoComponent.fromOctetString(
  136. component[1:], internalFormat=True,
  137. prepend=bitString, padding=trailingBits
  138. )
  139. return self._createComponent(asn1Spec, tagSet, bitString, **options), tail
  140. def indefLenValueDecoder(self, substrate, asn1Spec,
  141. tagSet=None, length=None, state=None,
  142. decodeFun=None, substrateFun=None,
  143. **options):
  144. if substrateFun:
  145. return substrateFun(self._createComponent(asn1Spec, tagSet, noValue, **options), substrate, length)
  146. # All inner fragments are of the same type, treat them as octet string
  147. substrateFun = self.substrateCollector
  148. bitString = self.protoComponent.fromOctetString(null, internalFormat=True)
  149. while substrate:
  150. component, substrate = decodeFun(substrate, self.protoComponent,
  151. substrateFun=substrateFun,
  152. allowEoo=True, **options)
  153. if component is eoo.endOfOctets:
  154. break
  155. trailingBits = oct2int(component[0])
  156. if trailingBits > 7:
  157. raise error.PyAsn1Error(
  158. 'Trailing bits overflow %s' % trailingBits
  159. )
  160. bitString = self.protoComponent.fromOctetString(
  161. component[1:], internalFormat=True,
  162. prepend=bitString, padding=trailingBits
  163. )
  164. else:
  165. raise error.SubstrateUnderrunError('No EOO seen before substrate ends')
  166. return self._createComponent(asn1Spec, tagSet, bitString, **options), substrate
  167. class OctetStringDecoder(AbstractSimpleDecoder):
  168. protoComponent = univ.OctetString('')
  169. supportConstructedForm = True
  170. def valueDecoder(self, substrate, asn1Spec,
  171. tagSet=None, length=None, state=None,
  172. decodeFun=None, substrateFun=None,
  173. **options):
  174. head, tail = substrate[:length], substrate[length:]
  175. if substrateFun:
  176. return substrateFun(self._createComponent(asn1Spec, tagSet, noValue, **options),
  177. substrate, length)
  178. if tagSet[0].tagFormat == tag.tagFormatSimple: # XXX what tag to check?
  179. return self._createComponent(asn1Spec, tagSet, head, **options), tail
  180. if not self.supportConstructedForm:
  181. raise error.PyAsn1Error('Constructed encoding form prohibited at %s' % self.__class__.__name__)
  182. if LOG:
  183. LOG('assembling constructed serialization')
  184. # All inner fragments are of the same type, treat them as octet string
  185. substrateFun = self.substrateCollector
  186. header = null
  187. while head:
  188. component, head = decodeFun(head, self.protoComponent,
  189. substrateFun=substrateFun,
  190. **options)
  191. header += component
  192. return self._createComponent(asn1Spec, tagSet, header, **options), tail
  193. def indefLenValueDecoder(self, substrate, asn1Spec,
  194. tagSet=None, length=None, state=None,
  195. decodeFun=None, substrateFun=None,
  196. **options):
  197. if substrateFun and substrateFun is not self.substrateCollector:
  198. asn1Object = self._createComponent(asn1Spec, tagSet, noValue, **options)
  199. return substrateFun(asn1Object, substrate, length)
  200. # All inner fragments are of the same type, treat them as octet string
  201. substrateFun = self.substrateCollector
  202. header = null
  203. while substrate:
  204. component, substrate = decodeFun(substrate,
  205. self.protoComponent,
  206. substrateFun=substrateFun,
  207. allowEoo=True, **options)
  208. if component is eoo.endOfOctets:
  209. break
  210. header += component
  211. else:
  212. raise error.SubstrateUnderrunError(
  213. 'No EOO seen before substrate ends'
  214. )
  215. return self._createComponent(asn1Spec, tagSet, header, **options), substrate
  216. class NullDecoder(AbstractSimpleDecoder):
  217. protoComponent = univ.Null('')
  218. def valueDecoder(self, substrate, asn1Spec,
  219. tagSet=None, length=None, state=None,
  220. decodeFun=None, substrateFun=None,
  221. **options):
  222. if tagSet[0].tagFormat != tag.tagFormatSimple:
  223. raise error.PyAsn1Error('Simple tag format expected')
  224. head, tail = substrate[:length], substrate[length:]
  225. component = self._createComponent(asn1Spec, tagSet, '', **options)
  226. if head:
  227. raise error.PyAsn1Error('Unexpected %d-octet substrate for Null' % length)
  228. return component, tail
  229. class ObjectIdentifierDecoder(AbstractSimpleDecoder):
  230. protoComponent = univ.ObjectIdentifier(())
  231. def valueDecoder(self, substrate, asn1Spec,
  232. tagSet=None, length=None, state=None,
  233. decodeFun=None, substrateFun=None,
  234. **options):
  235. if tagSet[0].tagFormat != tag.tagFormatSimple:
  236. raise error.PyAsn1Error('Simple tag format expected')
  237. head, tail = substrate[:length], substrate[length:]
  238. if not head:
  239. raise error.PyAsn1Error('Empty substrate')
  240. head = octs2ints(head)
  241. oid = ()
  242. index = 0
  243. substrateLen = len(head)
  244. while index < substrateLen:
  245. subId = head[index]
  246. index += 1
  247. if subId < 128:
  248. oid += (subId,)
  249. elif subId > 128:
  250. # Construct subid from a number of octets
  251. nextSubId = subId
  252. subId = 0
  253. while nextSubId >= 128:
  254. subId = (subId << 7) + (nextSubId & 0x7F)
  255. if index >= substrateLen:
  256. raise error.SubstrateUnderrunError(
  257. 'Short substrate for sub-OID past %s' % (oid,)
  258. )
  259. nextSubId = head[index]
  260. index += 1
  261. oid += ((subId << 7) + nextSubId,)
  262. elif subId == 128:
  263. # ASN.1 spec forbids leading zeros (0x80) in OID
  264. # encoding, tolerating it opens a vulnerability. See
  265. # https://www.esat.kuleuven.be/cosic/publications/article-1432.pdf
  266. # page 7
  267. raise error.PyAsn1Error('Invalid octet 0x80 in OID encoding')
  268. # Decode two leading arcs
  269. if 0 <= oid[0] <= 39:
  270. oid = (0,) + oid
  271. elif 40 <= oid[0] <= 79:
  272. oid = (1, oid[0] - 40) + oid[1:]
  273. elif oid[0] >= 80:
  274. oid = (2, oid[0] - 80) + oid[1:]
  275. else:
  276. raise error.PyAsn1Error('Malformed first OID octet: %s' % head[0])
  277. return self._createComponent(asn1Spec, tagSet, oid, **options), tail
  278. class RealDecoder(AbstractSimpleDecoder):
  279. protoComponent = univ.Real()
  280. def valueDecoder(self, substrate, asn1Spec,
  281. tagSet=None, length=None, state=None,
  282. decodeFun=None, substrateFun=None,
  283. **options):
  284. if tagSet[0].tagFormat != tag.tagFormatSimple:
  285. raise error.PyAsn1Error('Simple tag format expected')
  286. head, tail = substrate[:length], substrate[length:]
  287. if not head:
  288. return self._createComponent(asn1Spec, tagSet, 0.0, **options), tail
  289. fo = oct2int(head[0])
  290. head = head[1:]
  291. if fo & 0x80: # binary encoding
  292. if not head:
  293. raise error.PyAsn1Error("Incomplete floating-point value")
  294. if LOG:
  295. LOG('decoding binary encoded REAL')
  296. n = (fo & 0x03) + 1
  297. if n == 4:
  298. n = oct2int(head[0])
  299. head = head[1:]
  300. eo, head = head[:n], head[n:]
  301. if not eo or not head:
  302. raise error.PyAsn1Error('Real exponent screwed')
  303. e = oct2int(eo[0]) & 0x80 and -1 or 0
  304. while eo: # exponent
  305. e <<= 8
  306. e |= oct2int(eo[0])
  307. eo = eo[1:]
  308. b = fo >> 4 & 0x03 # base bits
  309. if b > 2:
  310. raise error.PyAsn1Error('Illegal Real base')
  311. if b == 1: # encbase = 8
  312. e *= 3
  313. elif b == 2: # encbase = 16
  314. e *= 4
  315. p = 0
  316. while head: # value
  317. p <<= 8
  318. p |= oct2int(head[0])
  319. head = head[1:]
  320. if fo & 0x40: # sign bit
  321. p = -p
  322. sf = fo >> 2 & 0x03 # scale bits
  323. p *= 2 ** sf
  324. value = (p, 2, e)
  325. elif fo & 0x40: # infinite value
  326. if LOG:
  327. LOG('decoding infinite REAL')
  328. value = fo & 0x01 and '-inf' or 'inf'
  329. elif fo & 0xc0 == 0: # character encoding
  330. if not head:
  331. raise error.PyAsn1Error("Incomplete floating-point value")
  332. if LOG:
  333. LOG('decoding character encoded REAL')
  334. try:
  335. if fo & 0x3 == 0x1: # NR1
  336. value = (int(head), 10, 0)
  337. elif fo & 0x3 == 0x2: # NR2
  338. value = float(head)
  339. elif fo & 0x3 == 0x3: # NR3
  340. value = float(head)
  341. else:
  342. raise error.SubstrateUnderrunError(
  343. 'Unknown NR (tag %s)' % fo
  344. )
  345. except ValueError:
  346. raise error.SubstrateUnderrunError(
  347. 'Bad character Real syntax'
  348. )
  349. else:
  350. raise error.SubstrateUnderrunError(
  351. 'Unknown encoding (tag %s)' % fo
  352. )
  353. return self._createComponent(asn1Spec, tagSet, value, **options), tail
  354. class AbstractConstructedDecoder(AbstractDecoder):
  355. protoComponent = None
  356. class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
  357. protoRecordComponent = None
  358. protoSequenceComponent = None
  359. def _getComponentTagMap(self, asn1Object, idx):
  360. raise NotImplementedError()
  361. def _getComponentPositionByType(self, asn1Object, tagSet, idx):
  362. raise NotImplementedError()
  363. def _decodeComponents(self, substrate, tagSet=None, decodeFun=None, **options):
  364. components = []
  365. componentTypes = set()
  366. while substrate:
  367. component, substrate = decodeFun(substrate, **options)
  368. if component is eoo.endOfOctets:
  369. break
  370. components.append(component)
  371. componentTypes.add(component.tagSet)
  372. # Now we have to guess is it SEQUENCE/SET or SEQUENCE OF/SET OF
  373. # The heuristics is:
  374. # * 1+ components of different types -> likely SEQUENCE/SET
  375. # * otherwise -> likely SEQUENCE OF/SET OF
  376. if len(componentTypes) > 1:
  377. protoComponent = self.protoRecordComponent
  378. else:
  379. protoComponent = self.protoSequenceComponent
  380. asn1Object = protoComponent.clone(
  381. # construct tagSet from base tag from prototype ASN.1 object
  382. # and additional tags recovered from the substrate
  383. tagSet=tag.TagSet(protoComponent.tagSet.baseTag, *tagSet.superTags)
  384. )
  385. if LOG:
  386. LOG('guessed %r container type (pass `asn1Spec` to guide the '
  387. 'decoder)' % asn1Object)
  388. for idx, component in enumerate(components):
  389. asn1Object.setComponentByPosition(
  390. idx, component,
  391. verifyConstraints=False,
  392. matchTags=False, matchConstraints=False
  393. )
  394. return asn1Object, substrate
  395. def valueDecoder(self, substrate, asn1Spec,
  396. tagSet=None, length=None, state=None,
  397. decodeFun=None, substrateFun=None,
  398. **options):
  399. if tagSet[0].tagFormat != tag.tagFormatConstructed:
  400. raise error.PyAsn1Error('Constructed tag format expected')
  401. head, tail = substrate[:length], substrate[length:]
  402. if substrateFun is not None:
  403. if asn1Spec is not None:
  404. asn1Object = asn1Spec.clone()
  405. elif self.protoComponent is not None:
  406. asn1Object = self.protoComponent.clone(tagSet=tagSet)
  407. else:
  408. asn1Object = self.protoRecordComponent, self.protoSequenceComponent
  409. return substrateFun(asn1Object, substrate, length)
  410. if asn1Spec is None:
  411. asn1Object, trailing = self._decodeComponents(
  412. head, tagSet=tagSet, decodeFun=decodeFun, **options
  413. )
  414. if trailing:
  415. if LOG:
  416. LOG('Unused trailing %d octets encountered: %s' % (
  417. len(trailing), debug.hexdump(trailing)))
  418. return asn1Object, tail
  419. asn1Object = asn1Spec.clone()
  420. asn1Object.clear()
  421. if asn1Spec.typeId in (univ.Sequence.typeId, univ.Set.typeId):
  422. namedTypes = asn1Spec.componentType
  423. isSetType = asn1Spec.typeId == univ.Set.typeId
  424. isDeterministic = not isSetType and not namedTypes.hasOptionalOrDefault
  425. if LOG:
  426. LOG('decoding %sdeterministic %s type %r chosen by type ID' % (
  427. not isDeterministic and 'non-' or '', isSetType and 'SET' or '',
  428. asn1Spec))
  429. seenIndices = set()
  430. idx = 0
  431. while head:
  432. if not namedTypes:
  433. componentType = None
  434. elif isSetType:
  435. componentType = namedTypes.tagMapUnique
  436. else:
  437. try:
  438. if isDeterministic:
  439. componentType = namedTypes[idx].asn1Object
  440. elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:
  441. componentType = namedTypes.getTagMapNearPosition(idx)
  442. else:
  443. componentType = namedTypes[idx].asn1Object
  444. except IndexError:
  445. raise error.PyAsn1Error(
  446. 'Excessive components decoded at %r' % (asn1Spec,)
  447. )
  448. component, head = decodeFun(head, componentType, **options)
  449. if not isDeterministic and namedTypes:
  450. if isSetType:
  451. idx = namedTypes.getPositionByType(component.effectiveTagSet)
  452. elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:
  453. idx = namedTypes.getPositionNearType(component.effectiveTagSet, idx)
  454. asn1Object.setComponentByPosition(
  455. idx, component,
  456. verifyConstraints=False,
  457. matchTags=False, matchConstraints=False
  458. )
  459. seenIndices.add(idx)
  460. idx += 1
  461. if LOG:
  462. LOG('seen component indices %s' % seenIndices)
  463. if namedTypes:
  464. if not namedTypes.requiredComponents.issubset(seenIndices):
  465. raise error.PyAsn1Error(
  466. 'ASN.1 object %s has uninitialized '
  467. 'components' % asn1Object.__class__.__name__)
  468. if namedTypes.hasOpenTypes:
  469. openTypes = options.get('openTypes', {})
  470. if LOG:
  471. LOG('using open types map: %r' % openTypes)
  472. if openTypes or options.get('decodeOpenTypes', False):
  473. for idx, namedType in enumerate(namedTypes.namedTypes):
  474. if not namedType.openType:
  475. continue
  476. if namedType.isOptional and not asn1Object.getComponentByPosition(idx).isValue:
  477. continue
  478. governingValue = asn1Object.getComponentByName(
  479. namedType.openType.name
  480. )
  481. try:
  482. openType = openTypes[governingValue]
  483. except KeyError:
  484. try:
  485. openType = namedType.openType[governingValue]
  486. except KeyError:
  487. if LOG:
  488. LOG('failed to resolve open type by governing '
  489. 'value %r' % (governingValue,))
  490. continue
  491. if LOG:
  492. LOG('resolved open type %r by governing '
  493. 'value %r' % (openType, governingValue))
  494. containerValue = asn1Object.getComponentByPosition(idx)
  495. if containerValue.typeId in (
  496. univ.SetOf.typeId, univ.SequenceOf.typeId):
  497. for pos, containerElement in enumerate(
  498. containerValue):
  499. component, rest = decodeFun(
  500. containerValue[pos].asOctets(),
  501. asn1Spec=openType, **options
  502. )
  503. containerValue[pos] = component
  504. else:
  505. component, rest = decodeFun(
  506. asn1Object.getComponentByPosition(idx).asOctets(),
  507. asn1Spec=openType, **options
  508. )
  509. asn1Object.setComponentByPosition(idx, component)
  510. else:
  511. inconsistency = asn1Object.isInconsistent
  512. if inconsistency:
  513. raise inconsistency
  514. else:
  515. asn1Object = asn1Spec.clone()
  516. asn1Object.clear()
  517. componentType = asn1Spec.componentType
  518. if LOG:
  519. LOG('decoding type %r chosen by given `asn1Spec`' % componentType)
  520. idx = 0
  521. while head:
  522. component, head = decodeFun(head, componentType, **options)
  523. asn1Object.setComponentByPosition(
  524. idx, component,
  525. verifyConstraints=False,
  526. matchTags=False, matchConstraints=False
  527. )
  528. idx += 1
  529. return asn1Object, tail
  530. def indefLenValueDecoder(self, substrate, asn1Spec,
  531. tagSet=None, length=None, state=None,
  532. decodeFun=None, substrateFun=None,
  533. **options):
  534. if tagSet[0].tagFormat != tag.tagFormatConstructed:
  535. raise error.PyAsn1Error('Constructed tag format expected')
  536. if substrateFun is not None:
  537. if asn1Spec is not None:
  538. asn1Object = asn1Spec.clone()
  539. elif self.protoComponent is not None:
  540. asn1Object = self.protoComponent.clone(tagSet=tagSet)
  541. else:
  542. asn1Object = self.protoRecordComponent, self.protoSequenceComponent
  543. return substrateFun(asn1Object, substrate, length)
  544. if asn1Spec is None:
  545. return self._decodeComponents(
  546. substrate, tagSet=tagSet, decodeFun=decodeFun,
  547. **dict(options, allowEoo=True)
  548. )
  549. asn1Object = asn1Spec.clone()
  550. asn1Object.clear()
  551. if asn1Spec.typeId in (univ.Sequence.typeId, univ.Set.typeId):
  552. namedTypes = asn1Object.componentType
  553. isSetType = asn1Object.typeId == univ.Set.typeId
  554. isDeterministic = not isSetType and not namedTypes.hasOptionalOrDefault
  555. if LOG:
  556. LOG('decoding %sdeterministic %s type %r chosen by type ID' % (
  557. not isDeterministic and 'non-' or '', isSetType and 'SET' or '',
  558. asn1Spec))
  559. seenIndices = set()
  560. idx = 0
  561. while substrate:
  562. if len(namedTypes) <= idx:
  563. asn1Spec = None
  564. elif isSetType:
  565. asn1Spec = namedTypes.tagMapUnique
  566. else:
  567. try:
  568. if isDeterministic:
  569. asn1Spec = namedTypes[idx].asn1Object
  570. elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:
  571. asn1Spec = namedTypes.getTagMapNearPosition(idx)
  572. else:
  573. asn1Spec = namedTypes[idx].asn1Object
  574. except IndexError:
  575. raise error.PyAsn1Error(
  576. 'Excessive components decoded at %r' % (asn1Object,)
  577. )
  578. component, substrate = decodeFun(substrate, asn1Spec, allowEoo=True, **options)
  579. if component is eoo.endOfOctets:
  580. break
  581. if not isDeterministic and namedTypes:
  582. if isSetType:
  583. idx = namedTypes.getPositionByType(component.effectiveTagSet)
  584. elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:
  585. idx = namedTypes.getPositionNearType(component.effectiveTagSet, idx)
  586. asn1Object.setComponentByPosition(
  587. idx, component,
  588. verifyConstraints=False,
  589. matchTags=False, matchConstraints=False
  590. )
  591. seenIndices.add(idx)
  592. idx += 1
  593. else:
  594. raise error.SubstrateUnderrunError(
  595. 'No EOO seen before substrate ends'
  596. )
  597. if LOG:
  598. LOG('seen component indices %s' % seenIndices)
  599. if namedTypes:
  600. if not namedTypes.requiredComponents.issubset(seenIndices):
  601. raise error.PyAsn1Error('ASN.1 object %s has uninitialized components' % asn1Object.__class__.__name__)
  602. if namedTypes.hasOpenTypes:
  603. openTypes = options.get('openTypes', {})
  604. if LOG:
  605. LOG('using open types map: %r' % openTypes)
  606. if openTypes or options.get('decodeOpenTypes', False):
  607. for idx, namedType in enumerate(namedTypes.namedTypes):
  608. if not namedType.openType:
  609. continue
  610. if namedType.isOptional and not asn1Object.getComponentByPosition(idx).isValue:
  611. continue
  612. governingValue = asn1Object.getComponentByName(
  613. namedType.openType.name
  614. )
  615. try:
  616. openType = openTypes[governingValue]
  617. except KeyError:
  618. try:
  619. openType = namedType.openType[governingValue]
  620. except KeyError:
  621. if LOG:
  622. LOG('failed to resolve open type by governing '
  623. 'value %r' % (governingValue,))
  624. continue
  625. if LOG:
  626. LOG('resolved open type %r by governing '
  627. 'value %r' % (openType, governingValue))
  628. containerValue = asn1Object.getComponentByPosition(idx)
  629. if containerValue.typeId in (
  630. univ.SetOf.typeId, univ.SequenceOf.typeId):
  631. for pos, containerElement in enumerate(
  632. containerValue):
  633. component, rest = decodeFun(
  634. containerValue[pos].asOctets(),
  635. asn1Spec=openType, **dict(options, allowEoo=True)
  636. )
  637. containerValue[pos] = component
  638. else:
  639. component, rest = decodeFun(
  640. asn1Object.getComponentByPosition(idx).asOctets(),
  641. asn1Spec=openType, **dict(options, allowEoo=True)
  642. )
  643. if component is not eoo.endOfOctets:
  644. asn1Object.setComponentByPosition(idx, component)
  645. else:
  646. inconsistency = asn1Object.isInconsistent
  647. if inconsistency:
  648. raise inconsistency
  649. else:
  650. asn1Object = asn1Spec.clone()
  651. asn1Object.clear()
  652. componentType = asn1Spec.componentType
  653. if LOG:
  654. LOG('decoding type %r chosen by given `asn1Spec`' % componentType)
  655. idx = 0
  656. while substrate:
  657. component, substrate = decodeFun(substrate, componentType, allowEoo=True, **options)
  658. if component is eoo.endOfOctets:
  659. break
  660. asn1Object.setComponentByPosition(
  661. idx, component,
  662. verifyConstraints=False,
  663. matchTags=False, matchConstraints=False
  664. )
  665. idx += 1
  666. else:
  667. raise error.SubstrateUnderrunError(
  668. 'No EOO seen before substrate ends'
  669. )
  670. return asn1Object, substrate
  671. class SequenceOrSequenceOfDecoder(UniversalConstructedTypeDecoder):
  672. protoRecordComponent = univ.Sequence()
  673. protoSequenceComponent = univ.SequenceOf()
  674. class SequenceDecoder(SequenceOrSequenceOfDecoder):
  675. protoComponent = univ.Sequence()
  676. class SequenceOfDecoder(SequenceOrSequenceOfDecoder):
  677. protoComponent = univ.SequenceOf()
  678. class SetOrSetOfDecoder(UniversalConstructedTypeDecoder):
  679. protoRecordComponent = univ.Set()
  680. protoSequenceComponent = univ.SetOf()
  681. class SetDecoder(SetOrSetOfDecoder):
  682. protoComponent = univ.Set()
  683. class SetOfDecoder(SetOrSetOfDecoder):
  684. protoComponent = univ.SetOf()
  685. class ChoiceDecoder(AbstractConstructedDecoder):
  686. protoComponent = univ.Choice()
  687. def valueDecoder(self, substrate, asn1Spec,
  688. tagSet=None, length=None, state=None,
  689. decodeFun=None, substrateFun=None,
  690. **options):
  691. head, tail = substrate[:length], substrate[length:]
  692. if asn1Spec is None:
  693. asn1Object = self.protoComponent.clone(tagSet=tagSet)
  694. else:
  695. asn1Object = asn1Spec.clone()
  696. if substrateFun:
  697. return substrateFun(asn1Object, substrate, length)
  698. if asn1Object.tagSet == tagSet:
  699. if LOG:
  700. LOG('decoding %s as explicitly tagged CHOICE' % (tagSet,))
  701. component, head = decodeFun(
  702. head, asn1Object.componentTagMap, **options
  703. )
  704. else:
  705. if LOG:
  706. LOG('decoding %s as untagged CHOICE' % (tagSet,))
  707. component, head = decodeFun(
  708. head, asn1Object.componentTagMap,
  709. tagSet, length, state, **options
  710. )
  711. effectiveTagSet = component.effectiveTagSet
  712. if LOG:
  713. LOG('decoded component %s, effective tag set %s' % (component, effectiveTagSet))
  714. asn1Object.setComponentByType(
  715. effectiveTagSet, component,
  716. verifyConstraints=False,
  717. matchTags=False, matchConstraints=False,
  718. innerFlag=False
  719. )
  720. return asn1Object, tail
  721. def indefLenValueDecoder(self, substrate, asn1Spec,
  722. tagSet=None, length=None, state=None,
  723. decodeFun=None, substrateFun=None,
  724. **options):
  725. if asn1Spec is None:
  726. asn1Object = self.protoComponent.clone(tagSet=tagSet)
  727. else:
  728. asn1Object = asn1Spec.clone()
  729. if substrateFun:
  730. return substrateFun(asn1Object, substrate, length)
  731. if asn1Object.tagSet == tagSet:
  732. if LOG:
  733. LOG('decoding %s as explicitly tagged CHOICE' % (tagSet,))
  734. component, substrate = decodeFun(
  735. substrate, asn1Object.componentType.tagMapUnique, **options
  736. )
  737. # eat up EOO marker
  738. eooMarker, substrate = decodeFun(
  739. substrate, allowEoo=True, **options
  740. )
  741. if eooMarker is not eoo.endOfOctets:
  742. raise error.PyAsn1Error('No EOO seen before substrate ends')
  743. else:
  744. if LOG:
  745. LOG('decoding %s as untagged CHOICE' % (tagSet,))
  746. component, substrate = decodeFun(
  747. substrate, asn1Object.componentType.tagMapUnique,
  748. tagSet, length, state, **options
  749. )
  750. effectiveTagSet = component.effectiveTagSet
  751. if LOG:
  752. LOG('decoded component %s, effective tag set %s' % (component, effectiveTagSet))
  753. asn1Object.setComponentByType(
  754. effectiveTagSet, component,
  755. verifyConstraints=False,
  756. matchTags=False, matchConstraints=False,
  757. innerFlag=False
  758. )
  759. return asn1Object, substrate
  760. class AnyDecoder(AbstractSimpleDecoder):
  761. protoComponent = univ.Any()
  762. def valueDecoder(self, substrate, asn1Spec,
  763. tagSet=None, length=None, state=None,
  764. decodeFun=None, substrateFun=None,
  765. **options):
  766. if asn1Spec is None:
  767. isUntagged = True
  768. elif asn1Spec.__class__ is tagmap.TagMap:
  769. isUntagged = tagSet not in asn1Spec.tagMap
  770. else:
  771. isUntagged = tagSet != asn1Spec.tagSet
  772. if isUntagged:
  773. fullSubstrate = options['fullSubstrate']
  774. # untagged Any container, recover inner header substrate
  775. length += len(fullSubstrate) - len(substrate)
  776. substrate = fullSubstrate
  777. if LOG:
  778. LOG('decoding as untagged ANY, substrate %s' % debug.hexdump(substrate))
  779. if substrateFun:
  780. return substrateFun(self._createComponent(asn1Spec, tagSet, noValue, **options),
  781. substrate, length)
  782. head, tail = substrate[:length], substrate[length:]
  783. return self._createComponent(asn1Spec, tagSet, head, **options), tail
  784. def indefLenValueDecoder(self, substrate, asn1Spec,
  785. tagSet=None, length=None, state=None,
  786. decodeFun=None, substrateFun=None,
  787. **options):
  788. if asn1Spec is None:
  789. isTagged = False
  790. elif asn1Spec.__class__ is tagmap.TagMap:
  791. isTagged = tagSet in asn1Spec.tagMap
  792. else:
  793. isTagged = tagSet == asn1Spec.tagSet
  794. if isTagged:
  795. # tagged Any type -- consume header substrate
  796. header = null
  797. if LOG:
  798. LOG('decoding as tagged ANY')
  799. else:
  800. fullSubstrate = options['fullSubstrate']
  801. # untagged Any, recover header substrate
  802. header = fullSubstrate[:-len(substrate)]
  803. if LOG:
  804. LOG('decoding as untagged ANY, header substrate %s' % debug.hexdump(header))
  805. # Any components do not inherit initial tag
  806. asn1Spec = self.protoComponent
  807. if substrateFun and substrateFun is not self.substrateCollector:
  808. asn1Object = self._createComponent(asn1Spec, tagSet, noValue, **options)
  809. return substrateFun(asn1Object, header + substrate, length + len(header))
  810. if LOG:
  811. LOG('assembling constructed serialization')
  812. # All inner fragments are of the same type, treat them as octet string
  813. substrateFun = self.substrateCollector
  814. while substrate:
  815. component, substrate = decodeFun(substrate, asn1Spec,
  816. substrateFun=substrateFun,
  817. allowEoo=True, **options)
  818. if component is eoo.endOfOctets:
  819. break
  820. header += component
  821. else:
  822. raise error.SubstrateUnderrunError(
  823. 'No EOO seen before substrate ends'
  824. )
  825. if substrateFun:
  826. return header, substrate
  827. else:
  828. return self._createComponent(asn1Spec, tagSet, header, **options), substrate
  829. # character string types
  830. class UTF8StringDecoder(OctetStringDecoder):
  831. protoComponent = char.UTF8String()
  832. class NumericStringDecoder(OctetStringDecoder):
  833. protoComponent = char.NumericString()
  834. class PrintableStringDecoder(OctetStringDecoder):
  835. protoComponent = char.PrintableString()
  836. class TeletexStringDecoder(OctetStringDecoder):
  837. protoComponent = char.TeletexString()
  838. class VideotexStringDecoder(OctetStringDecoder):
  839. protoComponent = char.VideotexString()
  840. class IA5StringDecoder(OctetStringDecoder):
  841. protoComponent = char.IA5String()
  842. class GraphicStringDecoder(OctetStringDecoder):
  843. protoComponent = char.GraphicString()
  844. class VisibleStringDecoder(OctetStringDecoder):
  845. protoComponent = char.VisibleString()
  846. class GeneralStringDecoder(OctetStringDecoder):
  847. protoComponent = char.GeneralString()
  848. class UniversalStringDecoder(OctetStringDecoder):
  849. protoComponent = char.UniversalString()
  850. class BMPStringDecoder(OctetStringDecoder):
  851. protoComponent = char.BMPString()
  852. # "useful" types
  853. class ObjectDescriptorDecoder(OctetStringDecoder):
  854. protoComponent = useful.ObjectDescriptor()
  855. class GeneralizedTimeDecoder(OctetStringDecoder):
  856. protoComponent = useful.GeneralizedTime()
  857. class UTCTimeDecoder(OctetStringDecoder):
  858. protoComponent = useful.UTCTime()
  859. tagMap = {
  860. univ.Integer.tagSet: IntegerDecoder(),
  861. univ.Boolean.tagSet: BooleanDecoder(),
  862. univ.BitString.tagSet: BitStringDecoder(),
  863. univ.OctetString.tagSet: OctetStringDecoder(),
  864. univ.Null.tagSet: NullDecoder(),
  865. univ.ObjectIdentifier.tagSet: ObjectIdentifierDecoder(),
  866. univ.Enumerated.tagSet: IntegerDecoder(),
  867. univ.Real.tagSet: RealDecoder(),
  868. univ.Sequence.tagSet: SequenceOrSequenceOfDecoder(), # conflicts with SequenceOf
  869. univ.Set.tagSet: SetOrSetOfDecoder(), # conflicts with SetOf
  870. univ.Choice.tagSet: ChoiceDecoder(), # conflicts with Any
  871. # character string types
  872. char.UTF8String.tagSet: UTF8StringDecoder(),
  873. char.NumericString.tagSet: NumericStringDecoder(),
  874. char.PrintableString.tagSet: PrintableStringDecoder(),
  875. char.TeletexString.tagSet: TeletexStringDecoder(),
  876. char.VideotexString.tagSet: VideotexStringDecoder(),
  877. char.IA5String.tagSet: IA5StringDecoder(),
  878. char.GraphicString.tagSet: GraphicStringDecoder(),
  879. char.VisibleString.tagSet: VisibleStringDecoder(),
  880. char.GeneralString.tagSet: GeneralStringDecoder(),
  881. char.UniversalString.tagSet: UniversalStringDecoder(),
  882. char.BMPString.tagSet: BMPStringDecoder(),
  883. # useful types
  884. useful.ObjectDescriptor.tagSet: ObjectDescriptorDecoder(),
  885. useful.GeneralizedTime.tagSet: GeneralizedTimeDecoder(),
  886. useful.UTCTime.tagSet: UTCTimeDecoder()
  887. }
  888. # Type-to-codec map for ambiguous ASN.1 types
  889. typeMap = {
  890. univ.Set.typeId: SetDecoder(),
  891. univ.SetOf.typeId: SetOfDecoder(),
  892. univ.Sequence.typeId: SequenceDecoder(),
  893. univ.SequenceOf.typeId: SequenceOfDecoder(),
  894. univ.Choice.typeId: ChoiceDecoder(),
  895. univ.Any.typeId: AnyDecoder()
  896. }
  897. # Put in non-ambiguous types for faster codec lookup
  898. for typeDecoder in tagMap.values():
  899. if typeDecoder.protoComponent is not None:
  900. typeId = typeDecoder.protoComponent.__class__.typeId
  901. if typeId is not None and typeId not in typeMap:
  902. typeMap[typeId] = typeDecoder
  903. (stDecodeTag,
  904. stDecodeLength,
  905. stGetValueDecoder,
  906. stGetValueDecoderByAsn1Spec,
  907. stGetValueDecoderByTag,
  908. stTryAsExplicitTag,
  909. stDecodeValue,
  910. stDumpRawValue,
  911. stErrorCondition,
  912. stStop) = [x for x in range(10)]
  913. class Decoder(object):
  914. defaultErrorState = stErrorCondition
  915. #defaultErrorState = stDumpRawValue
  916. defaultRawDecoder = AnyDecoder()
  917. supportIndefLength = True
  918. # noinspection PyDefaultArgument
  919. def __init__(self, tagMap, typeMap={}):
  920. self.__tagMap = tagMap
  921. self.__typeMap = typeMap
  922. # Tag & TagSet objects caches
  923. self.__tagCache = {}
  924. self.__tagSetCache = {}
  925. self.__eooSentinel = ints2octs((0, 0))
  926. def __call__(self, substrate, asn1Spec=None,
  927. tagSet=None, length=None, state=stDecodeTag,
  928. decodeFun=None, substrateFun=None,
  929. **options):
  930. if LOG:
  931. LOG('decoder called at scope %s with state %d, working with up to %d octets of substrate: %s' % (debug.scope, state, len(substrate), debug.hexdump(substrate)))
  932. allowEoo = options.pop('allowEoo', False)
  933. # Look for end-of-octets sentinel
  934. if allowEoo and self.supportIndefLength:
  935. if substrate[:2] == self.__eooSentinel:
  936. if LOG:
  937. LOG('end-of-octets sentinel found')
  938. return eoo.endOfOctets, substrate[2:]
  939. value = noValue
  940. tagMap = self.__tagMap
  941. typeMap = self.__typeMap
  942. tagCache = self.__tagCache
  943. tagSetCache = self.__tagSetCache
  944. fullSubstrate = substrate
  945. while state is not stStop:
  946. if state is stDecodeTag:
  947. if not substrate:
  948. raise error.SubstrateUnderrunError(
  949. 'Short octet stream on tag decoding'
  950. )
  951. # Decode tag
  952. isShortTag = True
  953. firstOctet = substrate[0]
  954. substrate = substrate[1:]
  955. try:
  956. lastTag = tagCache[firstOctet]
  957. except KeyError:
  958. integerTag = oct2int(firstOctet)
  959. tagClass = integerTag & 0xC0
  960. tagFormat = integerTag & 0x20
  961. tagId = integerTag & 0x1F
  962. if tagId == 0x1F:
  963. isShortTag = False
  964. lengthOctetIdx = 0
  965. tagId = 0
  966. try:
  967. while True:
  968. integerTag = oct2int(substrate[lengthOctetIdx])
  969. lengthOctetIdx += 1
  970. tagId <<= 7
  971. tagId |= (integerTag & 0x7F)
  972. if not integerTag & 0x80:
  973. break
  974. substrate = substrate[lengthOctetIdx:]
  975. except IndexError:
  976. raise error.SubstrateUnderrunError(
  977. 'Short octet stream on long tag decoding'
  978. )
  979. lastTag = tag.Tag(
  980. tagClass=tagClass, tagFormat=tagFormat, tagId=tagId
  981. )
  982. if isShortTag:
  983. # cache short tags
  984. tagCache[firstOctet] = lastTag
  985. if tagSet is None:
  986. if isShortTag:
  987. try:
  988. tagSet = tagSetCache[firstOctet]
  989. except KeyError:
  990. # base tag not recovered
  991. tagSet = tag.TagSet((), lastTag)
  992. tagSetCache[firstOctet] = tagSet
  993. else:
  994. tagSet = tag.TagSet((), lastTag)
  995. else:
  996. tagSet = lastTag + tagSet
  997. state = stDecodeLength
  998. if LOG:
  999. LOG('tag decoded into %s, decoding length' % tagSet)
  1000. if state is stDecodeLength:
  1001. # Decode length
  1002. if not substrate:
  1003. raise error.SubstrateUnderrunError(
  1004. 'Short octet stream on length decoding'
  1005. )
  1006. firstOctet = oct2int(substrate[0])
  1007. if firstOctet < 128:
  1008. size = 1
  1009. length = firstOctet
  1010. elif firstOctet > 128:
  1011. size = firstOctet & 0x7F
  1012. # encoded in size bytes
  1013. encodedLength = octs2ints(substrate[1:size + 1])
  1014. # missing check on maximum size, which shouldn't be a
  1015. # problem, we can handle more than is possible
  1016. if len(encodedLength) != size:
  1017. raise error.SubstrateUnderrunError(
  1018. '%s<%s at %s' % (size, len(encodedLength), tagSet)
  1019. )
  1020. length = 0
  1021. for lengthOctet in encodedLength:
  1022. length <<= 8
  1023. length |= lengthOctet
  1024. size += 1
  1025. else:
  1026. size = 1
  1027. length = -1
  1028. substrate = substrate[size:]
  1029. if length == -1:
  1030. if not self.supportIndefLength:
  1031. raise error.PyAsn1Error('Indefinite length encoding not supported by this codec')
  1032. else:
  1033. if len(substrate) < length:
  1034. raise error.SubstrateUnderrunError('%d-octet short' % (length - len(substrate)))
  1035. state = stGetValueDecoder
  1036. if LOG:
  1037. LOG('value length decoded into %d, payload substrate is: %s' % (length, debug.hexdump(length == -1 and substrate or substrate[:length])))
  1038. if state is stGetValueDecoder:
  1039. if asn1Spec is None:
  1040. state = stGetValueDecoderByTag
  1041. else:
  1042. state = stGetValueDecoderByAsn1Spec
  1043. #
  1044. # There're two ways of creating subtypes in ASN.1 what influences
  1045. # decoder operation. These methods are:
  1046. # 1) Either base types used in or no IMPLICIT tagging has been
  1047. # applied on subtyping.
  1048. # 2) Subtype syntax drops base type information (by means of
  1049. # IMPLICIT tagging.
  1050. # The first case allows for complete tag recovery from substrate
  1051. # while the second one requires original ASN.1 type spec for
  1052. # decoding.
  1053. #
  1054. # In either case a set of tags (tagSet) is coming from substrate
  1055. # in an incremental, tag-by-tag fashion (this is the case of
  1056. # EXPLICIT tag which is most basic). Outermost tag comes first
  1057. # from the wire.
  1058. #
  1059. if state is stGetValueDecoderByTag:
  1060. try:
  1061. concreteDecoder = tagMap[tagSet]
  1062. except KeyError:
  1063. concreteDecoder = None
  1064. if concreteDecoder:
  1065. state = stDecodeValue
  1066. else:
  1067. try:
  1068. concreteDecoder = tagMap[tagSet[:1]]
  1069. except KeyError:
  1070. concreteDecoder = None
  1071. if concreteDecoder:
  1072. state = stDecodeValue
  1073. else:
  1074. state = stTryAsExplicitTag
  1075. if LOG:
  1076. LOG('codec %s chosen by a built-in type, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "<none>", state is stDecodeValue and 'value' or 'as explicit tag'))
  1077. debug.scope.push(concreteDecoder is None and '?' or concreteDecoder.protoComponent.__class__.__name__)
  1078. if state is stGetValueDecoderByAsn1Spec:
  1079. if asn1Spec.__class__ is tagmap.TagMap:
  1080. try:
  1081. chosenSpec = asn1Spec[tagSet]
  1082. except KeyError:
  1083. chosenSpec = None
  1084. if LOG:
  1085. LOG('candidate ASN.1 spec is a map of:')
  1086. for firstOctet, v in asn1Spec.presentTypes.items():
  1087. LOG(' %s -> %s' % (firstOctet, v.__class__.__name__))
  1088. if asn1Spec.skipTypes:
  1089. LOG('but neither of: ')
  1090. for firstOctet, v in asn1Spec.skipTypes.items():
  1091. LOG(' %s -> %s' % (firstOctet, v.__class__.__name__))
  1092. LOG('new candidate ASN.1 spec is %s, chosen by %s' % (chosenSpec is None and '<none>' or chosenSpec.prettyPrintType(), tagSet))
  1093. elif tagSet == asn1Spec.tagSet or tagSet in asn1Spec.tagMap:
  1094. chosenSpec = asn1Spec
  1095. if LOG:
  1096. LOG('candidate ASN.1 spec is %s' % asn1Spec.__class__.__name__)
  1097. else:
  1098. chosenSpec = None
  1099. if chosenSpec is not None:
  1100. try:
  1101. # ambiguous type or just faster codec lookup
  1102. concreteDecoder = typeMap[chosenSpec.typeId]
  1103. if LOG:
  1104. LOG('value decoder chosen for an ambiguous type by type ID %s' % (chosenSpec.typeId,))
  1105. except KeyError:
  1106. # use base type for codec lookup to recover untagged types
  1107. baseTagSet = tag.TagSet(chosenSpec.tagSet.baseTag, chosenSpec.tagSet.baseTag)
  1108. try:
  1109. # base type or tagged subtype
  1110. concreteDecoder = tagMap[baseTagSet]
  1111. if LOG:
  1112. LOG('value decoder chosen by base %s' % (baseTagSet,))
  1113. except KeyError:
  1114. concreteDecoder = None
  1115. if concreteDecoder:
  1116. asn1Spec = chosenSpec
  1117. state = stDecodeValue
  1118. else:
  1119. state = stTryAsExplicitTag
  1120. else:
  1121. concreteDecoder = None
  1122. state = stTryAsExplicitTag
  1123. if LOG:
  1124. LOG('codec %s chosen by ASN.1 spec, decoding %s' % (state is stDecodeValue and concreteDecoder.__class__.__name__ or "<none>", state is stDecodeValue and 'value' or 'as explicit tag'))
  1125. debug.scope.push(chosenSpec is None and '?' or chosenSpec.__class__.__name__)
  1126. if state is stDecodeValue:
  1127. if not options.get('recursiveFlag', True) and not substrateFun: # deprecate this
  1128. substrateFun = lambda a, b, c: (a, b[:c])
  1129. options.update(fullSubstrate=fullSubstrate)
  1130. if length == -1: # indef length
  1131. value, substrate = concreteDecoder.indefLenValueDecoder(
  1132. substrate, asn1Spec,
  1133. tagSet, length, stGetValueDecoder,
  1134. self, substrateFun,
  1135. **options
  1136. )
  1137. else:
  1138. value, substrate = concreteDecoder.valueDecoder(
  1139. substrate, asn1Spec,
  1140. tagSet, length, stGetValueDecoder,
  1141. self, substrateFun,
  1142. **options
  1143. )
  1144. if LOG:
  1145. LOG('codec %s yields type %s, value:\n%s\n...remaining substrate is: %s' % (concreteDecoder.__class__.__name__, value.__class__.__name__, isinstance(value, base.Asn1Item) and value.prettyPrint() or value, substrate and debug.hexdump(substrate) or '<none>'))
  1146. state = stStop
  1147. break
  1148. if state is stTryAsExplicitTag:
  1149. if (tagSet and
  1150. tagSet[0].tagFormat == tag.tagFormatConstructed and
  1151. tagSet[0].tagClass != tag.tagClassUniversal):
  1152. # Assume explicit tagging
  1153. concreteDecoder = explicitTagDecoder
  1154. state = stDecodeValue
  1155. else:
  1156. concreteDecoder = None
  1157. state = self.defaultErrorState
  1158. if LOG:
  1159. LOG('codec %s chosen, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "<none>", state is stDecodeValue and 'value' or 'as failure'))
  1160. if state is stDumpRawValue:
  1161. concreteDecoder = self.defaultRawDecoder
  1162. if LOG:
  1163. LOG('codec %s chosen, decoding value' % concreteDecoder.__class__.__name__)
  1164. state = stDecodeValue
  1165. if state is stErrorCondition:
  1166. raise error.PyAsn1Error(
  1167. '%s not in asn1Spec: %r' % (tagSet, asn1Spec)
  1168. )
  1169. if LOG:
  1170. debug.scope.pop()
  1171. LOG('decoder left scope %s, call completed' % debug.scope)
  1172. return value, substrate
  1173. #: Turns BER octet stream into an ASN.1 object.
  1174. #:
  1175. #: Takes BER octet-stream and decode it into an ASN.1 object
  1176. #: (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which
  1177. #: may be a scalar or an arbitrary nested structure.
  1178. #:
  1179. #: Parameters
  1180. #: ----------
  1181. #: substrate: :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)
  1182. #: BER octet-stream
  1183. #:
  1184. #: Keyword Args
  1185. #: ------------
  1186. #: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
  1187. #: A pyasn1 type object to act as a template guiding the decoder. Depending on the ASN.1 structure
  1188. #: being decoded, *asn1Spec* may or may not be required. Most common reason for
  1189. #: it to require is that ASN.1 structure is encoded in *IMPLICIT* tagging mode.
  1190. #:
  1191. #: Returns
  1192. #: -------
  1193. #: : :py:class:`tuple`
  1194. #: A tuple of pyasn1 object recovered from BER substrate (:py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
  1195. #: and the unprocessed trailing portion of the *substrate* (may be empty)
  1196. #:
  1197. #: Raises
  1198. #: ------
  1199. #: ~pyasn1.error.PyAsn1Error, ~pyasn1.error.SubstrateUnderrunError
  1200. #: On decoding errors
  1201. #:
  1202. #: Examples
  1203. #: --------
  1204. #: Decode BER serialisation without ASN.1 schema
  1205. #:
  1206. #: .. code-block:: pycon
  1207. #:
  1208. #: >>> s, _ = decode(b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03')
  1209. #: >>> str(s)
  1210. #: SequenceOf:
  1211. #: 1 2 3
  1212. #:
  1213. #: Decode BER serialisation with ASN.1 schema
  1214. #:
  1215. #: .. code-block:: pycon
  1216. #:
  1217. #: >>> seq = SequenceOf(componentType=Integer())
  1218. #: >>> s, _ = decode(b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03', asn1Spec=seq)
  1219. #: >>> str(s)
  1220. #: SequenceOf:
  1221. #: 1 2 3
  1222. #:
  1223. decode = Decoder(tagMap, typeMap)
  1224. # XXX
  1225. # non-recursive decoding; return position rather than substrate