decoder.py 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952
  1. #
  2. # This file is part of pyasn1 software.
  3. #
  4. # Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
  5. # License: http://pyasn1.sf.net/license.html
  6. #
  7. from pyasn1.type import base, tag, univ, char, useful, tagmap
  8. from pyasn1.codec.ber import eoo
  9. from pyasn1.compat.octets import oct2int, octs2ints, isOctetsType
  10. from pyasn1.compat.integer import from_bytes
  11. from pyasn1 import debug, error
  12. __all__ = ['decode']
  13. class AbstractDecoder(object):
  14. protoComponent = None
  15. def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
  16. length, state, decodeFun, substrateFun):
  17. raise error.PyAsn1Error('Decoder not implemented for %s' % (tagSet,))
  18. def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
  19. length, state, decodeFun, substrateFun):
  20. raise error.PyAsn1Error('Indefinite length mode decoder not implemented for %s' % (tagSet,))
  21. class AbstractSimpleDecoder(AbstractDecoder):
  22. tagFormats = (tag.tagFormatSimple,)
  23. def _createComponent(self, asn1Spec, tagSet, value=None):
  24. if tagSet[0][1] not in self.tagFormats:
  25. raise error.PyAsn1Error('Invalid tag format %s for %s' % (tagSet[0], self.protoComponent.prettyPrintType()))
  26. if asn1Spec is None:
  27. return self.protoComponent.clone(value, tagSet)
  28. elif value is None:
  29. return asn1Spec
  30. else:
  31. return asn1Spec.clone(value)
  32. class AbstractConstructedDecoder(AbstractDecoder):
  33. tagFormats = (tag.tagFormatConstructed,)
  34. # noinspection PyUnusedLocal
  35. def _createComponent(self, asn1Spec, tagSet, value=None):
  36. if tagSet[0][1] not in self.tagFormats:
  37. raise error.PyAsn1Error('Invalid tag format %s for %s' % (tagSet[0], self.protoComponent.prettyPrintType()))
  38. if asn1Spec is None:
  39. return self.protoComponent.clone(tagSet)
  40. else:
  41. return asn1Spec.clone()
  42. class ExplicitTagDecoder(AbstractSimpleDecoder):
  43. protoComponent = univ.Any('')
  44. tagFormats = (tag.tagFormatConstructed,)
  45. def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
  46. length, state, decodeFun, substrateFun):
  47. if substrateFun:
  48. return substrateFun(
  49. self._createComponent(asn1Spec, tagSet, ''),
  50. substrate, length
  51. )
  52. head, tail = substrate[:length], substrate[length:]
  53. value, _ = decodeFun(head, asn1Spec, tagSet, length)
  54. return value, tail
  55. def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
  56. length, state, decodeFun, substrateFun):
  57. if substrateFun:
  58. return substrateFun(
  59. self._createComponent(asn1Spec, tagSet, ''),
  60. substrate, length
  61. )
  62. value, substrate = decodeFun(substrate, asn1Spec, tagSet, length)
  63. terminator, substrate = decodeFun(substrate, allowEoo=True)
  64. if eoo.endOfOctets.isSameTypeWith(terminator) and \
  65. terminator == eoo.endOfOctets:
  66. return value, substrate
  67. else:
  68. raise error.PyAsn1Error('Missing end-of-octets terminator')
  69. explicitTagDecoder = ExplicitTagDecoder()
  70. class IntegerDecoder(AbstractSimpleDecoder):
  71. protoComponent = univ.Integer(0)
  72. def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
  73. state, decodeFun, substrateFun):
  74. head, tail = substrate[:length], substrate[length:]
  75. if not head:
  76. return self._createComponent(asn1Spec, tagSet, 0), tail
  77. value = from_bytes(head, signed=True)
  78. return self._createComponent(asn1Spec, tagSet, value), tail
  79. class BooleanDecoder(IntegerDecoder):
  80. protoComponent = univ.Boolean(0)
  81. def _createComponent(self, asn1Spec, tagSet, value=None):
  82. return IntegerDecoder._createComponent(self, asn1Spec, tagSet, value and 1 or 0)
  83. class BitStringDecoder(AbstractSimpleDecoder):
  84. protoComponent = univ.BitString(())
  85. tagFormats = (tag.tagFormatSimple, tag.tagFormatConstructed)
  86. supportConstructedForm = True
  87. def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
  88. state, decodeFun, substrateFun):
  89. head, tail = substrate[:length], substrate[length:]
  90. if tagSet[0][1] == tag.tagFormatSimple: # XXX what tag to check?
  91. if not head:
  92. raise error.PyAsn1Error('Empty substrate')
  93. trailingBits = oct2int(head[0])
  94. if trailingBits > 7:
  95. raise error.PyAsn1Error(
  96. 'Trailing bits overflow %s' % trailingBits
  97. )
  98. head = head[1:]
  99. value = self.protoComponent.fromOctetString(head, trailingBits)
  100. return self._createComponent(asn1Spec, tagSet, value), tail
  101. if not self.supportConstructedForm:
  102. raise error.PyAsn1Error('Constructed encoding form prohibited at %s' % self.__class__.__name__)
  103. bitString = self._createComponent(asn1Spec, tagSet)
  104. if substrateFun:
  105. return substrateFun(bitString, substrate, length)
  106. while head:
  107. component, head = decodeFun(head, self.protoComponent)
  108. bitString += component
  109. return bitString, tail
  110. def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
  111. length, state, decodeFun, substrateFun):
  112. bitString = self._createComponent(asn1Spec, tagSet)
  113. if substrateFun:
  114. return substrateFun(bitString, substrate, length)
  115. while substrate:
  116. component, substrate = decodeFun(substrate, self.protoComponent, allowEoo=True)
  117. if eoo.endOfOctets.isSameTypeWith(component) and component == eoo.endOfOctets:
  118. break
  119. bitString += component
  120. else:
  121. raise error.SubstrateUnderrunError('No EOO seen before substrate ends')
  122. return bitString, substrate
  123. class OctetStringDecoder(AbstractSimpleDecoder):
  124. protoComponent = univ.OctetString('')
  125. tagFormats = (tag.tagFormatSimple, tag.tagFormatConstructed)
  126. supportConstructedForm = True
  127. def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
  128. state, decodeFun, substrateFun):
  129. head, tail = substrate[:length], substrate[length:]
  130. if tagSet[0][1] == tag.tagFormatSimple: # XXX what tag to check?
  131. return self._createComponent(asn1Spec, tagSet, head), tail
  132. if not self.supportConstructedForm:
  133. raise error.PyAsn1Error('Constructed encoding form prohibited at %s' % self.__class__.__name__)
  134. r = self._createComponent(asn1Spec, tagSet, '')
  135. if substrateFun:
  136. return substrateFun(r, substrate, length)
  137. while head:
  138. component, head = decodeFun(head, self.protoComponent)
  139. r = r + component
  140. return r, tail
  141. def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
  142. length, state, decodeFun, substrateFun):
  143. r = self._createComponent(asn1Spec, tagSet, '')
  144. if substrateFun:
  145. return substrateFun(r, substrate, length)
  146. while substrate:
  147. component, substrate = decodeFun(substrate, self.protoComponent,
  148. allowEoo=True)
  149. if eoo.endOfOctets.isSameTypeWith(component) and \
  150. component == eoo.endOfOctets:
  151. break
  152. r = r + component
  153. else:
  154. raise error.SubstrateUnderrunError(
  155. 'No EOO seen before substrate ends'
  156. )
  157. return r, substrate
  158. class NullDecoder(AbstractSimpleDecoder):
  159. protoComponent = univ.Null('')
  160. def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
  161. length, state, decodeFun, substrateFun):
  162. head, tail = substrate[:length], substrate[length:]
  163. r = self._createComponent(asn1Spec, tagSet)
  164. if head:
  165. raise error.PyAsn1Error('Unexpected %d-octet substrate for Null' % length)
  166. return r, tail
  167. class ObjectIdentifierDecoder(AbstractSimpleDecoder):
  168. protoComponent = univ.ObjectIdentifier(())
  169. def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
  170. state, decodeFun, substrateFun):
  171. head, tail = substrate[:length], substrate[length:]
  172. if not head:
  173. raise error.PyAsn1Error('Empty substrate')
  174. head = octs2ints(head)
  175. oid = ()
  176. index = 0
  177. substrateLen = len(head)
  178. while index < substrateLen:
  179. subId = head[index]
  180. index += 1
  181. if subId < 128:
  182. oid = oid + (subId,)
  183. elif subId > 128:
  184. # Construct subid from a number of octets
  185. nextSubId = subId
  186. subId = 0
  187. while nextSubId >= 128:
  188. subId = (subId << 7) + (nextSubId & 0x7F)
  189. if index >= substrateLen:
  190. raise error.SubstrateUnderrunError(
  191. 'Short substrate for sub-OID past %s' % (oid,)
  192. )
  193. nextSubId = head[index]
  194. index += 1
  195. oid += ((subId << 7) + nextSubId,)
  196. elif subId == 128:
  197. # ASN.1 spec forbids leading zeros (0x80) in OID
  198. # encoding, tolerating it opens a vulnerability. See
  199. # http://www.cosic.esat.kuleuven.be/publications/article-1432.pdf
  200. # page 7
  201. raise error.PyAsn1Error('Invalid octet 0x80 in OID encoding')
  202. # Decode two leading arcs
  203. if 0 <= oid[0] <= 39:
  204. oid = (0,) + oid
  205. elif 40 <= oid[0] <= 79:
  206. oid = (1, oid[0] - 40) + oid[1:]
  207. elif oid[0] >= 80:
  208. oid = (2, oid[0] - 80) + oid[1:]
  209. else:
  210. raise error.PyAsn1Error('Malformed first OID octet: %s' % head[0])
  211. return self._createComponent(asn1Spec, tagSet, oid), tail
  212. class RealDecoder(AbstractSimpleDecoder):
  213. protoComponent = univ.Real()
  214. def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
  215. length, state, decodeFun, substrateFun):
  216. head, tail = substrate[:length], substrate[length:]
  217. if not head:
  218. return self._createComponent(asn1Spec, tagSet, 0.0), tail
  219. fo = oct2int(head[0])
  220. head = head[1:]
  221. if fo & 0x80: # binary encoding
  222. if not head:
  223. raise error.PyAsn1Error("Incomplete floating-point value")
  224. n = (fo & 0x03) + 1
  225. if n == 4:
  226. n = oct2int(head[0])
  227. head = head[1:]
  228. eo, head = head[:n], head[n:]
  229. if not eo or not head:
  230. raise error.PyAsn1Error('Real exponent screwed')
  231. e = oct2int(eo[0]) & 0x80 and -1 or 0
  232. while eo: # exponent
  233. e <<= 8
  234. e |= oct2int(eo[0])
  235. eo = eo[1:]
  236. b = fo >> 4 & 0x03 # base bits
  237. if b > 2:
  238. raise error.PyAsn1Error('Illegal Real base')
  239. if b == 1: # encbase = 8
  240. e *= 3
  241. elif b == 2: # encbase = 16
  242. e *= 4
  243. p = 0
  244. while head: # value
  245. p <<= 8
  246. p |= oct2int(head[0])
  247. head = head[1:]
  248. if fo & 0x40: # sign bit
  249. p = -p
  250. sf = fo >> 2 & 0x03 # scale bits
  251. p *= 2 ** sf
  252. value = (p, 2, e)
  253. elif fo & 0x40: # infinite value
  254. value = fo & 0x01 and '-inf' or 'inf'
  255. elif fo & 0xc0 == 0: # character encoding
  256. if not head:
  257. raise error.PyAsn1Error("Incomplete floating-point value")
  258. try:
  259. if fo & 0x3 == 0x1: # NR1
  260. value = (int(head), 10, 0)
  261. elif fo & 0x3 == 0x2: # NR2
  262. value = float(head)
  263. elif fo & 0x3 == 0x3: # NR3
  264. value = float(head)
  265. else:
  266. raise error.SubstrateUnderrunError(
  267. 'Unknown NR (tag %s)' % fo
  268. )
  269. except ValueError:
  270. raise error.SubstrateUnderrunError(
  271. 'Bad character Real syntax'
  272. )
  273. else:
  274. raise error.SubstrateUnderrunError(
  275. 'Unknown encoding (tag %s)' % fo
  276. )
  277. return self._createComponent(asn1Spec, tagSet, value), tail
  278. class SequenceDecoder(AbstractConstructedDecoder):
  279. protoComponent = univ.Sequence()
  280. def _getComponentTagMap(self, r, idx):
  281. try:
  282. return r.getComponentTagMapNearPosition(idx)
  283. except error.PyAsn1Error:
  284. return
  285. def _getComponentPositionByType(self, r, t, idx):
  286. return r.getComponentPositionNearType(t, idx)
  287. def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
  288. length, state, decodeFun, substrateFun):
  289. head, tail = substrate[:length], substrate[length:]
  290. r = self._createComponent(asn1Spec, tagSet)
  291. idx = 0
  292. if substrateFun:
  293. return substrateFun(r, substrate, length)
  294. while head:
  295. asn1Spec = self._getComponentTagMap(r, idx)
  296. component, head = decodeFun(head, asn1Spec)
  297. idx = self._getComponentPositionByType(
  298. r, component.getEffectiveTagSet(), idx
  299. )
  300. r.setComponentByPosition(idx, component,
  301. verifyConstraints=False,
  302. matchTags=False, matchConstraints=False)
  303. idx += 1
  304. r.setDefaultComponents()
  305. r.verifySizeSpec()
  306. return r, tail
  307. def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
  308. length, state, decodeFun, substrateFun):
  309. r = self._createComponent(asn1Spec, tagSet)
  310. if substrateFun:
  311. return substrateFun(r, substrate, length)
  312. idx = 0
  313. while substrate:
  314. asn1Spec = self._getComponentTagMap(r, idx)
  315. component, substrate = decodeFun(substrate, asn1Spec, allowEoo=True)
  316. if eoo.endOfOctets.isSameTypeWith(component) and \
  317. component == eoo.endOfOctets:
  318. break
  319. idx = self._getComponentPositionByType(
  320. r, component.getEffectiveTagSet(), idx
  321. )
  322. r.setComponentByPosition(idx, component,
  323. verifyConstraints=False,
  324. matchTags=False, matchConstraints=False)
  325. idx += 1
  326. else:
  327. raise error.SubstrateUnderrunError(
  328. 'No EOO seen before substrate ends'
  329. )
  330. r.setDefaultComponents()
  331. r.verifySizeSpec()
  332. return r, substrate
  333. class SequenceOfDecoder(AbstractConstructedDecoder):
  334. protoComponent = univ.SequenceOf()
  335. def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
  336. length, state, decodeFun, substrateFun):
  337. head, tail = substrate[:length], substrate[length:]
  338. r = self._createComponent(asn1Spec, tagSet)
  339. if substrateFun:
  340. return substrateFun(r, substrate, length)
  341. asn1Spec = r.getComponentType()
  342. idx = 0
  343. while head:
  344. component, head = decodeFun(head, asn1Spec)
  345. r.setComponentByPosition(idx, component,
  346. verifyConstraints=False,
  347. matchTags=False, matchConstraints=False)
  348. idx += 1
  349. r.verifySizeSpec()
  350. return r, tail
  351. def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
  352. length, state, decodeFun, substrateFun):
  353. r = self._createComponent(asn1Spec, tagSet)
  354. if substrateFun:
  355. return substrateFun(r, substrate, length)
  356. asn1Spec = r.getComponentType()
  357. idx = 0
  358. while substrate:
  359. component, substrate = decodeFun(substrate, asn1Spec, allowEoo=True)
  360. if eoo.endOfOctets.isSameTypeWith(component) and \
  361. component == eoo.endOfOctets:
  362. break
  363. r.setComponentByPosition(idx, component,
  364. verifyConstraints=False,
  365. matchTags=False, matchConstraints=False)
  366. idx += 1
  367. else:
  368. raise error.SubstrateUnderrunError(
  369. 'No EOO seen before substrate ends'
  370. )
  371. r.verifySizeSpec()
  372. return r, substrate
  373. class SetDecoder(SequenceDecoder):
  374. protoComponent = univ.Set()
  375. def _getComponentTagMap(self, r, idx):
  376. return r.getComponentTagMap()
  377. def _getComponentPositionByType(self, r, t, idx):
  378. nextIdx = r.getComponentPositionByType(t)
  379. if nextIdx is None:
  380. return idx
  381. else:
  382. return nextIdx
  383. class SetOfDecoder(SequenceOfDecoder):
  384. protoComponent = univ.SetOf()
  385. class ChoiceDecoder(AbstractConstructedDecoder):
  386. protoComponent = univ.Choice()
  387. tagFormats = (tag.tagFormatSimple, tag.tagFormatConstructed)
  388. def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
  389. length, state, decodeFun, substrateFun):
  390. head, tail = substrate[:length], substrate[length:]
  391. r = self._createComponent(asn1Spec, tagSet)
  392. if substrateFun:
  393. return substrateFun(r, substrate, length)
  394. if r.getTagSet() == tagSet: # explicitly tagged Choice
  395. component, head = decodeFun(
  396. head, r.getComponentTagMap()
  397. )
  398. else:
  399. component, head = decodeFun(
  400. head, r.getComponentTagMap(), tagSet, length, state
  401. )
  402. if isinstance(component, univ.Choice):
  403. effectiveTagSet = component.getEffectiveTagSet()
  404. else:
  405. effectiveTagSet = component.getTagSet()
  406. r.setComponentByType(effectiveTagSet, component,
  407. verifyConstraints=False,
  408. matchTags=False, matchConstraints=False,
  409. innerFlag=False)
  410. return r, tail
  411. def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
  412. length, state, decodeFun, substrateFun):
  413. r = self._createComponent(asn1Spec, tagSet)
  414. if substrateFun:
  415. return substrateFun(r, substrate, length)
  416. if r.getTagSet() == tagSet: # explicitly tagged Choice
  417. component, substrate = decodeFun(substrate, r.getComponentTagMap())
  418. # eat up EOO marker
  419. eooMarker, substrate = decodeFun(substrate, allowEoo=True)
  420. if not eoo.endOfOctets.isSameTypeWith(eooMarker) or \
  421. eooMarker != eoo.endOfOctets:
  422. raise error.PyAsn1Error('No EOO seen before substrate ends')
  423. else:
  424. component, substrate = decodeFun(
  425. substrate, r.getComponentTagMap(), tagSet, length, state
  426. )
  427. if isinstance(component, univ.Choice):
  428. effectiveTagSet = component.getEffectiveTagSet()
  429. else:
  430. effectiveTagSet = component.getTagSet()
  431. r.setComponentByType(effectiveTagSet, component,
  432. verifyConstraints=False,
  433. matchTags=False, matchConstraints=False,
  434. innerFlag=False)
  435. return r, substrate
  436. class AnyDecoder(AbstractSimpleDecoder):
  437. protoComponent = univ.Any()
  438. tagFormats = (tag.tagFormatSimple, tag.tagFormatConstructed)
  439. def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
  440. length, state, decodeFun, substrateFun):
  441. if asn1Spec is None or asn1Spec is not None and tagSet != asn1Spec.getTagSet():
  442. # untagged Any container, recover inner header substrate
  443. length = length + len(fullSubstrate) - len(substrate)
  444. substrate = fullSubstrate
  445. if substrateFun:
  446. return substrateFun(self._createComponent(asn1Spec, tagSet),
  447. substrate, length)
  448. head, tail = substrate[:length], substrate[length:]
  449. return self._createComponent(asn1Spec, tagSet, value=head), tail
  450. def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
  451. length, state, decodeFun, substrateFun):
  452. if asn1Spec is not None and tagSet == asn1Spec.getTagSet():
  453. # tagged Any type -- consume header substrate
  454. header = ''
  455. else:
  456. # untagged Any, recover header substrate
  457. header = fullSubstrate[:-len(substrate)]
  458. r = self._createComponent(asn1Spec, tagSet, header)
  459. # Any components do not inherit initial tag
  460. asn1Spec = self.protoComponent
  461. if substrateFun:
  462. return substrateFun(r, substrate, length)
  463. while substrate:
  464. component, substrate = decodeFun(substrate, asn1Spec, allowEoo=True)
  465. if eoo.endOfOctets.isSameTypeWith(component) and \
  466. component == eoo.endOfOctets:
  467. break
  468. r = r + component
  469. else:
  470. raise error.SubstrateUnderrunError(
  471. 'No EOO seen before substrate ends'
  472. )
  473. return r, substrate
  474. # character string types
  475. class UTF8StringDecoder(OctetStringDecoder):
  476. protoComponent = char.UTF8String()
  477. class NumericStringDecoder(OctetStringDecoder):
  478. protoComponent = char.NumericString()
  479. class PrintableStringDecoder(OctetStringDecoder):
  480. protoComponent = char.PrintableString()
  481. class TeletexStringDecoder(OctetStringDecoder):
  482. protoComponent = char.TeletexString()
  483. class VideotexStringDecoder(OctetStringDecoder):
  484. protoComponent = char.VideotexString()
  485. class IA5StringDecoder(OctetStringDecoder):
  486. protoComponent = char.IA5String()
  487. class GraphicStringDecoder(OctetStringDecoder):
  488. protoComponent = char.GraphicString()
  489. class VisibleStringDecoder(OctetStringDecoder):
  490. protoComponent = char.VisibleString()
  491. class GeneralStringDecoder(OctetStringDecoder):
  492. protoComponent = char.GeneralString()
  493. class UniversalStringDecoder(OctetStringDecoder):
  494. protoComponent = char.UniversalString()
  495. class BMPStringDecoder(OctetStringDecoder):
  496. protoComponent = char.BMPString()
  497. # "useful" types
  498. class ObjectDescriptorDecoder(OctetStringDecoder):
  499. protoComponent = useful.ObjectDescriptor()
  500. class GeneralizedTimeDecoder(OctetStringDecoder):
  501. protoComponent = useful.GeneralizedTime()
  502. class UTCTimeDecoder(OctetStringDecoder):
  503. protoComponent = useful.UTCTime()
  504. tagMap = {
  505. univ.Integer.tagSet: IntegerDecoder(),
  506. univ.Boolean.tagSet: BooleanDecoder(),
  507. univ.BitString.tagSet: BitStringDecoder(),
  508. univ.OctetString.tagSet: OctetStringDecoder(),
  509. univ.Null.tagSet: NullDecoder(),
  510. univ.ObjectIdentifier.tagSet: ObjectIdentifierDecoder(),
  511. univ.Enumerated.tagSet: IntegerDecoder(),
  512. univ.Real.tagSet: RealDecoder(),
  513. univ.Sequence.tagSet: SequenceDecoder(), # conflicts with SequenceOf
  514. univ.Set.tagSet: SetDecoder(), # conflicts with SetOf
  515. univ.Choice.tagSet: ChoiceDecoder(), # conflicts with Any
  516. # character string types
  517. char.UTF8String.tagSet: UTF8StringDecoder(),
  518. char.NumericString.tagSet: NumericStringDecoder(),
  519. char.PrintableString.tagSet: PrintableStringDecoder(),
  520. char.TeletexString.tagSet: TeletexStringDecoder(),
  521. char.VideotexString.tagSet: VideotexStringDecoder(),
  522. char.IA5String.tagSet: IA5StringDecoder(),
  523. char.GraphicString.tagSet: GraphicStringDecoder(),
  524. char.VisibleString.tagSet: VisibleStringDecoder(),
  525. char.GeneralString.tagSet: GeneralStringDecoder(),
  526. char.UniversalString.tagSet: UniversalStringDecoder(),
  527. char.BMPString.tagSet: BMPStringDecoder(),
  528. # useful types
  529. useful.ObjectDescriptor.tagSet: ObjectDescriptorDecoder(),
  530. useful.GeneralizedTime.tagSet: GeneralizedTimeDecoder(),
  531. useful.UTCTime.tagSet: UTCTimeDecoder()
  532. }
  533. # Type-to-codec map for ambiguous ASN.1 types
  534. typeMap = {
  535. univ.Set.typeId: SetDecoder(),
  536. univ.SetOf.typeId: SetOfDecoder(),
  537. univ.Sequence.typeId: SequenceDecoder(),
  538. univ.SequenceOf.typeId: SequenceOfDecoder(),
  539. univ.Choice.typeId: ChoiceDecoder(),
  540. univ.Any.typeId: AnyDecoder()
  541. }
  542. (stDecodeTag, stDecodeLength, stGetValueDecoder, stGetValueDecoderByAsn1Spec,
  543. stGetValueDecoderByTag, stTryAsExplicitTag, stDecodeValue,
  544. stDumpRawValue, stErrorCondition, stStop) = [x for x in range(10)]
  545. class Decoder(object):
  546. defaultErrorState = stErrorCondition
  547. # defaultErrorState = stDumpRawValue
  548. defaultRawDecoder = AnyDecoder()
  549. supportIndefLength = True
  550. # noinspection PyDefaultArgument
  551. def __init__(self, tagMap, typeMap={}):
  552. self.__tagMap = tagMap
  553. self.__typeMap = typeMap
  554. # Tag & TagSet objects caches
  555. self.__tagCache = {}
  556. self.__tagSetCache = {}
  557. def __call__(self, substrate, asn1Spec=None, tagSet=None,
  558. length=None, state=stDecodeTag, recursiveFlag=1,
  559. substrateFun=None, allowEoo=False):
  560. if debug.logger & debug.flagDecoder:
  561. debug.logger('decoder called at scope %s with state %d, working with up to %d octets of substrate: %s' % (debug.scope, state, len(substrate), debug.hexdump(substrate)))
  562. if asn1Spec is not None and not isinstance(asn1Spec, (base.Asn1Item, tagmap.TagMap)):
  563. raise error.PyAsn1Error(
  564. 'asn1Spec is not valid (should be an instance of an ASN.1 Item, not %s)' % asn1Spec.__class__.__name__)
  565. value = base.noValue
  566. fullSubstrate = substrate
  567. while state != stStop:
  568. if state == stDecodeTag:
  569. if not substrate:
  570. raise error.SubstrateUnderrunError(
  571. 'Short octet stream on tag decoding'
  572. )
  573. if not isOctetsType(substrate) and \
  574. not isinstance(substrate, univ.OctetString):
  575. raise error.PyAsn1Error('Bad octet stream type')
  576. # Decode tag
  577. firstOctet = substrate[0]
  578. substrate = substrate[1:]
  579. if firstOctet in self.__tagCache:
  580. lastTag = self.__tagCache[firstOctet]
  581. else:
  582. t = oct2int(firstOctet)
  583. # Look for end-of-octets sentinel
  584. if t == 0:
  585. if substrate and oct2int(substrate[0]) == 0:
  586. if allowEoo and self.supportIndefLength:
  587. debug.logger and debug.logger & debug.flagDecoder and debug.logger(
  588. 'end-of-octets sentinel found')
  589. value, substrate = eoo.endOfOctets, substrate[1:]
  590. state = stStop
  591. continue
  592. else:
  593. raise error.PyAsn1Error('Unexpected end-of-contents sentinel')
  594. else:
  595. raise error.PyAsn1Error('Zero tag encountered')
  596. tagClass = t & 0xC0
  597. tagFormat = t & 0x20
  598. tagId = t & 0x1F
  599. short = True
  600. if tagId == 0x1F:
  601. short = False
  602. tagId = 0
  603. while True:
  604. if not substrate:
  605. raise error.SubstrateUnderrunError(
  606. 'Short octet stream on long tag decoding'
  607. )
  608. t = oct2int(substrate[0])
  609. tagId = tagId << 7 | (t & 0x7F)
  610. substrate = substrate[1:]
  611. if not t & 0x80:
  612. break
  613. lastTag = tag.Tag(
  614. tagClass=tagClass, tagFormat=tagFormat, tagId=tagId
  615. )
  616. if short:
  617. # cache short tags
  618. self.__tagCache[firstOctet] = lastTag
  619. if tagSet is None:
  620. if firstOctet in self.__tagSetCache:
  621. tagSet = self.__tagSetCache[firstOctet]
  622. else:
  623. # base tag not recovered
  624. tagSet = tag.TagSet((), lastTag)
  625. if firstOctet in self.__tagCache:
  626. self.__tagSetCache[firstOctet] = tagSet
  627. else:
  628. tagSet = lastTag + tagSet
  629. state = stDecodeLength
  630. debug.logger and debug.logger & debug.flagDecoder and debug.logger(
  631. 'tag decoded into %s, decoding length' % tagSet)
  632. if state == stDecodeLength:
  633. # Decode length
  634. if not substrate:
  635. raise error.SubstrateUnderrunError(
  636. 'Short octet stream on length decoding'
  637. )
  638. firstOctet = oct2int(substrate[0])
  639. if firstOctet == 128:
  640. size = 1
  641. length = -1
  642. elif firstOctet < 128:
  643. length, size = firstOctet, 1
  644. else:
  645. size = firstOctet & 0x7F
  646. # encoded in size bytes
  647. length = 0
  648. lengthString = substrate[1:size + 1]
  649. # missing check on maximum size, which shouldn't be a
  650. # problem, we can handle more than is possible
  651. if len(lengthString) != size:
  652. raise error.SubstrateUnderrunError(
  653. '%s<%s at %s' %
  654. (size, len(lengthString), tagSet)
  655. )
  656. for char in lengthString:
  657. length = (length << 8) | oct2int(char)
  658. size += 1
  659. substrate = substrate[size:]
  660. if length != -1 and len(substrate) < length:
  661. raise error.SubstrateUnderrunError(
  662. '%d-octet short' % (length - len(substrate))
  663. )
  664. if length == -1 and not self.supportIndefLength:
  665. raise error.PyAsn1Error('Indefinite length encoding not supported by this codec')
  666. state = stGetValueDecoder
  667. debug.logger and debug.logger & debug.flagDecoder and debug.logger(
  668. 'value length decoded into %d, payload substrate is: %s' % (length, debug.hexdump(length == -1 and substrate or substrate[:length]))
  669. )
  670. if state == stGetValueDecoder:
  671. if asn1Spec is None:
  672. state = stGetValueDecoderByTag
  673. else:
  674. state = stGetValueDecoderByAsn1Spec
  675. #
  676. # There're two ways of creating subtypes in ASN.1 what influences
  677. # decoder operation. These methods are:
  678. # 1) Either base types used in or no IMPLICIT tagging has been
  679. # applied on subtyping.
  680. # 2) Subtype syntax drops base type information (by means of
  681. # IMPLICIT tagging.
  682. # The first case allows for complete tag recovery from substrate
  683. # while the second one requires original ASN.1 type spec for
  684. # decoding.
  685. #
  686. # In either case a set of tags (tagSet) is coming from substrate
  687. # in an incremental, tag-by-tag fashion (this is the case of
  688. # EXPLICIT tag which is most basic). Outermost tag comes first
  689. # from the wire.
  690. #
  691. if state == stGetValueDecoderByTag:
  692. if tagSet in self.__tagMap:
  693. concreteDecoder = self.__tagMap[tagSet]
  694. else:
  695. concreteDecoder = None
  696. if concreteDecoder:
  697. state = stDecodeValue
  698. else:
  699. _k = tagSet[:1]
  700. if _k in self.__tagMap:
  701. concreteDecoder = self.__tagMap[_k]
  702. else:
  703. concreteDecoder = None
  704. if concreteDecoder:
  705. state = stDecodeValue
  706. else:
  707. state = stTryAsExplicitTag
  708. if debug.logger and debug.logger & debug.flagDecoder:
  709. debug.logger('codec %s chosen by a built-in type, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "<none>", state == stDecodeValue and 'value' or 'as explicit tag'))
  710. debug.scope.push(
  711. concreteDecoder is None and '?' or concreteDecoder.protoComponent.__class__.__name__)
  712. if state == stGetValueDecoderByAsn1Spec:
  713. if isinstance(asn1Spec, (dict, tagmap.TagMap)):
  714. if tagSet in asn1Spec:
  715. __chosenSpec = asn1Spec[tagSet]
  716. else:
  717. __chosenSpec = None
  718. if debug.logger and debug.logger & debug.flagDecoder:
  719. debug.logger('candidate ASN.1 spec is a map of:')
  720. for t, v in asn1Spec.getPosMap().items():
  721. debug.logger(' %s -> %s' % (t, v.__class__.__name__))
  722. if asn1Spec.getNegMap():
  723. debug.logger('but neither of: ')
  724. for t, v in asn1Spec.getNegMap().items():
  725. debug.logger(' %s -> %s' % (t, v.__class__.__name__))
  726. debug.logger('new candidate ASN.1 spec is %s, chosen by %s' % (__chosenSpec is None and '<none>' or __chosenSpec.prettyPrintType(), tagSet))
  727. else:
  728. __chosenSpec = asn1Spec
  729. debug.logger and debug.logger & debug.flagDecoder and debug.logger(
  730. 'candidate ASN.1 spec is %s' % asn1Spec.__class__.__name__)
  731. if __chosenSpec is not None and (tagSet == __chosenSpec.getTagSet() or
  732. tagSet in __chosenSpec.getTagMap()):
  733. # use base type for codec lookup to recover untagged types
  734. baseTagSet = __chosenSpec.baseTagSet
  735. if __chosenSpec.typeId is not None and \
  736. __chosenSpec.typeId in self.__typeMap:
  737. # ambiguous type
  738. concreteDecoder = self.__typeMap[__chosenSpec.typeId]
  739. debug.logger and debug.logger & debug.flagDecoder and debug.logger(
  740. 'value decoder chosen for an ambiguous type by type ID %s' % (__chosenSpec.typeId,))
  741. elif baseTagSet in self.__tagMap:
  742. # base type or tagged subtype
  743. concreteDecoder = self.__tagMap[baseTagSet]
  744. debug.logger and debug.logger & debug.flagDecoder and debug.logger(
  745. 'value decoder chosen by base %s' % (baseTagSet,))
  746. else:
  747. concreteDecoder = None
  748. if concreteDecoder:
  749. asn1Spec = __chosenSpec
  750. state = stDecodeValue
  751. else:
  752. state = stTryAsExplicitTag
  753. else:
  754. concreteDecoder = None
  755. state = stTryAsExplicitTag
  756. if debug.logger and debug.logger & debug.flagDecoder:
  757. debug.logger('codec %s chosen by ASN.1 spec, decoding %s' % (state == stDecodeValue and concreteDecoder.__class__.__name__ or "<none>", state == stDecodeValue and 'value' or 'as explicit tag'))
  758. debug.scope.push(__chosenSpec is None and '?' or __chosenSpec.__class__.__name__)
  759. if state == stTryAsExplicitTag:
  760. if tagSet and tagSet[0][1] == tag.tagFormatConstructed and \
  761. tagSet[0][0] != tag.tagClassUniversal:
  762. # Assume explicit tagging
  763. concreteDecoder = explicitTagDecoder
  764. state = stDecodeValue
  765. else:
  766. concreteDecoder = None
  767. state = self.defaultErrorState
  768. debug.logger and debug.logger & debug.flagDecoder and debug.logger('codec %s chosen, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "<none>", state == stDecodeValue and 'value' or 'as failure'))
  769. if state == stDumpRawValue:
  770. concreteDecoder = self.defaultRawDecoder
  771. debug.logger and debug.logger & debug.flagDecoder and debug.logger(
  772. 'codec %s chosen, decoding value' % concreteDecoder.__class__.__name__)
  773. state = stDecodeValue
  774. if state == stDecodeValue:
  775. if recursiveFlag == 0 and not substrateFun: # legacy
  776. def substrateFun(a, b, c):
  777. return a, b[:c]
  778. if length == -1: # indef length
  779. value, substrate = concreteDecoder.indefLenValueDecoder(
  780. fullSubstrate, substrate, asn1Spec, tagSet, length,
  781. stGetValueDecoder, self, substrateFun
  782. )
  783. else:
  784. value, substrate = concreteDecoder.valueDecoder(
  785. fullSubstrate, substrate, asn1Spec, tagSet, length,
  786. stGetValueDecoder, self, substrateFun
  787. )
  788. state = stStop
  789. debug.logger and debug.logger & debug.flagDecoder and debug.logger(
  790. 'codec %s yields type %s, value:\n%s\n...remaining substrate is: %s' % (concreteDecoder.__class__.__name__, value.__class__.__name__, value.prettyPrint(), substrate and debug.hexdump(substrate) or '<none>'))
  791. if state == stErrorCondition:
  792. raise error.PyAsn1Error(
  793. '%s not in asn1Spec: %s' % (tagSet, asn1Spec)
  794. )
  795. if debug.logger and debug.logger & debug.flagDecoder:
  796. debug.scope.pop()
  797. debug.logger('decoder left scope %s, call completed' % debug.scope)
  798. return value, substrate
  799. #: Turns BER octet stream into an ASN.1 object.
  800. #:
  801. #: Takes BER octetstream and decode it into an ASN.1 object
  802. #: (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which
  803. #: may be a scalar or an arbitrary nested structure.
  804. #:
  805. #: Parameters
  806. #: ----------
  807. #: substrate: :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)
  808. #: BER octetstream
  809. #:
  810. #: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
  811. #: A pyasn1 type object to act as a template guiding the decoder. Depending on the ASN.1 structure
  812. #: being decoded, *asn1Spec* may or may not be required. Most common reason for
  813. #: it to require is that ASN.1 structure is encoded in *IMPLICIT* tagging mode.
  814. #:
  815. #: Returns
  816. #: -------
  817. #: : :py:class:`tuple`
  818. #: A tuple of pyasn1 object recovered from BER substrate (:py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
  819. #: and the unprocessed trailing portion of the *substrate* (may be empty)
  820. #:
  821. #: Raises
  822. #: ------
  823. #: : :py:class:`pyasn1.error.PyAsn1Error`
  824. #: On decoding errors
  825. decode = Decoder(tagMap, typeMap)
  826. # XXX
  827. # non-recursive decoding; return position rather than substrate