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)