Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/pyasn1/codec/cer/decoder.py: 66%
32 statements
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-26 07:30 +0000
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-26 07:30 +0000
1#
2# This file is part of pyasn1 software.
3#
4# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
5# License: http://snmplabs.com/pyasn1/license.html
6#
7from pyasn1 import error
8from pyasn1.codec.ber import decoder
9from pyasn1.compat.octets import oct2int
10from pyasn1.type import univ
12__all__ = ['decode']
15class BooleanDecoder(decoder.AbstractSimpleDecoder):
16 protoComponent = univ.Boolean(0)
18 def valueDecoder(self, substrate, asn1Spec,
19 tagSet=None, length=None, state=None,
20 decodeFun=None, substrateFun=None,
21 **options):
22 head, tail = substrate[:length], substrate[length:]
23 if not head or length != 1:
24 raise error.PyAsn1Error('Not single-octet Boolean payload')
25 byte = oct2int(head[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 return self._createComponent(asn1Spec, tagSet, value, **options), tail
37# TODO: prohibit non-canonical encoding
38BitStringDecoder = decoder.BitStringDecoder
39OctetStringDecoder = decoder.OctetStringDecoder
40RealDecoder = decoder.RealDecoder
42tagMap = decoder.tagMap.copy()
43tagMap.update(
44 {univ.Boolean.tagSet: BooleanDecoder(),
45 univ.BitString.tagSet: BitStringDecoder(),
46 univ.OctetString.tagSet: OctetStringDecoder(),
47 univ.Real.tagSet: RealDecoder()}
48)
50typeMap = decoder.typeMap.copy()
52# Put in non-ambiguous types for faster codec lookup
53for typeDecoder in tagMap.values():
54 if typeDecoder.protoComponent is not None:
55 typeId = typeDecoder.protoComponent.__class__.typeId
56 if typeId is not None and typeId not in typeMap:
57 typeMap[typeId] = typeDecoder
60class Decoder(decoder.Decoder):
61 pass
64#: Turns CER octet stream into an ASN.1 object.
65#:
66#: Takes CER 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` (Python 3) or :py:class:`str` (Python 2)
73#: CER 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 CER 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 CER serialisation without ASN.1 schema
96#:
97#: .. code-block:: pycon
98#:
99#: >>> s, _ = decode(b'0\x80\x02\x01\x01\x02\x01\x02\x02\x01\x03\x00\x00')
100#: >>> str(s)
101#: SequenceOf:
102#: 1 2 3
103#:
104#: Decode CER serialisation with ASN.1 schema
105#:
106#: .. code-block:: pycon
107#:
108#: >>> seq = SequenceOf(componentType=Integer())
109#: >>> s, _ = decode(b'0\x80\x02\x01\x01\x02\x01\x02\x02\x01\x03\x00\x00', asn1Spec=seq)
110#: >>> str(s)
111#: SequenceOf:
112#: 1 2 3
113#:
114decode = Decoder(tagMap, decoder.typeMap)