decoder.py 79 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225
  1. #
  2. # This file is part of pyasn1 software.
  3. #
  4. # Copyright (c) 2005-2020, Ilya Etingof <etingof@gmail.com>
  5. # License: https://pyasn1.readthedocs.io/en/latest/license.html
  6. #
  7. import io
  8. import os
  9. import sys
  10. import warnings
  11. from pyasn1 import debug
  12. from pyasn1 import error
  13. from pyasn1.codec.ber import eoo
  14. from pyasn1.codec.streaming import asSeekableStream
  15. from pyasn1.codec.streaming import isEndOfStream
  16. from pyasn1.codec.streaming import peekIntoStream
  17. from pyasn1.codec.streaming import readFromStream
  18. from pyasn1.compat import _MISSING
  19. from pyasn1.error import PyAsn1Error
  20. from pyasn1.type import base
  21. from pyasn1.type import char
  22. from pyasn1.type import tag
  23. from pyasn1.type import tagmap
  24. from pyasn1.type import univ
  25. from pyasn1.type import useful
  26. __all__ = ['StreamingDecoder', 'Decoder', 'decode']
  27. LOG = debug.registerLoggee(__name__, flags=debug.DEBUG_DECODER)
  28. noValue = base.noValue
  29. SubstrateUnderrunError = error.SubstrateUnderrunError
  30. # Maximum number of continuation octets (high-bit set) allowed per OID arc.
  31. # 20 octets allows up to 140-bit integers, supporting UUID-based OIDs
  32. MAX_OID_ARC_CONTINUATION_OCTETS = 20
  33. MAX_NESTING_DEPTH = 100
  34. # Maximum number of bytes in a BER length field (8 bytes = up to 2^64-1)
  35. MAX_LENGTH_OCTETS = 8
  36. class AbstractPayloadDecoder(object):
  37. protoComponent = None
  38. def valueDecoder(self, substrate, asn1Spec,
  39. tagSet=None, length=None, state=None,
  40. decodeFun=None, substrateFun=None,
  41. **options):
  42. """Decode value with fixed byte length.
  43. The decoder is allowed to consume as many bytes as necessary.
  44. """
  45. raise error.PyAsn1Error('SingleItemDecoder not implemented for %s' % (tagSet,)) # TODO: Seems more like an NotImplementedError?
  46. def indefLenValueDecoder(self, substrate, asn1Spec,
  47. tagSet=None, length=None, state=None,
  48. decodeFun=None, substrateFun=None,
  49. **options):
  50. """Decode value with undefined length.
  51. The decoder is allowed to consume as many bytes as necessary.
  52. """
  53. raise error.PyAsn1Error('Indefinite length mode decoder not implemented for %s' % (tagSet,)) # TODO: Seems more like an NotImplementedError?
  54. @staticmethod
  55. def _passAsn1Object(asn1Object, options):
  56. if 'asn1Object' not in options:
  57. options['asn1Object'] = asn1Object
  58. return options
  59. class AbstractSimplePayloadDecoder(AbstractPayloadDecoder):
  60. @staticmethod
  61. def substrateCollector(asn1Object, substrate, length, options):
  62. for chunk in readFromStream(substrate, length, options):
  63. yield chunk
  64. def _createComponent(self, asn1Spec, tagSet, value, **options):
  65. if options.get('native'):
  66. return value
  67. elif asn1Spec is None:
  68. return self.protoComponent.clone(value, tagSet=tagSet)
  69. elif value is noValue:
  70. return asn1Spec
  71. else:
  72. return asn1Spec.clone(value)
  73. class RawPayloadDecoder(AbstractSimplePayloadDecoder):
  74. protoComponent = univ.Any('')
  75. def valueDecoder(self, substrate, asn1Spec,
  76. tagSet=None, length=None, state=None,
  77. decodeFun=None, substrateFun=None,
  78. **options):
  79. if substrateFun:
  80. asn1Object = self._createComponent(asn1Spec, tagSet, '', **options)
  81. for chunk in substrateFun(asn1Object, substrate, length, options):
  82. yield chunk
  83. return
  84. for value in decodeFun(substrate, asn1Spec, tagSet, length, **options):
  85. yield value
  86. def indefLenValueDecoder(self, substrate, asn1Spec,
  87. tagSet=None, length=None, state=None,
  88. decodeFun=None, substrateFun=None,
  89. **options):
  90. if substrateFun:
  91. asn1Object = self._createComponent(asn1Spec, tagSet, '', **options)
  92. for chunk in substrateFun(asn1Object, substrate, length, options):
  93. yield chunk
  94. return
  95. while True:
  96. for value in decodeFun(
  97. substrate, asn1Spec, tagSet, length,
  98. allowEoo=True, **options):
  99. if value is eoo.endOfOctets:
  100. return
  101. yield value
  102. rawPayloadDecoder = RawPayloadDecoder()
  103. class IntegerPayloadDecoder(AbstractSimplePayloadDecoder):
  104. protoComponent = univ.Integer(0)
  105. def valueDecoder(self, substrate, asn1Spec,
  106. tagSet=None, length=None, state=None,
  107. decodeFun=None, substrateFun=None,
  108. **options):
  109. if tagSet[0].tagFormat != tag.tagFormatSimple:
  110. raise error.PyAsn1Error('Simple tag format expected')
  111. for chunk in readFromStream(substrate, length, options):
  112. if isinstance(chunk, SubstrateUnderrunError):
  113. yield chunk
  114. if chunk:
  115. value = int.from_bytes(bytes(chunk), 'big', signed=True)
  116. else:
  117. value = 0
  118. yield self._createComponent(asn1Spec, tagSet, value, **options)
  119. class BooleanPayloadDecoder(IntegerPayloadDecoder):
  120. protoComponent = univ.Boolean(0)
  121. def _createComponent(self, asn1Spec, tagSet, value, **options):
  122. return IntegerPayloadDecoder._createComponent(
  123. self, asn1Spec, tagSet, value and 1 or 0, **options)
  124. class BitStringPayloadDecoder(AbstractSimplePayloadDecoder):
  125. protoComponent = univ.BitString(())
  126. supportConstructedForm = True
  127. def valueDecoder(self, substrate, asn1Spec,
  128. tagSet=None, length=None, state=None,
  129. decodeFun=None, substrateFun=None,
  130. **options):
  131. if substrateFun:
  132. asn1Object = self._createComponent(asn1Spec, tagSet, noValue, **options)
  133. for chunk in substrateFun(asn1Object, substrate, length, options):
  134. yield chunk
  135. return
  136. if not length:
  137. raise error.PyAsn1Error('Empty BIT STRING substrate')
  138. for chunk in isEndOfStream(substrate):
  139. if isinstance(chunk, SubstrateUnderrunError):
  140. yield chunk
  141. if chunk:
  142. raise error.PyAsn1Error('Empty BIT STRING substrate')
  143. if tagSet[0].tagFormat == tag.tagFormatSimple: # XXX what tag to check?
  144. for trailingBits in readFromStream(substrate, 1, options):
  145. if isinstance(trailingBits, SubstrateUnderrunError):
  146. yield trailingBits
  147. trailingBits = ord(trailingBits)
  148. if trailingBits > 7:
  149. raise error.PyAsn1Error(
  150. 'Trailing bits overflow %s' % trailingBits
  151. )
  152. for chunk in readFromStream(substrate, length - 1, options):
  153. if isinstance(chunk, SubstrateUnderrunError):
  154. yield chunk
  155. value = self.protoComponent.fromOctetString(
  156. chunk, internalFormat=True, padding=trailingBits)
  157. yield self._createComponent(asn1Spec, tagSet, value, **options)
  158. return
  159. if not self.supportConstructedForm:
  160. raise error.PyAsn1Error('Constructed encoding form prohibited '
  161. 'at %s' % self.__class__.__name__)
  162. if LOG:
  163. LOG('assembling constructed serialization')
  164. # All inner fragments are of the same type, treat them as octet string
  165. substrateFun = self.substrateCollector
  166. bitString = self.protoComponent.fromOctetString(b'', internalFormat=True)
  167. current_position = substrate.tell()
  168. while substrate.tell() - current_position < length:
  169. for component in decodeFun(
  170. substrate, self.protoComponent, substrateFun=substrateFun,
  171. **options):
  172. if isinstance(component, SubstrateUnderrunError):
  173. yield component
  174. trailingBits = component[0]
  175. if trailingBits > 7:
  176. raise error.PyAsn1Error(
  177. 'Trailing bits overflow %s' % trailingBits
  178. )
  179. bitString = self.protoComponent.fromOctetString(
  180. component[1:], internalFormat=True,
  181. prepend=bitString, padding=trailingBits
  182. )
  183. yield self._createComponent(asn1Spec, tagSet, bitString, **options)
  184. def indefLenValueDecoder(self, substrate, asn1Spec,
  185. tagSet=None, length=None, state=None,
  186. decodeFun=None, substrateFun=None,
  187. **options):
  188. if substrateFun:
  189. asn1Object = self._createComponent(asn1Spec, tagSet, noValue, **options)
  190. for chunk in substrateFun(asn1Object, substrate, length, options):
  191. yield chunk
  192. return
  193. # All inner fragments are of the same type, treat them as octet string
  194. substrateFun = self.substrateCollector
  195. bitString = self.protoComponent.fromOctetString(b'', internalFormat=True)
  196. while True: # loop over fragments
  197. for component in decodeFun(
  198. substrate, self.protoComponent, substrateFun=substrateFun,
  199. allowEoo=True, **options):
  200. if component is eoo.endOfOctets:
  201. break
  202. if isinstance(component, SubstrateUnderrunError):
  203. yield component
  204. if component is eoo.endOfOctets:
  205. break
  206. trailingBits = component[0]
  207. if trailingBits > 7:
  208. raise error.PyAsn1Error(
  209. 'Trailing bits overflow %s' % trailingBits
  210. )
  211. bitString = self.protoComponent.fromOctetString(
  212. component[1:], internalFormat=True,
  213. prepend=bitString, padding=trailingBits
  214. )
  215. yield self._createComponent(asn1Spec, tagSet, bitString, **options)
  216. class OctetStringPayloadDecoder(AbstractSimplePayloadDecoder):
  217. protoComponent = univ.OctetString('')
  218. supportConstructedForm = True
  219. def valueDecoder(self, substrate, asn1Spec,
  220. tagSet=None, length=None, state=None,
  221. decodeFun=None, substrateFun=None,
  222. **options):
  223. if substrateFun:
  224. asn1Object = self._createComponent(asn1Spec, tagSet, noValue, **options)
  225. for chunk in substrateFun(asn1Object, substrate, length, options):
  226. yield chunk
  227. return
  228. if tagSet[0].tagFormat == tag.tagFormatSimple: # XXX what tag to check?
  229. for chunk in readFromStream(substrate, length, options):
  230. if isinstance(chunk, SubstrateUnderrunError):
  231. yield chunk
  232. yield self._createComponent(asn1Spec, tagSet, chunk, **options)
  233. return
  234. if not self.supportConstructedForm:
  235. raise error.PyAsn1Error('Constructed encoding form prohibited at %s' % self.__class__.__name__)
  236. if LOG:
  237. LOG('assembling constructed serialization')
  238. # All inner fragments are of the same type, treat them as octet string
  239. substrateFun = self.substrateCollector
  240. header = b''
  241. original_position = substrate.tell()
  242. # head = popSubstream(substrate, length)
  243. while substrate.tell() - original_position < length:
  244. for component in decodeFun(
  245. substrate, self.protoComponent, substrateFun=substrateFun,
  246. **options):
  247. if isinstance(component, SubstrateUnderrunError):
  248. yield component
  249. header += component
  250. yield self._createComponent(asn1Spec, tagSet, header, **options)
  251. def indefLenValueDecoder(self, substrate, asn1Spec,
  252. tagSet=None, length=None, state=None,
  253. decodeFun=None, substrateFun=None,
  254. **options):
  255. if substrateFun and substrateFun is not self.substrateCollector:
  256. asn1Object = self._createComponent(asn1Spec, tagSet, noValue, **options)
  257. for chunk in substrateFun(asn1Object, substrate, length, options):
  258. yield chunk
  259. return
  260. # All inner fragments are of the same type, treat them as octet string
  261. substrateFun = self.substrateCollector
  262. header = b''
  263. while True: # loop over fragments
  264. for component in decodeFun(
  265. substrate, self.protoComponent, substrateFun=substrateFun,
  266. allowEoo=True, **options):
  267. if isinstance(component, SubstrateUnderrunError):
  268. yield component
  269. if component is eoo.endOfOctets:
  270. break
  271. if component is eoo.endOfOctets:
  272. break
  273. header += component
  274. yield self._createComponent(asn1Spec, tagSet, header, **options)
  275. class NullPayloadDecoder(AbstractSimplePayloadDecoder):
  276. protoComponent = univ.Null('')
  277. def valueDecoder(self, substrate, asn1Spec,
  278. tagSet=None, length=None, state=None,
  279. decodeFun=None, substrateFun=None,
  280. **options):
  281. if tagSet[0].tagFormat != tag.tagFormatSimple:
  282. raise error.PyAsn1Error('Simple tag format expected')
  283. for chunk in readFromStream(substrate, length, options):
  284. if isinstance(chunk, SubstrateUnderrunError):
  285. yield chunk
  286. component = self._createComponent(asn1Spec, tagSet, '', **options)
  287. if chunk:
  288. raise error.PyAsn1Error('Unexpected %d-octet substrate for Null' % length)
  289. yield component
  290. class ObjectIdentifierPayloadDecoder(AbstractSimplePayloadDecoder):
  291. protoComponent = univ.ObjectIdentifier(())
  292. def valueDecoder(self, substrate, asn1Spec,
  293. tagSet=None, length=None, state=None,
  294. decodeFun=None, substrateFun=None,
  295. **options):
  296. if tagSet[0].tagFormat != tag.tagFormatSimple:
  297. raise error.PyAsn1Error('Simple tag format expected')
  298. for chunk in readFromStream(substrate, length, options):
  299. if isinstance(chunk, SubstrateUnderrunError):
  300. yield chunk
  301. if not chunk:
  302. raise error.PyAsn1Error('Empty substrate')
  303. oid = ()
  304. index = 0
  305. substrateLen = len(chunk)
  306. while index < substrateLen:
  307. subId = chunk[index]
  308. index += 1
  309. if subId < 128:
  310. oid += (subId,)
  311. elif subId > 128:
  312. # Construct subid from a number of octets
  313. nextSubId = subId
  314. subId = 0
  315. continuationOctetCount = 0
  316. while nextSubId >= 128:
  317. continuationOctetCount += 1
  318. if continuationOctetCount > MAX_OID_ARC_CONTINUATION_OCTETS:
  319. raise error.PyAsn1Error(
  320. 'OID arc exceeds maximum continuation octets limit (%d) '
  321. 'at position %d' % (MAX_OID_ARC_CONTINUATION_OCTETS, index)
  322. )
  323. subId = (subId << 7) + (nextSubId & 0x7F)
  324. if index >= substrateLen:
  325. raise error.SubstrateUnderrunError(
  326. 'Short substrate for sub-OID past %s' % (oid,)
  327. )
  328. nextSubId = chunk[index]
  329. index += 1
  330. oid += ((subId << 7) + nextSubId,)
  331. elif subId == 128:
  332. # ASN.1 spec forbids leading zeros (0x80) in OID
  333. # encoding, tolerating it opens a vulnerability. See
  334. # https://www.esat.kuleuven.be/cosic/publications/article-1432.pdf
  335. # page 7
  336. raise error.PyAsn1Error('Invalid octet 0x80 in OID encoding')
  337. # Decode two leading arcs
  338. if 0 <= oid[0] <= 39:
  339. oid = (0,) + oid
  340. elif 40 <= oid[0] <= 79:
  341. oid = (1, oid[0] - 40) + oid[1:]
  342. elif oid[0] >= 80:
  343. oid = (2, oid[0] - 80) + oid[1:]
  344. else:
  345. raise error.PyAsn1Error('Malformed first OID octet: %s' % chunk[0])
  346. yield self._createComponent(asn1Spec, tagSet, oid, **options)
  347. class RelativeOIDPayloadDecoder(AbstractSimplePayloadDecoder):
  348. protoComponent = univ.RelativeOID(())
  349. def valueDecoder(self, substrate, asn1Spec,
  350. tagSet=None, length=None, state=None,
  351. decodeFun=None, substrateFun=None,
  352. **options):
  353. if tagSet[0].tagFormat != tag.tagFormatSimple:
  354. raise error.PyAsn1Error('Simple tag format expected')
  355. for chunk in readFromStream(substrate, length, options):
  356. if isinstance(chunk, SubstrateUnderrunError):
  357. yield chunk
  358. if not chunk:
  359. raise error.PyAsn1Error('Empty substrate')
  360. reloid = ()
  361. index = 0
  362. substrateLen = len(chunk)
  363. while index < substrateLen:
  364. subId = chunk[index]
  365. index += 1
  366. if subId < 128:
  367. reloid += (subId,)
  368. elif subId > 128:
  369. # Construct subid from a number of octets
  370. nextSubId = subId
  371. subId = 0
  372. continuationOctetCount = 0
  373. while nextSubId >= 128:
  374. continuationOctetCount += 1
  375. if continuationOctetCount > MAX_OID_ARC_CONTINUATION_OCTETS:
  376. raise error.PyAsn1Error(
  377. 'RELATIVE-OID arc exceeds maximum continuation octets limit (%d) '
  378. 'at position %d' % (MAX_OID_ARC_CONTINUATION_OCTETS, index)
  379. )
  380. subId = (subId << 7) + (nextSubId & 0x7F)
  381. if index >= substrateLen:
  382. raise error.SubstrateUnderrunError(
  383. 'Short substrate for sub-OID past %s' % (reloid,)
  384. )
  385. nextSubId = chunk[index]
  386. index += 1
  387. reloid += ((subId << 7) + nextSubId,)
  388. elif subId == 128:
  389. # ASN.1 spec forbids leading zeros (0x80) in OID
  390. # encoding, tolerating it opens a vulnerability. See
  391. # https://www.esat.kuleuven.be/cosic/publications/article-1432.pdf
  392. # page 7
  393. raise error.PyAsn1Error('Invalid octet 0x80 in RELATIVE-OID encoding')
  394. yield self._createComponent(asn1Spec, tagSet, reloid, **options)
  395. class RealPayloadDecoder(AbstractSimplePayloadDecoder):
  396. protoComponent = univ.Real()
  397. def valueDecoder(self, substrate, asn1Spec,
  398. tagSet=None, length=None, state=None,
  399. decodeFun=None, substrateFun=None,
  400. **options):
  401. if tagSet[0].tagFormat != tag.tagFormatSimple:
  402. raise error.PyAsn1Error('Simple tag format expected')
  403. for chunk in readFromStream(substrate, length, options):
  404. if isinstance(chunk, SubstrateUnderrunError):
  405. yield chunk
  406. if not chunk:
  407. yield self._createComponent(asn1Spec, tagSet, 0.0, **options)
  408. return
  409. fo = chunk[0]
  410. chunk = chunk[1:]
  411. if fo & 0x80: # binary encoding
  412. if not chunk:
  413. raise error.PyAsn1Error("Incomplete floating-point value")
  414. if LOG:
  415. LOG('decoding binary encoded REAL')
  416. n = (fo & 0x03) + 1
  417. if n == 4:
  418. n = chunk[0]
  419. chunk = chunk[1:]
  420. eo, chunk = chunk[:n], chunk[n:]
  421. if not eo or not chunk:
  422. raise error.PyAsn1Error('Real exponent screwed')
  423. e = eo[0] & 0x80 and -1 or 0
  424. while eo: # exponent
  425. e <<= 8
  426. e |= eo[0]
  427. eo = eo[1:]
  428. b = fo >> 4 & 0x03 # base bits
  429. if b > 2:
  430. raise error.PyAsn1Error('Illegal Real base')
  431. if b == 1: # encbase = 8
  432. e *= 3
  433. elif b == 2: # encbase = 16
  434. e *= 4
  435. p = 0
  436. while chunk: # value
  437. p <<= 8
  438. p |= chunk[0]
  439. chunk = chunk[1:]
  440. if fo & 0x40: # sign bit
  441. p = -p
  442. sf = fo >> 2 & 0x03 # scale bits
  443. p *= 2 ** sf
  444. value = (p, 2, e)
  445. elif fo & 0x40: # infinite value
  446. if LOG:
  447. LOG('decoding infinite REAL')
  448. value = fo & 0x01 and '-inf' or 'inf'
  449. elif fo & 0xc0 == 0: # character encoding
  450. if not chunk:
  451. raise error.PyAsn1Error("Incomplete floating-point value")
  452. if LOG:
  453. LOG('decoding character encoded REAL')
  454. try:
  455. if fo & 0x3 == 0x1: # NR1
  456. value = (int(chunk), 10, 0)
  457. elif fo & 0x3 == 0x2: # NR2
  458. value = float(chunk)
  459. elif fo & 0x3 == 0x3: # NR3
  460. value = float(chunk)
  461. else:
  462. raise error.SubstrateUnderrunError(
  463. 'Unknown NR (tag %s)' % fo
  464. )
  465. except ValueError:
  466. raise error.SubstrateUnderrunError(
  467. 'Bad character Real syntax'
  468. )
  469. else:
  470. raise error.SubstrateUnderrunError(
  471. 'Unknown encoding (tag %s)' % fo
  472. )
  473. yield self._createComponent(asn1Spec, tagSet, value, **options)
  474. class AbstractConstructedPayloadDecoder(AbstractPayloadDecoder):
  475. protoComponent = None
  476. class ConstructedPayloadDecoderBase(AbstractConstructedPayloadDecoder):
  477. protoRecordComponent = None
  478. protoSequenceComponent = None
  479. def _getComponentTagMap(self, asn1Object, idx):
  480. raise NotImplementedError
  481. def _getComponentPositionByType(self, asn1Object, tagSet, idx):
  482. raise NotImplementedError
  483. def _decodeComponentsSchemaless(
  484. self, substrate, tagSet=None, decodeFun=None,
  485. length=None, **options):
  486. asn1Object = None
  487. components = []
  488. componentTypes = set()
  489. original_position = substrate.tell()
  490. while length == -1 or substrate.tell() < original_position + length:
  491. for component in decodeFun(substrate, **options):
  492. if isinstance(component, SubstrateUnderrunError):
  493. yield component
  494. if length == -1 and component is eoo.endOfOctets:
  495. break
  496. components.append(component)
  497. componentTypes.add(component.tagSet)
  498. # Now we have to guess is it SEQUENCE/SET or SEQUENCE OF/SET OF
  499. # The heuristics is:
  500. # * 1+ components of different types -> likely SEQUENCE/SET
  501. # * otherwise -> likely SEQUENCE OF/SET OF
  502. if len(componentTypes) > 1:
  503. protoComponent = self.protoRecordComponent
  504. else:
  505. protoComponent = self.protoSequenceComponent
  506. asn1Object = protoComponent.clone(
  507. # construct tagSet from base tag from prototype ASN.1 object
  508. # and additional tags recovered from the substrate
  509. tagSet=tag.TagSet(protoComponent.tagSet.baseTag, *tagSet.superTags)
  510. )
  511. if LOG:
  512. LOG('guessed %r container type (pass `asn1Spec` to guide the '
  513. 'decoder)' % asn1Object)
  514. for idx, component in enumerate(components):
  515. asn1Object.setComponentByPosition(
  516. idx, component,
  517. verifyConstraints=False,
  518. matchTags=False, matchConstraints=False
  519. )
  520. yield asn1Object
  521. def valueDecoder(self, substrate, asn1Spec,
  522. tagSet=None, length=None, state=None,
  523. decodeFun=None, substrateFun=None,
  524. **options):
  525. if tagSet[0].tagFormat != tag.tagFormatConstructed:
  526. raise error.PyAsn1Error('Constructed tag format expected')
  527. original_position = substrate.tell()
  528. if substrateFun:
  529. if asn1Spec is not None:
  530. asn1Object = asn1Spec.clone()
  531. elif self.protoComponent is not None:
  532. asn1Object = self.protoComponent.clone(tagSet=tagSet)
  533. else:
  534. asn1Object = self.protoRecordComponent, self.protoSequenceComponent
  535. for chunk in substrateFun(asn1Object, substrate, length, options):
  536. yield chunk
  537. return
  538. if asn1Spec is None:
  539. for asn1Object in self._decodeComponentsSchemaless(
  540. substrate, tagSet=tagSet, decodeFun=decodeFun,
  541. length=length, **options):
  542. if isinstance(asn1Object, SubstrateUnderrunError):
  543. yield asn1Object
  544. if substrate.tell() < original_position + length:
  545. if LOG:
  546. for trailing in readFromStream(substrate, context=options):
  547. if isinstance(trailing, SubstrateUnderrunError):
  548. yield trailing
  549. LOG('Unused trailing %d octets encountered: %s' % (
  550. len(trailing), debug.hexdump(trailing)))
  551. yield asn1Object
  552. return
  553. asn1Object = asn1Spec.clone()
  554. asn1Object.clear()
  555. options = self._passAsn1Object(asn1Object, options)
  556. if asn1Spec.typeId in (univ.Sequence.typeId, univ.Set.typeId):
  557. namedTypes = asn1Spec.componentType
  558. isSetType = asn1Spec.typeId == univ.Set.typeId
  559. isDeterministic = not isSetType and not namedTypes.hasOptionalOrDefault
  560. if LOG:
  561. LOG('decoding %sdeterministic %s type %r chosen by type ID' % (
  562. not isDeterministic and 'non-' or '', isSetType and 'SET' or '',
  563. asn1Spec))
  564. seenIndices = set()
  565. idx = 0
  566. while substrate.tell() - original_position < length:
  567. if not namedTypes:
  568. componentType = None
  569. elif isSetType:
  570. componentType = namedTypes.tagMapUnique
  571. else:
  572. try:
  573. if isDeterministic:
  574. componentType = namedTypes[idx].asn1Object
  575. elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:
  576. componentType = namedTypes.getTagMapNearPosition(idx)
  577. else:
  578. componentType = namedTypes[idx].asn1Object
  579. except IndexError:
  580. raise error.PyAsn1Error(
  581. 'Excessive components decoded at %r' % (asn1Spec,)
  582. )
  583. for component in decodeFun(substrate, componentType, **options):
  584. if isinstance(component, SubstrateUnderrunError):
  585. yield component
  586. if not isDeterministic and namedTypes:
  587. if isSetType:
  588. idx = namedTypes.getPositionByType(component.effectiveTagSet)
  589. elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:
  590. idx = namedTypes.getPositionNearType(component.effectiveTagSet, idx)
  591. asn1Object.setComponentByPosition(
  592. idx, component,
  593. verifyConstraints=False,
  594. matchTags=False, matchConstraints=False
  595. )
  596. seenIndices.add(idx)
  597. idx += 1
  598. if LOG:
  599. LOG('seen component indices %s' % seenIndices)
  600. if namedTypes:
  601. if not namedTypes.requiredComponents.issubset(seenIndices):
  602. raise error.PyAsn1Error(
  603. 'ASN.1 object %s has uninitialized '
  604. 'components' % asn1Object.__class__.__name__)
  605. if namedTypes.hasOpenTypes:
  606. openTypes = options.get('openTypes', {})
  607. if LOG:
  608. LOG('user-specified open types map:')
  609. for k, v in openTypes.items():
  610. LOG('%s -> %r' % (k, v))
  611. if openTypes or options.get('decodeOpenTypes', False):
  612. for idx, namedType in enumerate(namedTypes.namedTypes):
  613. if not namedType.openType:
  614. continue
  615. if namedType.isOptional and not asn1Object.getComponentByPosition(idx).isValue:
  616. continue
  617. governingValue = asn1Object.getComponentByName(
  618. namedType.openType.name
  619. )
  620. try:
  621. openType = openTypes[governingValue]
  622. except KeyError:
  623. if LOG:
  624. LOG('default open types map of component '
  625. '"%s.%s" governed by component "%s.%s"'
  626. ':' % (asn1Object.__class__.__name__,
  627. namedType.name,
  628. asn1Object.__class__.__name__,
  629. namedType.openType.name))
  630. for k, v in namedType.openType.items():
  631. LOG('%s -> %r' % (k, v))
  632. try:
  633. openType = namedType.openType[governingValue]
  634. except KeyError:
  635. if LOG:
  636. LOG('failed to resolve open type by governing '
  637. 'value %r' % (governingValue,))
  638. continue
  639. if LOG:
  640. LOG('resolved open type %r by governing '
  641. 'value %r' % (openType, governingValue))
  642. containerValue = asn1Object.getComponentByPosition(idx)
  643. if containerValue.typeId in (
  644. univ.SetOf.typeId, univ.SequenceOf.typeId):
  645. for pos, containerElement in enumerate(
  646. containerValue):
  647. stream = asSeekableStream(containerValue[pos].asOctets())
  648. for component in decodeFun(stream, asn1Spec=openType, **options):
  649. if isinstance(component, SubstrateUnderrunError):
  650. yield component
  651. containerValue[pos] = component
  652. else:
  653. stream = asSeekableStream(asn1Object.getComponentByPosition(idx).asOctets())
  654. for component in decodeFun(stream, asn1Spec=openType, **options):
  655. if isinstance(component, SubstrateUnderrunError):
  656. yield component
  657. asn1Object.setComponentByPosition(idx, component)
  658. else:
  659. inconsistency = asn1Object.isInconsistent
  660. if inconsistency:
  661. raise error.PyAsn1Error(
  662. f"ASN.1 object {asn1Object.__class__.__name__} is inconsistent")
  663. else:
  664. componentType = asn1Spec.componentType
  665. if LOG:
  666. LOG('decoding type %r chosen by given `asn1Spec`' % componentType)
  667. idx = 0
  668. while substrate.tell() - original_position < length:
  669. for component in decodeFun(substrate, componentType, **options):
  670. if isinstance(component, SubstrateUnderrunError):
  671. yield component
  672. asn1Object.setComponentByPosition(
  673. idx, component,
  674. verifyConstraints=False,
  675. matchTags=False, matchConstraints=False
  676. )
  677. idx += 1
  678. yield asn1Object
  679. def indefLenValueDecoder(self, substrate, asn1Spec,
  680. tagSet=None, length=None, state=None,
  681. decodeFun=None, substrateFun=None,
  682. **options):
  683. if tagSet[0].tagFormat != tag.tagFormatConstructed:
  684. raise error.PyAsn1Error('Constructed tag format expected')
  685. if substrateFun is not None:
  686. if asn1Spec is not None:
  687. asn1Object = asn1Spec.clone()
  688. elif self.protoComponent is not None:
  689. asn1Object = self.protoComponent.clone(tagSet=tagSet)
  690. else:
  691. asn1Object = self.protoRecordComponent, self.protoSequenceComponent
  692. for chunk in substrateFun(asn1Object, substrate, length, options):
  693. yield chunk
  694. return
  695. if asn1Spec is None:
  696. for asn1Object in self._decodeComponentsSchemaless(
  697. substrate, tagSet=tagSet, decodeFun=decodeFun,
  698. length=length, **dict(options, allowEoo=True)):
  699. if isinstance(asn1Object, SubstrateUnderrunError):
  700. yield asn1Object
  701. yield asn1Object
  702. return
  703. asn1Object = asn1Spec.clone()
  704. asn1Object.clear()
  705. options = self._passAsn1Object(asn1Object, options)
  706. if asn1Spec.typeId in (univ.Sequence.typeId, univ.Set.typeId):
  707. namedTypes = asn1Object.componentType
  708. isSetType = asn1Object.typeId == univ.Set.typeId
  709. isDeterministic = not isSetType and not namedTypes.hasOptionalOrDefault
  710. if LOG:
  711. LOG('decoding %sdeterministic %s type %r chosen by type ID' % (
  712. not isDeterministic and 'non-' or '', isSetType and 'SET' or '',
  713. asn1Spec))
  714. seenIndices = set()
  715. idx = 0
  716. while True: # loop over components
  717. if len(namedTypes) <= idx:
  718. asn1Spec = None
  719. elif isSetType:
  720. asn1Spec = namedTypes.tagMapUnique
  721. else:
  722. try:
  723. if isDeterministic:
  724. asn1Spec = namedTypes[idx].asn1Object
  725. elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:
  726. asn1Spec = namedTypes.getTagMapNearPosition(idx)
  727. else:
  728. asn1Spec = namedTypes[idx].asn1Object
  729. except IndexError:
  730. raise error.PyAsn1Error(
  731. 'Excessive components decoded at %r' % (asn1Object,)
  732. )
  733. for component in decodeFun(substrate, asn1Spec, allowEoo=True, **options):
  734. if isinstance(component, SubstrateUnderrunError):
  735. yield component
  736. if component is eoo.endOfOctets:
  737. break
  738. if component is eoo.endOfOctets:
  739. break
  740. if not isDeterministic and namedTypes:
  741. if isSetType:
  742. idx = namedTypes.getPositionByType(component.effectiveTagSet)
  743. elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:
  744. idx = namedTypes.getPositionNearType(component.effectiveTagSet, idx)
  745. asn1Object.setComponentByPosition(
  746. idx, component,
  747. verifyConstraints=False,
  748. matchTags=False, matchConstraints=False
  749. )
  750. seenIndices.add(idx)
  751. idx += 1
  752. if LOG:
  753. LOG('seen component indices %s' % seenIndices)
  754. if namedTypes:
  755. if not namedTypes.requiredComponents.issubset(seenIndices):
  756. raise error.PyAsn1Error(
  757. 'ASN.1 object %s has uninitialized '
  758. 'components' % asn1Object.__class__.__name__)
  759. if namedTypes.hasOpenTypes:
  760. openTypes = options.get('openTypes', {})
  761. if LOG:
  762. LOG('user-specified open types map:')
  763. for k, v in openTypes.items():
  764. LOG('%s -> %r' % (k, v))
  765. if openTypes or options.get('decodeOpenTypes', False):
  766. for idx, namedType in enumerate(namedTypes.namedTypes):
  767. if not namedType.openType:
  768. continue
  769. if namedType.isOptional and not asn1Object.getComponentByPosition(idx).isValue:
  770. continue
  771. governingValue = asn1Object.getComponentByName(
  772. namedType.openType.name
  773. )
  774. try:
  775. openType = openTypes[governingValue]
  776. except KeyError:
  777. if LOG:
  778. LOG('default open types map of component '
  779. '"%s.%s" governed by component "%s.%s"'
  780. ':' % (asn1Object.__class__.__name__,
  781. namedType.name,
  782. asn1Object.__class__.__name__,
  783. namedType.openType.name))
  784. for k, v in namedType.openType.items():
  785. LOG('%s -> %r' % (k, v))
  786. try:
  787. openType = namedType.openType[governingValue]
  788. except KeyError:
  789. if LOG:
  790. LOG('failed to resolve open type by governing '
  791. 'value %r' % (governingValue,))
  792. continue
  793. if LOG:
  794. LOG('resolved open type %r by governing '
  795. 'value %r' % (openType, governingValue))
  796. containerValue = asn1Object.getComponentByPosition(idx)
  797. if containerValue.typeId in (
  798. univ.SetOf.typeId, univ.SequenceOf.typeId):
  799. for pos, containerElement in enumerate(
  800. containerValue):
  801. stream = asSeekableStream(containerValue[pos].asOctets())
  802. for component in decodeFun(stream, asn1Spec=openType,
  803. **dict(options, allowEoo=True)):
  804. if isinstance(component, SubstrateUnderrunError):
  805. yield component
  806. if component is eoo.endOfOctets:
  807. break
  808. containerValue[pos] = component
  809. else:
  810. stream = asSeekableStream(asn1Object.getComponentByPosition(idx).asOctets())
  811. for component in decodeFun(stream, asn1Spec=openType,
  812. **dict(options, allowEoo=True)):
  813. if isinstance(component, SubstrateUnderrunError):
  814. yield component
  815. if component is eoo.endOfOctets:
  816. break
  817. asn1Object.setComponentByPosition(idx, component)
  818. else:
  819. inconsistency = asn1Object.isInconsistent
  820. if inconsistency:
  821. raise error.PyAsn1Error(
  822. f"ASN.1 object {asn1Object.__class__.__name__} is inconsistent")
  823. else:
  824. componentType = asn1Spec.componentType
  825. if LOG:
  826. LOG('decoding type %r chosen by given `asn1Spec`' % componentType)
  827. idx = 0
  828. while True:
  829. for component in decodeFun(
  830. substrate, componentType, allowEoo=True, **options):
  831. if isinstance(component, SubstrateUnderrunError):
  832. yield component
  833. if component is eoo.endOfOctets:
  834. break
  835. if component is eoo.endOfOctets:
  836. break
  837. asn1Object.setComponentByPosition(
  838. idx, component,
  839. verifyConstraints=False,
  840. matchTags=False, matchConstraints=False
  841. )
  842. idx += 1
  843. yield asn1Object
  844. class SequenceOrSequenceOfPayloadDecoder(ConstructedPayloadDecoderBase):
  845. protoRecordComponent = univ.Sequence()
  846. protoSequenceComponent = univ.SequenceOf()
  847. class SequencePayloadDecoder(SequenceOrSequenceOfPayloadDecoder):
  848. protoComponent = univ.Sequence()
  849. class SequenceOfPayloadDecoder(SequenceOrSequenceOfPayloadDecoder):
  850. protoComponent = univ.SequenceOf()
  851. class SetOrSetOfPayloadDecoder(ConstructedPayloadDecoderBase):
  852. protoRecordComponent = univ.Set()
  853. protoSequenceComponent = univ.SetOf()
  854. class SetPayloadDecoder(SetOrSetOfPayloadDecoder):
  855. protoComponent = univ.Set()
  856. class SetOfPayloadDecoder(SetOrSetOfPayloadDecoder):
  857. protoComponent = univ.SetOf()
  858. class ChoicePayloadDecoder(ConstructedPayloadDecoderBase):
  859. protoComponent = univ.Choice()
  860. def valueDecoder(self, substrate, asn1Spec,
  861. tagSet=None, length=None, state=None,
  862. decodeFun=None, substrateFun=None,
  863. **options):
  864. if asn1Spec is None:
  865. asn1Object = self.protoComponent.clone(tagSet=tagSet)
  866. else:
  867. asn1Object = asn1Spec.clone()
  868. if substrateFun:
  869. for chunk in substrateFun(asn1Object, substrate, length, options):
  870. yield chunk
  871. return
  872. options = self._passAsn1Object(asn1Object, options)
  873. if asn1Object.tagSet == tagSet:
  874. if LOG:
  875. LOG('decoding %s as explicitly tagged CHOICE' % (tagSet,))
  876. for component in decodeFun(
  877. substrate, asn1Object.componentTagMap, **options):
  878. if isinstance(component, SubstrateUnderrunError):
  879. yield component
  880. else:
  881. if LOG:
  882. LOG('decoding %s as untagged CHOICE' % (tagSet,))
  883. for component in decodeFun(
  884. substrate, asn1Object.componentTagMap, tagSet, length,
  885. state, **options):
  886. if isinstance(component, SubstrateUnderrunError):
  887. yield component
  888. effectiveTagSet = component.effectiveTagSet
  889. if LOG:
  890. LOG('decoded component %s, effective tag set %s' % (component, effectiveTagSet))
  891. asn1Object.setComponentByType(
  892. effectiveTagSet, component,
  893. verifyConstraints=False,
  894. matchTags=False, matchConstraints=False,
  895. innerFlag=False
  896. )
  897. yield asn1Object
  898. def indefLenValueDecoder(self, substrate, asn1Spec,
  899. tagSet=None, length=None, state=None,
  900. decodeFun=None, substrateFun=None,
  901. **options):
  902. if asn1Spec is None:
  903. asn1Object = self.protoComponent.clone(tagSet=tagSet)
  904. else:
  905. asn1Object = asn1Spec.clone()
  906. if substrateFun:
  907. for chunk in substrateFun(asn1Object, substrate, length, options):
  908. yield chunk
  909. return
  910. options = self._passAsn1Object(asn1Object, options)
  911. isTagged = asn1Object.tagSet == tagSet
  912. if LOG:
  913. LOG('decoding %s as %stagged CHOICE' % (
  914. tagSet, isTagged and 'explicitly ' or 'un'))
  915. while True:
  916. if isTagged:
  917. iterator = decodeFun(
  918. substrate, asn1Object.componentType.tagMapUnique,
  919. **dict(options, allowEoo=True))
  920. else:
  921. iterator = decodeFun(
  922. substrate, asn1Object.componentType.tagMapUnique,
  923. tagSet, length, state, **dict(options, allowEoo=True))
  924. for component in iterator:
  925. if isinstance(component, SubstrateUnderrunError):
  926. yield component
  927. if component is eoo.endOfOctets:
  928. break
  929. effectiveTagSet = component.effectiveTagSet
  930. if LOG:
  931. LOG('decoded component %s, effective tag set '
  932. '%s' % (component, effectiveTagSet))
  933. asn1Object.setComponentByType(
  934. effectiveTagSet, component,
  935. verifyConstraints=False,
  936. matchTags=False, matchConstraints=False,
  937. innerFlag=False
  938. )
  939. if not isTagged:
  940. break
  941. if not isTagged or component is eoo.endOfOctets:
  942. break
  943. yield asn1Object
  944. class AnyPayloadDecoder(AbstractSimplePayloadDecoder):
  945. protoComponent = univ.Any()
  946. def valueDecoder(self, substrate, asn1Spec,
  947. tagSet=None, length=None, state=None,
  948. decodeFun=None, substrateFun=None,
  949. **options):
  950. if asn1Spec is None:
  951. isUntagged = True
  952. elif asn1Spec.__class__ is tagmap.TagMap:
  953. isUntagged = tagSet not in asn1Spec.tagMap
  954. else:
  955. isUntagged = tagSet != asn1Spec.tagSet
  956. if isUntagged:
  957. fullPosition = substrate.markedPosition
  958. currentPosition = substrate.tell()
  959. substrate.seek(fullPosition, os.SEEK_SET)
  960. length += currentPosition - fullPosition
  961. if LOG:
  962. for chunk in peekIntoStream(substrate, length):
  963. if isinstance(chunk, SubstrateUnderrunError):
  964. yield chunk
  965. LOG('decoding as untagged ANY, substrate '
  966. '%s' % debug.hexdump(chunk))
  967. if substrateFun:
  968. for chunk in substrateFun(
  969. self._createComponent(asn1Spec, tagSet, noValue, **options),
  970. substrate, length, options):
  971. yield chunk
  972. return
  973. for chunk in readFromStream(substrate, length, options):
  974. if isinstance(chunk, SubstrateUnderrunError):
  975. yield chunk
  976. yield self._createComponent(asn1Spec, tagSet, chunk, **options)
  977. def indefLenValueDecoder(self, substrate, asn1Spec,
  978. tagSet=None, length=None, state=None,
  979. decodeFun=None, substrateFun=None,
  980. **options):
  981. if asn1Spec is None:
  982. isTagged = False
  983. elif asn1Spec.__class__ is tagmap.TagMap:
  984. isTagged = tagSet in asn1Spec.tagMap
  985. else:
  986. isTagged = tagSet == asn1Spec.tagSet
  987. if isTagged:
  988. # tagged Any type -- consume header substrate
  989. chunk = b''
  990. if LOG:
  991. LOG('decoding as tagged ANY')
  992. else:
  993. # TODO: Seems not to be tested
  994. fullPosition = substrate.markedPosition
  995. currentPosition = substrate.tell()
  996. substrate.seek(fullPosition, os.SEEK_SET)
  997. for chunk in readFromStream(substrate, currentPosition - fullPosition, options):
  998. if isinstance(chunk, SubstrateUnderrunError):
  999. yield chunk
  1000. if LOG:
  1001. LOG('decoding as untagged ANY, header substrate %s' % debug.hexdump(chunk))
  1002. # Any components do not inherit initial tag
  1003. asn1Spec = self.protoComponent
  1004. if substrateFun and substrateFun is not self.substrateCollector:
  1005. asn1Object = self._createComponent(
  1006. asn1Spec, tagSet, noValue, **options)
  1007. for chunk in substrateFun(
  1008. asn1Object, chunk + substrate, length + len(chunk), options):
  1009. yield chunk
  1010. return
  1011. if LOG:
  1012. LOG('assembling constructed serialization')
  1013. # All inner fragments are of the same type, treat them as octet string
  1014. substrateFun = self.substrateCollector
  1015. while True: # loop over fragments
  1016. for component in decodeFun(
  1017. substrate, asn1Spec, substrateFun=substrateFun,
  1018. allowEoo=True, **options):
  1019. if isinstance(component, SubstrateUnderrunError):
  1020. yield component
  1021. if component is eoo.endOfOctets:
  1022. break
  1023. if component is eoo.endOfOctets:
  1024. break
  1025. chunk += component
  1026. if substrateFun:
  1027. yield chunk # TODO: Weird
  1028. else:
  1029. yield self._createComponent(asn1Spec, tagSet, chunk, **options)
  1030. # character string types
  1031. class UTF8StringPayloadDecoder(OctetStringPayloadDecoder):
  1032. protoComponent = char.UTF8String()
  1033. class NumericStringPayloadDecoder(OctetStringPayloadDecoder):
  1034. protoComponent = char.NumericString()
  1035. class PrintableStringPayloadDecoder(OctetStringPayloadDecoder):
  1036. protoComponent = char.PrintableString()
  1037. class TeletexStringPayloadDecoder(OctetStringPayloadDecoder):
  1038. protoComponent = char.TeletexString()
  1039. class VideotexStringPayloadDecoder(OctetStringPayloadDecoder):
  1040. protoComponent = char.VideotexString()
  1041. class IA5StringPayloadDecoder(OctetStringPayloadDecoder):
  1042. protoComponent = char.IA5String()
  1043. class GraphicStringPayloadDecoder(OctetStringPayloadDecoder):
  1044. protoComponent = char.GraphicString()
  1045. class VisibleStringPayloadDecoder(OctetStringPayloadDecoder):
  1046. protoComponent = char.VisibleString()
  1047. class GeneralStringPayloadDecoder(OctetStringPayloadDecoder):
  1048. protoComponent = char.GeneralString()
  1049. class UniversalStringPayloadDecoder(OctetStringPayloadDecoder):
  1050. protoComponent = char.UniversalString()
  1051. class BMPStringPayloadDecoder(OctetStringPayloadDecoder):
  1052. protoComponent = char.BMPString()
  1053. # "useful" types
  1054. class ObjectDescriptorPayloadDecoder(OctetStringPayloadDecoder):
  1055. protoComponent = useful.ObjectDescriptor()
  1056. class GeneralizedTimePayloadDecoder(OctetStringPayloadDecoder):
  1057. protoComponent = useful.GeneralizedTime()
  1058. class UTCTimePayloadDecoder(OctetStringPayloadDecoder):
  1059. protoComponent = useful.UTCTime()
  1060. TAG_MAP = {
  1061. univ.Integer.tagSet: IntegerPayloadDecoder(),
  1062. univ.Boolean.tagSet: BooleanPayloadDecoder(),
  1063. univ.BitString.tagSet: BitStringPayloadDecoder(),
  1064. univ.OctetString.tagSet: OctetStringPayloadDecoder(),
  1065. univ.Null.tagSet: NullPayloadDecoder(),
  1066. univ.ObjectIdentifier.tagSet: ObjectIdentifierPayloadDecoder(),
  1067. univ.RelativeOID.tagSet: RelativeOIDPayloadDecoder(),
  1068. univ.Enumerated.tagSet: IntegerPayloadDecoder(),
  1069. univ.Real.tagSet: RealPayloadDecoder(),
  1070. univ.Sequence.tagSet: SequenceOrSequenceOfPayloadDecoder(), # conflicts with SequenceOf
  1071. univ.Set.tagSet: SetOrSetOfPayloadDecoder(), # conflicts with SetOf
  1072. univ.Choice.tagSet: ChoicePayloadDecoder(), # conflicts with Any
  1073. # character string types
  1074. char.UTF8String.tagSet: UTF8StringPayloadDecoder(),
  1075. char.NumericString.tagSet: NumericStringPayloadDecoder(),
  1076. char.PrintableString.tagSet: PrintableStringPayloadDecoder(),
  1077. char.TeletexString.tagSet: TeletexStringPayloadDecoder(),
  1078. char.VideotexString.tagSet: VideotexStringPayloadDecoder(),
  1079. char.IA5String.tagSet: IA5StringPayloadDecoder(),
  1080. char.GraphicString.tagSet: GraphicStringPayloadDecoder(),
  1081. char.VisibleString.tagSet: VisibleStringPayloadDecoder(),
  1082. char.GeneralString.tagSet: GeneralStringPayloadDecoder(),
  1083. char.UniversalString.tagSet: UniversalStringPayloadDecoder(),
  1084. char.BMPString.tagSet: BMPStringPayloadDecoder(),
  1085. # useful types
  1086. useful.ObjectDescriptor.tagSet: ObjectDescriptorPayloadDecoder(),
  1087. useful.GeneralizedTime.tagSet: GeneralizedTimePayloadDecoder(),
  1088. useful.UTCTime.tagSet: UTCTimePayloadDecoder()
  1089. }
  1090. # Type-to-codec map for ambiguous ASN.1 types
  1091. TYPE_MAP = {
  1092. univ.Set.typeId: SetPayloadDecoder(),
  1093. univ.SetOf.typeId: SetOfPayloadDecoder(),
  1094. univ.Sequence.typeId: SequencePayloadDecoder(),
  1095. univ.SequenceOf.typeId: SequenceOfPayloadDecoder(),
  1096. univ.Choice.typeId: ChoicePayloadDecoder(),
  1097. univ.Any.typeId: AnyPayloadDecoder()
  1098. }
  1099. # Put in non-ambiguous types for faster codec lookup
  1100. for typeDecoder in TAG_MAP.values():
  1101. if typeDecoder.protoComponent is not None:
  1102. typeId = typeDecoder.protoComponent.__class__.typeId
  1103. if typeId is not None and typeId not in TYPE_MAP:
  1104. TYPE_MAP[typeId] = typeDecoder
  1105. (stDecodeTag,
  1106. stDecodeLength,
  1107. stGetValueDecoder,
  1108. stGetValueDecoderByAsn1Spec,
  1109. stGetValueDecoderByTag,
  1110. stTryAsExplicitTag,
  1111. stDecodeValue,
  1112. stDumpRawValue,
  1113. stErrorCondition,
  1114. stStop) = [x for x in range(10)]
  1115. EOO_SENTINEL = bytes((0, 0))
  1116. class SingleItemDecoder(object):
  1117. defaultErrorState = stErrorCondition
  1118. #defaultErrorState = stDumpRawValue
  1119. defaultRawDecoder = AnyPayloadDecoder()
  1120. supportIndefLength = True
  1121. TAG_MAP = TAG_MAP
  1122. TYPE_MAP = TYPE_MAP
  1123. def __init__(self, tagMap=_MISSING, typeMap=_MISSING, **ignored):
  1124. self._tagMap = tagMap if tagMap is not _MISSING else self.TAG_MAP
  1125. self._typeMap = typeMap if typeMap is not _MISSING else self.TYPE_MAP
  1126. # Tag & TagSet objects caches
  1127. self._tagCache = {}
  1128. self._tagSetCache = {}
  1129. def __call__(self, substrate, asn1Spec=None,
  1130. tagSet=None, length=None, state=stDecodeTag,
  1131. decodeFun=None, substrateFun=None,
  1132. **options):
  1133. _nestingLevel = options.get('_nestingLevel', 0)
  1134. if _nestingLevel > MAX_NESTING_DEPTH:
  1135. raise error.PyAsn1Error(
  1136. 'ASN.1 structure nesting depth exceeds limit (%d)' % MAX_NESTING_DEPTH
  1137. )
  1138. options['_nestingLevel'] = _nestingLevel + 1
  1139. allowEoo = options.pop('allowEoo', False)
  1140. if LOG:
  1141. LOG('decoder called at scope %s with state %d, working with up '
  1142. 'to %s octets of substrate: '
  1143. '%s' % (debug.scope, state, length, substrate))
  1144. # Look for end-of-octets sentinel
  1145. if allowEoo and self.supportIndefLength:
  1146. for eoo_candidate in readFromStream(substrate, 2, options):
  1147. if isinstance(eoo_candidate, SubstrateUnderrunError):
  1148. yield eoo_candidate
  1149. if eoo_candidate == EOO_SENTINEL:
  1150. if LOG:
  1151. LOG('end-of-octets sentinel found')
  1152. yield eoo.endOfOctets
  1153. return
  1154. else:
  1155. substrate.seek(-2, os.SEEK_CUR)
  1156. tagMap = self._tagMap
  1157. typeMap = self._typeMap
  1158. tagCache = self._tagCache
  1159. tagSetCache = self._tagSetCache
  1160. value = noValue
  1161. substrate.markedPosition = substrate.tell()
  1162. while state is not stStop:
  1163. if state is stDecodeTag:
  1164. # Decode tag
  1165. isShortTag = True
  1166. for firstByte in readFromStream(substrate, 1, options):
  1167. if isinstance(firstByte, SubstrateUnderrunError):
  1168. yield firstByte
  1169. firstOctet = ord(firstByte)
  1170. try:
  1171. lastTag = tagCache[firstOctet]
  1172. except KeyError:
  1173. integerTag = firstOctet
  1174. tagClass = integerTag & 0xC0
  1175. tagFormat = integerTag & 0x20
  1176. tagId = integerTag & 0x1F
  1177. if tagId == 0x1F:
  1178. isShortTag = False
  1179. lengthOctetIdx = 0
  1180. tagId = 0
  1181. while True:
  1182. for integerByte in readFromStream(substrate, 1, options):
  1183. if isinstance(integerByte, SubstrateUnderrunError):
  1184. yield integerByte
  1185. if not integerByte:
  1186. raise error.SubstrateUnderrunError(
  1187. 'Short octet stream on long tag decoding'
  1188. )
  1189. integerTag = ord(integerByte)
  1190. lengthOctetIdx += 1
  1191. tagId <<= 7
  1192. tagId |= (integerTag & 0x7F)
  1193. if not integerTag & 0x80:
  1194. break
  1195. lastTag = tag.Tag(
  1196. tagClass=tagClass, tagFormat=tagFormat, tagId=tagId
  1197. )
  1198. if isShortTag:
  1199. # cache short tags
  1200. tagCache[firstOctet] = lastTag
  1201. if tagSet is None:
  1202. if isShortTag:
  1203. try:
  1204. tagSet = tagSetCache[firstOctet]
  1205. except KeyError:
  1206. # base tag not recovered
  1207. tagSet = tag.TagSet((), lastTag)
  1208. tagSetCache[firstOctet] = tagSet
  1209. else:
  1210. tagSet = tag.TagSet((), lastTag)
  1211. else:
  1212. tagSet = lastTag + tagSet
  1213. state = stDecodeLength
  1214. if LOG:
  1215. LOG('tag decoded into %s, decoding length' % tagSet)
  1216. if state is stDecodeLength:
  1217. # Decode length
  1218. for firstOctet in readFromStream(substrate, 1, options):
  1219. if isinstance(firstOctet, SubstrateUnderrunError):
  1220. yield firstOctet
  1221. firstOctet = ord(firstOctet)
  1222. if firstOctet < 128:
  1223. length = firstOctet
  1224. elif firstOctet > 128:
  1225. size = firstOctet & 0x7F
  1226. if size > MAX_LENGTH_OCTETS:
  1227. raise error.PyAsn1Error(
  1228. 'BER length field size %d exceeds limit (%d)' % (
  1229. size, MAX_LENGTH_OCTETS)
  1230. )
  1231. # encoded in size bytes
  1232. for encodedLength in readFromStream(substrate, size, options):
  1233. if isinstance(encodedLength, SubstrateUnderrunError):
  1234. yield encodedLength
  1235. encodedLength = list(encodedLength)
  1236. if len(encodedLength) != size:
  1237. raise error.SubstrateUnderrunError(
  1238. '%s<%s at %s' % (size, len(encodedLength), tagSet)
  1239. )
  1240. length = 0
  1241. for lengthOctet in encodedLength:
  1242. length <<= 8
  1243. length |= lengthOctet
  1244. size += 1
  1245. else: # 128 means indefinite
  1246. length = -1
  1247. if length == -1 and not self.supportIndefLength:
  1248. raise error.PyAsn1Error('Indefinite length encoding not supported by this codec')
  1249. state = stGetValueDecoder
  1250. if LOG:
  1251. LOG('value length decoded into %d' % length)
  1252. if state is stGetValueDecoder:
  1253. if asn1Spec is None:
  1254. state = stGetValueDecoderByTag
  1255. else:
  1256. state = stGetValueDecoderByAsn1Spec
  1257. #
  1258. # There're two ways of creating subtypes in ASN.1 what influences
  1259. # decoder operation. These methods are:
  1260. # 1) Either base types used in or no IMPLICIT tagging has been
  1261. # applied on subtyping.
  1262. # 2) Subtype syntax drops base type information (by means of
  1263. # IMPLICIT tagging.
  1264. # The first case allows for complete tag recovery from substrate
  1265. # while the second one requires original ASN.1 type spec for
  1266. # decoding.
  1267. #
  1268. # In either case a set of tags (tagSet) is coming from substrate
  1269. # in an incremental, tag-by-tag fashion (this is the case of
  1270. # EXPLICIT tag which is most basic). Outermost tag comes first
  1271. # from the wire.
  1272. #
  1273. if state is stGetValueDecoderByTag:
  1274. try:
  1275. concreteDecoder = tagMap[tagSet]
  1276. except KeyError:
  1277. concreteDecoder = None
  1278. if concreteDecoder:
  1279. state = stDecodeValue
  1280. else:
  1281. try:
  1282. concreteDecoder = tagMap[tagSet[:1]]
  1283. except KeyError:
  1284. concreteDecoder = None
  1285. if concreteDecoder:
  1286. state = stDecodeValue
  1287. else:
  1288. state = stTryAsExplicitTag
  1289. if LOG:
  1290. 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'))
  1291. debug.scope.push(concreteDecoder is None and '?' or concreteDecoder.protoComponent.__class__.__name__)
  1292. if state is stGetValueDecoderByAsn1Spec:
  1293. if asn1Spec.__class__ is tagmap.TagMap:
  1294. try:
  1295. chosenSpec = asn1Spec[tagSet]
  1296. except KeyError:
  1297. chosenSpec = None
  1298. if LOG:
  1299. LOG('candidate ASN.1 spec is a map of:')
  1300. for firstOctet, v in asn1Spec.presentTypes.items():
  1301. LOG(' %s -> %s' % (firstOctet, v.__class__.__name__))
  1302. if asn1Spec.skipTypes:
  1303. LOG('but neither of: ')
  1304. for firstOctet, v in asn1Spec.skipTypes.items():
  1305. LOG(' %s -> %s' % (firstOctet, v.__class__.__name__))
  1306. LOG('new candidate ASN.1 spec is %s, chosen by %s' % (chosenSpec is None and '<none>' or chosenSpec.prettyPrintType(), tagSet))
  1307. elif tagSet == asn1Spec.tagSet or tagSet in asn1Spec.tagMap:
  1308. chosenSpec = asn1Spec
  1309. if LOG:
  1310. LOG('candidate ASN.1 spec is %s' % asn1Spec.__class__.__name__)
  1311. else:
  1312. chosenSpec = None
  1313. if chosenSpec is not None:
  1314. try:
  1315. # ambiguous type or just faster codec lookup
  1316. concreteDecoder = typeMap[chosenSpec.typeId]
  1317. if LOG:
  1318. LOG('value decoder chosen for an ambiguous type by type ID %s' % (chosenSpec.typeId,))
  1319. except KeyError:
  1320. # use base type for codec lookup to recover untagged types
  1321. baseTagSet = tag.TagSet(chosenSpec.tagSet.baseTag, chosenSpec.tagSet.baseTag)
  1322. try:
  1323. # base type or tagged subtype
  1324. concreteDecoder = tagMap[baseTagSet]
  1325. if LOG:
  1326. LOG('value decoder chosen by base %s' % (baseTagSet,))
  1327. except KeyError:
  1328. concreteDecoder = None
  1329. if concreteDecoder:
  1330. asn1Spec = chosenSpec
  1331. state = stDecodeValue
  1332. else:
  1333. state = stTryAsExplicitTag
  1334. else:
  1335. concreteDecoder = None
  1336. state = stTryAsExplicitTag
  1337. if LOG:
  1338. 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'))
  1339. debug.scope.push(chosenSpec is None and '?' or chosenSpec.__class__.__name__)
  1340. if state is stDecodeValue:
  1341. if not options.get('recursiveFlag', True) and not substrateFun: # deprecate this
  1342. def substrateFun(asn1Object, _substrate, _length, _options):
  1343. """Legacy hack to keep the recursiveFlag=False option supported.
  1344. The decode(..., substrateFun=userCallback) option was introduced in 0.1.4 as a generalization
  1345. of the old recursiveFlag=False option. Users should pass their callback instead of using
  1346. recursiveFlag.
  1347. """
  1348. yield asn1Object
  1349. original_position = substrate.tell()
  1350. if length == -1: # indef length
  1351. for value in concreteDecoder.indefLenValueDecoder(
  1352. substrate, asn1Spec,
  1353. tagSet, length, stGetValueDecoder,
  1354. self, substrateFun, **options):
  1355. if isinstance(value, SubstrateUnderrunError):
  1356. yield value
  1357. else:
  1358. for value in concreteDecoder.valueDecoder(
  1359. substrate, asn1Spec,
  1360. tagSet, length, stGetValueDecoder,
  1361. self, substrateFun, **options):
  1362. if isinstance(value, SubstrateUnderrunError):
  1363. yield value
  1364. bytesRead = substrate.tell() - original_position
  1365. if not substrateFun and bytesRead != length:
  1366. raise PyAsn1Error(
  1367. "Read %s bytes instead of expected %s." % (bytesRead, length))
  1368. elif substrateFun and bytesRead > length:
  1369. # custom substrateFun may be used for partial decoding, reading less is expected there
  1370. raise PyAsn1Error(
  1371. "Read %s bytes are more than expected %s." % (bytesRead, length))
  1372. if LOG:
  1373. LOG('codec %s yields type %s, value:\n%s\n...' % (
  1374. concreteDecoder.__class__.__name__, value.__class__.__name__,
  1375. isinstance(value, base.Asn1Item) and value.prettyPrint() or value))
  1376. state = stStop
  1377. break
  1378. if state is stTryAsExplicitTag:
  1379. if (tagSet and
  1380. tagSet[0].tagFormat == tag.tagFormatConstructed and
  1381. tagSet[0].tagClass != tag.tagClassUniversal):
  1382. # Assume explicit tagging
  1383. concreteDecoder = rawPayloadDecoder
  1384. state = stDecodeValue
  1385. else:
  1386. concreteDecoder = None
  1387. state = self.defaultErrorState
  1388. if LOG:
  1389. LOG('codec %s chosen, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "<none>", state is stDecodeValue and 'value' or 'as failure'))
  1390. if state is stDumpRawValue:
  1391. concreteDecoder = self.defaultRawDecoder
  1392. if LOG:
  1393. LOG('codec %s chosen, decoding value' % concreteDecoder.__class__.__name__)
  1394. state = stDecodeValue
  1395. if state is stErrorCondition:
  1396. raise error.PyAsn1Error(
  1397. '%s not in asn1Spec: %r' % (tagSet, asn1Spec)
  1398. )
  1399. if LOG:
  1400. debug.scope.pop()
  1401. LOG('decoder left scope %s, call completed' % debug.scope)
  1402. yield value
  1403. class StreamingDecoder(object):
  1404. """Create an iterator that turns BER/CER/DER byte stream into ASN.1 objects.
  1405. On each iteration, consume whatever BER/CER/DER serialization is
  1406. available in the `substrate` stream-like object and turns it into
  1407. one or more, possibly nested, ASN.1 objects.
  1408. Parameters
  1409. ----------
  1410. substrate: :py:class:`file`, :py:class:`io.BytesIO`
  1411. BER/CER/DER serialization in form of a byte stream
  1412. Keyword Args
  1413. ------------
  1414. asn1Spec: :py:class:`~pyasn1.type.base.PyAsn1Item`
  1415. A pyasn1 type object to act as a template guiding the decoder.
  1416. Depending on the ASN.1 structure being decoded, `asn1Spec` may
  1417. or may not be required. One of the reasons why `asn1Spec` may
  1418. me required is that ASN.1 structure is encoded in the *IMPLICIT*
  1419. tagging mode.
  1420. Yields
  1421. ------
  1422. : :py:class:`~pyasn1.type.base.PyAsn1Item`, :py:class:`~pyasn1.error.SubstrateUnderrunError`
  1423. Decoded ASN.1 object (possibly, nested) or
  1424. :py:class:`~pyasn1.error.SubstrateUnderrunError` object indicating
  1425. insufficient BER/CER/DER serialization on input to fully recover ASN.1
  1426. objects from it.
  1427. In the latter case the caller is advised to ensure some more data in
  1428. the input stream, then call the iterator again. The decoder will resume
  1429. the decoding process using the newly arrived data.
  1430. The `context` property of :py:class:`~pyasn1.error.SubstrateUnderrunError`
  1431. object might hold a reference to the partially populated ASN.1 object
  1432. being reconstructed.
  1433. Raises
  1434. ------
  1435. ~pyasn1.error.PyAsn1Error, ~pyasn1.error.EndOfStreamError
  1436. `PyAsn1Error` on deserialization error, `EndOfStreamError` on
  1437. premature stream closure.
  1438. Examples
  1439. --------
  1440. Decode BER serialisation without ASN.1 schema
  1441. .. code-block:: pycon
  1442. >>> stream = io.BytesIO(
  1443. ... b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03')
  1444. >>>
  1445. >>> for asn1Object in StreamingDecoder(stream):
  1446. ... print(asn1Object)
  1447. >>>
  1448. SequenceOf:
  1449. 1 2 3
  1450. Decode BER serialisation with ASN.1 schema
  1451. .. code-block:: pycon
  1452. >>> stream = io.BytesIO(
  1453. ... b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03')
  1454. >>>
  1455. >>> schema = SequenceOf(componentType=Integer())
  1456. >>>
  1457. >>> decoder = StreamingDecoder(stream, asn1Spec=schema)
  1458. >>> for asn1Object in decoder:
  1459. ... print(asn1Object)
  1460. >>>
  1461. SequenceOf:
  1462. 1 2 3
  1463. """
  1464. SINGLE_ITEM_DECODER = SingleItemDecoder
  1465. def __init__(self, substrate, asn1Spec=None, **options):
  1466. self._singleItemDecoder = self.SINGLE_ITEM_DECODER(**options)
  1467. self._substrate = asSeekableStream(substrate)
  1468. self._asn1Spec = asn1Spec
  1469. self._options = options
  1470. def __iter__(self):
  1471. while True:
  1472. for asn1Object in self._singleItemDecoder(
  1473. self._substrate, self._asn1Spec, **self._options):
  1474. yield asn1Object
  1475. for chunk in isEndOfStream(self._substrate):
  1476. if isinstance(chunk, SubstrateUnderrunError):
  1477. yield
  1478. break
  1479. if chunk:
  1480. break
  1481. class Decoder(object):
  1482. """Create a BER decoder object.
  1483. Parse BER/CER/DER octet-stream into one, possibly nested, ASN.1 object.
  1484. """
  1485. STREAMING_DECODER = StreamingDecoder
  1486. @classmethod
  1487. def __call__(cls, substrate, asn1Spec=None, **options):
  1488. """Turns BER/CER/DER octet stream into an ASN.1 object.
  1489. Takes BER/CER/DER octet-stream in form of :py:class:`bytes`
  1490. and decode it into an ASN.1 object
  1491. (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which
  1492. may be a scalar or an arbitrary nested structure.
  1493. Parameters
  1494. ----------
  1495. substrate: :py:class:`bytes`
  1496. BER/CER/DER octet-stream to parse
  1497. Keyword Args
  1498. ------------
  1499. asn1Spec: :py:class:`~pyasn1.type.base.PyAsn1Item`
  1500. A pyasn1 type object (:py:class:`~pyasn1.type.base.PyAsn1Item`
  1501. derivative) to act as a template guiding the decoder.
  1502. Depending on the ASN.1 structure being decoded, `asn1Spec` may or
  1503. may not be required. Most common reason for it to require is that
  1504. ASN.1 structure is encoded in *IMPLICIT* tagging mode.
  1505. substrateFun: :py:class:`Union[
  1506. Callable[[pyasn1.type.base.PyAsn1Item, bytes, int],
  1507. Tuple[pyasn1.type.base.PyAsn1Item, bytes]],
  1508. Callable[[pyasn1.type.base.PyAsn1Item, io.BytesIO, int, dict],
  1509. Generator[Union[pyasn1.type.base.PyAsn1Item,
  1510. pyasn1.error.SubstrateUnderrunError],
  1511. None, None]]
  1512. ]`
  1513. User callback meant to generalize special use cases like non-recursive or
  1514. partial decoding. A 3-arg non-streaming variant is supported for backwards
  1515. compatiblilty in addition to the newer 4-arg streaming variant.
  1516. The callback will receive the uninitialized object recovered from substrate
  1517. as 1st argument, the uninterpreted payload as 2nd argument, and the length
  1518. of the uninterpreted payload as 3rd argument. The streaming variant will
  1519. additionally receive the decode(..., **options) kwargs as 4th argument.
  1520. The non-streaming variant shall return an object that will be propagated
  1521. as decode() return value as 1st item, and the remainig payload for further
  1522. decode passes as 2nd item.
  1523. The streaming variant shall yield an object that will be propagated as
  1524. decode() return value, and leave the remaining payload in the stream.
  1525. Returns
  1526. -------
  1527. : :py:class:`tuple`
  1528. A tuple of :py:class:`~pyasn1.type.base.PyAsn1Item` object
  1529. recovered from BER/CER/DER substrate and the unprocessed trailing
  1530. portion of the `substrate` (may be empty)
  1531. Raises
  1532. ------
  1533. : :py:class:`~pyasn1.error.PyAsn1Error`
  1534. :py:class:`~pyasn1.error.SubstrateUnderrunError` on insufficient
  1535. input or :py:class:`~pyasn1.error.PyAsn1Error` on decoding error.
  1536. Examples
  1537. --------
  1538. Decode BER/CER/DER serialisation without ASN.1 schema
  1539. .. code-block:: pycon
  1540. >>> s, unprocessed = decode(b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03')
  1541. >>> str(s)
  1542. SequenceOf:
  1543. 1 2 3
  1544. Decode BER/CER/DER serialisation with ASN.1 schema
  1545. .. code-block:: pycon
  1546. >>> seq = SequenceOf(componentType=Integer())
  1547. >>> s, unprocessed = decode(
  1548. b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03', asn1Spec=seq)
  1549. >>> str(s)
  1550. SequenceOf:
  1551. 1 2 3
  1552. """
  1553. substrate = asSeekableStream(substrate)
  1554. if "substrateFun" in options:
  1555. origSubstrateFun = options["substrateFun"]
  1556. def substrateFunWrapper(asn1Object, substrate, length, options=None):
  1557. """Support both 0.4 and 0.5 style APIs.
  1558. substrateFun API has changed in 0.5 for use with streaming decoders. To stay backwards compatible,
  1559. we first try if we received a streaming user callback. If that fails,we assume we've received a
  1560. non-streaming v0.4 user callback and convert it for streaming on the fly
  1561. """
  1562. try:
  1563. substrate_gen = origSubstrateFun(asn1Object, substrate, length, options)
  1564. except TypeError as _value:
  1565. if _value.__traceback__.tb_next:
  1566. # Traceback depth > 1 means TypeError from inside user provided function
  1567. raise
  1568. # invariant maintained at Decoder.__call__ entry
  1569. assert isinstance(substrate, io.BytesIO) # nosec assert_used
  1570. substrate_gen = Decoder._callSubstrateFunV4asV5(origSubstrateFun, asn1Object, substrate, length)
  1571. for value in substrate_gen:
  1572. yield value
  1573. options["substrateFun"] = substrateFunWrapper
  1574. streamingDecoder = cls.STREAMING_DECODER(
  1575. substrate, asn1Spec, **options)
  1576. for asn1Object in streamingDecoder:
  1577. if isinstance(asn1Object, SubstrateUnderrunError):
  1578. raise error.SubstrateUnderrunError('Short substrate on input')
  1579. try:
  1580. tail = next(readFromStream(substrate))
  1581. except error.EndOfStreamError:
  1582. tail = b''
  1583. return asn1Object, tail
  1584. @staticmethod
  1585. def _callSubstrateFunV4asV5(substrateFunV4, asn1Object, substrate, length):
  1586. substrate_bytes = substrate.read()
  1587. if length == -1:
  1588. length = len(substrate_bytes)
  1589. value, nextSubstrate = substrateFunV4(asn1Object, substrate_bytes, length)
  1590. nbytes = substrate.write(nextSubstrate)
  1591. substrate.truncate()
  1592. substrate.seek(-nbytes, os.SEEK_CUR)
  1593. yield value
  1594. #: Turns BER octet stream into an ASN.1 object.
  1595. #:
  1596. #: Takes BER octet-stream and decode it into an ASN.1 object
  1597. #: (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which
  1598. #: may be a scalar or an arbitrary nested structure.
  1599. #:
  1600. #: Parameters
  1601. #: ----------
  1602. #: substrate: :py:class:`bytes`
  1603. #: BER octet-stream
  1604. #:
  1605. #: Keyword Args
  1606. #: ------------
  1607. #: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
  1608. #: A pyasn1 type object to act as a template guiding the decoder. Depending on the ASN.1 structure
  1609. #: being decoded, *asn1Spec* may or may not be required. Most common reason for
  1610. #: it to require is that ASN.1 structure is encoded in *IMPLICIT* tagging mode.
  1611. #:
  1612. #: Returns
  1613. #: -------
  1614. #: : :py:class:`tuple`
  1615. #: A tuple of pyasn1 object recovered from BER substrate (:py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
  1616. #: and the unprocessed trailing portion of the *substrate* (may be empty)
  1617. #:
  1618. #: Raises
  1619. #: ------
  1620. #: ~pyasn1.error.PyAsn1Error, ~pyasn1.error.SubstrateUnderrunError
  1621. #: On decoding errors
  1622. #:
  1623. #: Notes
  1624. #: -----
  1625. #: This function is deprecated. Please use :py:class:`Decoder` or
  1626. #: :py:class:`StreamingDecoder` class instance.
  1627. #:
  1628. #: Examples
  1629. #: --------
  1630. #: Decode BER serialisation without ASN.1 schema
  1631. #:
  1632. #: .. code-block:: pycon
  1633. #:
  1634. #: >>> s, _ = decode(b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03')
  1635. #: >>> str(s)
  1636. #: SequenceOf:
  1637. #: 1 2 3
  1638. #:
  1639. #: Decode BER serialisation with ASN.1 schema
  1640. #:
  1641. #: .. code-block:: pycon
  1642. #:
  1643. #: >>> seq = SequenceOf(componentType=Integer())
  1644. #: >>> s, _ = decode(b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03', asn1Spec=seq)
  1645. #: >>> str(s)
  1646. #: SequenceOf:
  1647. #: 1 2 3
  1648. #:
  1649. decode = Decoder()
  1650. def __getattr__(attr: str):
  1651. if newAttr := {"tagMap": "TAG_MAP", "typeMap": "TYPE_MAP"}.get(attr):
  1652. warnings.warn(f"{attr} is deprecated. Please use {newAttr} instead.", DeprecationWarning, stacklevel=2)
  1653. return globals()[newAttr]
  1654. raise AttributeError(attr)