Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

decoder.py 51KB

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