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