Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
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 71KB

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