decoder.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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 warnings
  8. from pyasn1.codec.cer import decoder
  9. from pyasn1.type import univ
  10. __all__ = ['decode', 'StreamingDecoder']
  11. class BitStringPayloadDecoder(decoder.BitStringPayloadDecoder):
  12. supportConstructedForm = False
  13. class OctetStringPayloadDecoder(decoder.OctetStringPayloadDecoder):
  14. supportConstructedForm = False
  15. # TODO: prohibit non-canonical encoding
  16. RealPayloadDecoder = decoder.RealPayloadDecoder
  17. TAG_MAP = decoder.TAG_MAP.copy()
  18. TAG_MAP.update(
  19. {univ.BitString.tagSet: BitStringPayloadDecoder(),
  20. univ.OctetString.tagSet: OctetStringPayloadDecoder(),
  21. univ.Real.tagSet: RealPayloadDecoder()}
  22. )
  23. TYPE_MAP = decoder.TYPE_MAP.copy()
  24. # Put in non-ambiguous types for faster codec lookup
  25. for typeDecoder in TAG_MAP.values():
  26. if typeDecoder.protoComponent is not None:
  27. typeId = typeDecoder.protoComponent.__class__.typeId
  28. if typeId is not None and typeId not in TYPE_MAP:
  29. TYPE_MAP[typeId] = typeDecoder
  30. class SingleItemDecoder(decoder.SingleItemDecoder):
  31. __doc__ = decoder.SingleItemDecoder.__doc__
  32. TAG_MAP = TAG_MAP
  33. TYPE_MAP = TYPE_MAP
  34. supportIndefLength = False
  35. class StreamingDecoder(decoder.StreamingDecoder):
  36. __doc__ = decoder.StreamingDecoder.__doc__
  37. SINGLE_ITEM_DECODER = SingleItemDecoder
  38. class Decoder(decoder.Decoder):
  39. __doc__ = decoder.Decoder.__doc__
  40. STREAMING_DECODER = StreamingDecoder
  41. #: Turns DER octet stream into an ASN.1 object.
  42. #:
  43. #: Takes DER octet-stream and decode it into an ASN.1 object
  44. #: (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which
  45. #: may be a scalar or an arbitrary nested structure.
  46. #:
  47. #: Parameters
  48. #: ----------
  49. #: substrate: :py:class:`bytes`
  50. #: DER octet-stream
  51. #:
  52. #: Keyword Args
  53. #: ------------
  54. #: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
  55. #: A pyasn1 type object to act as a template guiding the decoder. Depending on the ASN.1 structure
  56. #: being decoded, *asn1Spec* may or may not be required. Most common reason for
  57. #: it to require is that ASN.1 structure is encoded in *IMPLICIT* tagging mode.
  58. #:
  59. #: Returns
  60. #: -------
  61. #: : :py:class:`tuple`
  62. #: A tuple of pyasn1 object recovered from DER substrate (:py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
  63. #: and the unprocessed trailing portion of the *substrate* (may be empty)
  64. #:
  65. #: Raises
  66. #: ------
  67. #: ~pyasn1.error.PyAsn1Error, ~pyasn1.error.SubstrateUnderrunError
  68. #: On decoding errors
  69. #:
  70. #: Examples
  71. #: --------
  72. #: Decode DER serialisation without ASN.1 schema
  73. #:
  74. #: .. code-block:: pycon
  75. #:
  76. #: >>> s, _ = decode(b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03')
  77. #: >>> str(s)
  78. #: SequenceOf:
  79. #: 1 2 3
  80. #:
  81. #: Decode DER serialisation with ASN.1 schema
  82. #:
  83. #: .. code-block:: pycon
  84. #:
  85. #: >>> seq = SequenceOf(componentType=Integer())
  86. #: >>> s, _ = decode(b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03', asn1Spec=seq)
  87. #: >>> str(s)
  88. #: SequenceOf:
  89. #: 1 2 3
  90. #:
  91. decode = Decoder()
  92. def __getattr__(attr: str):
  93. if newAttr := {"tagMap": "TAG_MAP", "typeMap": "TYPE_MAP"}.get(attr):
  94. warnings.warn(f"{attr} is deprecated. Please use {newAttr} instead.", DeprecationWarning)
  95. return globals()[newAttr]
  96. raise AttributeError(attr)