Development of an internal social media platform with personalised dashboards for students
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 3.6KB

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