117 lines
3.2 KiB
Python
117 lines
3.2 KiB
Python
|
#
|
||
|
# This file is part of pyasn1 software.
|
||
|
#
|
||
|
# Copyright (c) 2005-2020, Ilya Etingof <etingof@gmail.com>
|
||
|
# License: https://pyasn1.readthedocs.io/en/latest/license.html
|
||
|
#
|
||
|
from pyasn1.codec.cer import decoder
|
||
|
from pyasn1.type import univ
|
||
|
|
||
|
__all__ = ['decode', 'StreamingDecoder']
|
||
|
|
||
|
|
||
|
class BitStringPayloadDecoder(decoder.BitStringPayloadDecoder):
|
||
|
supportConstructedForm = False
|
||
|
|
||
|
|
||
|
class OctetStringPayloadDecoder(decoder.OctetStringPayloadDecoder):
|
||
|
supportConstructedForm = False
|
||
|
|
||
|
|
||
|
# TODO: prohibit non-canonical encoding
|
||
|
RealPayloadDecoder = decoder.RealPayloadDecoder
|
||
|
|
||
|
TAG_MAP = decoder.TAG_MAP.copy()
|
||
|
TAG_MAP.update(
|
||
|
{univ.BitString.tagSet: BitStringPayloadDecoder(),
|
||
|
univ.OctetString.tagSet: OctetStringPayloadDecoder(),
|
||
|
univ.Real.tagSet: RealPayloadDecoder()}
|
||
|
)
|
||
|
|
||
|
TYPE_MAP = decoder.TYPE_MAP.copy()
|
||
|
|
||
|
# deprecated aliases, https://github.com/pyasn1/pyasn1/issues/9
|
||
|
tagMap = TAG_MAP
|
||
|
typeMap = TYPE_MAP
|
||
|
|
||
|
# Put in non-ambiguous types for faster codec lookup
|
||
|
for typeDecoder in TAG_MAP.values():
|
||
|
if typeDecoder.protoComponent is not None:
|
||
|
typeId = typeDecoder.protoComponent.__class__.typeId
|
||
|
if typeId is not None and typeId not in TYPE_MAP:
|
||
|
TYPE_MAP[typeId] = typeDecoder
|
||
|
|
||
|
|
||
|
class SingleItemDecoder(decoder.SingleItemDecoder):
|
||
|
__doc__ = decoder.SingleItemDecoder.__doc__
|
||
|
|
||
|
TAG_MAP = TAG_MAP
|
||
|
TYPE_MAP = TYPE_MAP
|
||
|
|
||
|
supportIndefLength = False
|
||
|
|
||
|
|
||
|
class StreamingDecoder(decoder.StreamingDecoder):
|
||
|
__doc__ = decoder.StreamingDecoder.__doc__
|
||
|
|
||
|
SINGLE_ITEM_DECODER = SingleItemDecoder
|
||
|
|
||
|
|
||
|
class Decoder(decoder.Decoder):
|
||
|
__doc__ = decoder.Decoder.__doc__
|
||
|
|
||
|
STREAMING_DECODER = StreamingDecoder
|
||
|
|
||
|
|
||
|
#: Turns DER octet stream into an ASN.1 object.
|
||
|
#:
|
||
|
#: Takes DER octet-stream and decode it into an ASN.1 object
|
||
|
#: (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which
|
||
|
#: may be a scalar or an arbitrary nested structure.
|
||
|
#:
|
||
|
#: Parameters
|
||
|
#: ----------
|
||
|
#: substrate: :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)
|
||
|
#: DER octet-stream
|
||
|
#:
|
||
|
#: Keyword Args
|
||
|
#: ------------
|
||
|
#: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
|
||
|
#: A pyasn1 type object to act as a template guiding the decoder. Depending on the ASN.1 structure
|
||
|
#: being decoded, *asn1Spec* may or may not be required. Most common reason for
|
||
|
#: it to require is that ASN.1 structure is encoded in *IMPLICIT* tagging mode.
|
||
|
#:
|
||
|
#: Returns
|
||
|
#: -------
|
||
|
#: : :py:class:`tuple`
|
||
|
#: A tuple of pyasn1 object recovered from DER substrate (:py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
|
||
|
#: and the unprocessed trailing portion of the *substrate* (may be empty)
|
||
|
#:
|
||
|
#: Raises
|
||
|
#: ------
|
||
|
#: ~pyasn1.error.PyAsn1Error, ~pyasn1.error.SubstrateUnderrunError
|
||
|
#: On decoding errors
|
||
|
#:
|
||
|
#: Examples
|
||
|
#: --------
|
||
|
#: Decode DER serialisation without ASN.1 schema
|
||
|
#:
|
||
|
#: .. code-block:: pycon
|
||
|
#:
|
||
|
#: >>> s, _ = decode(b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03')
|
||
|
#: >>> str(s)
|
||
|
#: SequenceOf:
|
||
|
#: 1 2 3
|
||
|
#:
|
||
|
#: Decode DER serialisation with ASN.1 schema
|
||
|
#:
|
||
|
#: .. code-block:: pycon
|
||
|
#:
|
||
|
#: >>> seq = SequenceOf(componentType=Integer())
|
||
|
#: >>> s, _ = decode(b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03', asn1Spec=seq)
|
||
|
#: >>> str(s)
|
||
|
#: SequenceOf:
|
||
|
#: 1 2 3
|
||
|
#:
|
||
|
decode = Decoder()
|