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 4.4KB

1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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. from pyasn1 import error
  8. from pyasn1.codec.streaming import readFromStream
  9. from pyasn1.codec.ber import decoder
  10. from pyasn1.compat.octets import oct2int
  11. from pyasn1.type import univ
  12. __all__ = ['decode', 'StreamingDecoder']
  13. SubstrateUnderrunError = error.SubstrateUnderrunError
  14. class BooleanPayloadDecoder(decoder.AbstractSimplePayloadDecoder):
  15. protoComponent = univ.Boolean(0)
  16. def valueDecoder(self, substrate, asn1Spec,
  17. tagSet=None, length=None, state=None,
  18. decodeFun=None, substrateFun=None,
  19. **options):
  20. if length != 1:
  21. raise error.PyAsn1Error('Not single-octet Boolean payload')
  22. for chunk in readFromStream(substrate, length, options):
  23. if isinstance(chunk, SubstrateUnderrunError):
  24. yield chunk
  25. byte = oct2int(chunk[0])
  26. # CER/DER specifies encoding of TRUE as 0xFF and FALSE as 0x0, while
  27. # BER allows any non-zero value as TRUE; cf. sections 8.2.2. and 11.1
  28. # in https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
  29. if byte == 0xff:
  30. value = 1
  31. elif byte == 0x00:
  32. value = 0
  33. else:
  34. raise error.PyAsn1Error('Unexpected Boolean payload: %s' % byte)
  35. yield self._createComponent(asn1Spec, tagSet, value, **options)
  36. # TODO: prohibit non-canonical encoding
  37. BitStringPayloadDecoder = decoder.BitStringPayloadDecoder
  38. OctetStringPayloadDecoder = decoder.OctetStringPayloadDecoder
  39. RealPayloadDecoder = decoder.RealPayloadDecoder
  40. TAG_MAP = decoder.TAG_MAP.copy()
  41. TAG_MAP.update(
  42. {univ.Boolean.tagSet: BooleanPayloadDecoder(),
  43. univ.BitString.tagSet: BitStringPayloadDecoder(),
  44. univ.OctetString.tagSet: OctetStringPayloadDecoder(),
  45. univ.Real.tagSet: RealPayloadDecoder()}
  46. )
  47. TYPE_MAP = decoder.TYPE_MAP.copy()
  48. # deprecated aliases, https://github.com/pyasn1/pyasn1/issues/9
  49. tagMap = TAG_MAP
  50. typeMap = TYPE_MAP
  51. # Put in non-ambiguous types for faster codec lookup
  52. for typeDecoder in TAG_MAP.values():
  53. if typeDecoder.protoComponent is not None:
  54. typeId = typeDecoder.protoComponent.__class__.typeId
  55. if typeId is not None and typeId not in TYPE_MAP:
  56. TYPE_MAP[typeId] = typeDecoder
  57. class SingleItemDecoder(decoder.SingleItemDecoder):
  58. __doc__ = decoder.SingleItemDecoder.__doc__
  59. TAG_MAP = TAG_MAP
  60. TYPE_MAP = TYPE_MAP
  61. class StreamingDecoder(decoder.StreamingDecoder):
  62. __doc__ = decoder.StreamingDecoder.__doc__
  63. SINGLE_ITEM_DECODER = SingleItemDecoder
  64. class Decoder(decoder.Decoder):
  65. __doc__ = decoder.Decoder.__doc__
  66. STREAMING_DECODER = StreamingDecoder
  67. #: Turns CER octet stream into an ASN.1 object.
  68. #:
  69. #: Takes CER octet-stream and decode it into an ASN.1 object
  70. #: (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which
  71. #: may be a scalar or an arbitrary nested structure.
  72. #:
  73. #: Parameters
  74. #: ----------
  75. #: substrate: :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)
  76. #: CER octet-stream
  77. #:
  78. #: Keyword Args
  79. #: ------------
  80. #: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
  81. #: A pyasn1 type object to act as a template guiding the decoder. Depending on the ASN.1 structure
  82. #: being decoded, *asn1Spec* may or may not be required. Most common reason for
  83. #: it to require is that ASN.1 structure is encoded in *IMPLICIT* tagging mode.
  84. #:
  85. #: Returns
  86. #: -------
  87. #: : :py:class:`tuple`
  88. #: A tuple of pyasn1 object recovered from CER substrate (:py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
  89. #: and the unprocessed trailing portion of the *substrate* (may be empty)
  90. #:
  91. #: Raises
  92. #: ------
  93. #: ~pyasn1.error.PyAsn1Error, ~pyasn1.error.SubstrateUnderrunError
  94. #: On decoding errors
  95. #:
  96. #: Examples
  97. #: --------
  98. #: Decode CER serialisation without ASN.1 schema
  99. #:
  100. #: .. code-block:: pycon
  101. #:
  102. #: >>> s, _ = decode(b'0\x80\x02\x01\x01\x02\x01\x02\x02\x01\x03\x00\x00')
  103. #: >>> str(s)
  104. #: SequenceOf:
  105. #: 1 2 3
  106. #:
  107. #: Decode CER serialisation with ASN.1 schema
  108. #:
  109. #: .. code-block:: pycon
  110. #:
  111. #: >>> seq = SequenceOf(componentType=Integer())
  112. #: >>> s, _ = decode(b'0\x80\x02\x01\x01\x02\x01\x02\x02\x01\x03\x00\x00', asn1Spec=seq)
  113. #: >>> str(s)
  114. #: SequenceOf:
  115. #: 1 2 3
  116. #:
  117. decode = Decoder()