Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/pyasn1/codec/cer/decoder.py: 72%

46 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-08 06:45 +0000

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# 

7from pyasn1 import error 

8from pyasn1.codec.streaming import readFromStream 

9from pyasn1.codec.ber import decoder 

10from pyasn1.compat.octets import oct2int 

11from pyasn1.type import univ 

12 

13__all__ = ['decode', 'StreamingDecoder'] 

14 

15SubstrateUnderrunError = error.SubstrateUnderrunError 

16 

17 

18class BooleanPayloadDecoder(decoder.AbstractSimplePayloadDecoder): 

19 protoComponent = univ.Boolean(0) 

20 

21 def valueDecoder(self, substrate, asn1Spec, 

22 tagSet=None, length=None, state=None, 

23 decodeFun=None, substrateFun=None, 

24 **options): 

25 

26 if length != 1: 

27 raise error.PyAsn1Error('Not single-octet Boolean payload') 

28 

29 for chunk in readFromStream(substrate, length, options): 

30 if isinstance(chunk, SubstrateUnderrunError): 

31 yield chunk 

32 

33 byte = oct2int(chunk[0]) 

34 

35 # CER/DER specifies encoding of TRUE as 0xFF and FALSE as 0x0, while 

36 # BER allows any non-zero value as TRUE; cf. sections 8.2.2. and 11.1  

37 # in https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf 

38 if byte == 0xff: 

39 value = 1 

40 

41 elif byte == 0x00: 

42 value = 0 

43 

44 else: 

45 raise error.PyAsn1Error('Unexpected Boolean payload: %s' % byte) 

46 

47 yield self._createComponent(asn1Spec, tagSet, value, **options) 

48 

49 

50# TODO: prohibit non-canonical encoding 

51BitStringPayloadDecoder = decoder.BitStringPayloadDecoder 

52OctetStringPayloadDecoder = decoder.OctetStringPayloadDecoder 

53RealPayloadDecoder = decoder.RealPayloadDecoder 

54 

55TAG_MAP = decoder.TAG_MAP.copy() 

56TAG_MAP.update( 

57 {univ.Boolean.tagSet: BooleanPayloadDecoder(), 

58 univ.BitString.tagSet: BitStringPayloadDecoder(), 

59 univ.OctetString.tagSet: OctetStringPayloadDecoder(), 

60 univ.Real.tagSet: RealPayloadDecoder()} 

61) 

62 

63TYPE_MAP = decoder.TYPE_MAP.copy() 

64 

65# deprecated aliases, https://github.com/pyasn1/pyasn1/issues/9 

66tagMap = TAG_MAP 

67typeMap = TYPE_MAP 

68 

69# Put in non-ambiguous types for faster codec lookup 

70for typeDecoder in TAG_MAP.values(): 

71 if typeDecoder.protoComponent is not None: 

72 typeId = typeDecoder.protoComponent.__class__.typeId 

73 if typeId is not None and typeId not in TYPE_MAP: 

74 TYPE_MAP[typeId] = typeDecoder 

75 

76 

77class SingleItemDecoder(decoder.SingleItemDecoder): 

78 __doc__ = decoder.SingleItemDecoder.__doc__ 

79 

80 TAG_MAP = TAG_MAP 

81 TYPE_MAP = TYPE_MAP 

82 

83 

84class StreamingDecoder(decoder.StreamingDecoder): 

85 __doc__ = decoder.StreamingDecoder.__doc__ 

86 

87 SINGLE_ITEM_DECODER = SingleItemDecoder 

88 

89 

90class Decoder(decoder.Decoder): 

91 __doc__ = decoder.Decoder.__doc__ 

92 

93 STREAMING_DECODER = StreamingDecoder 

94 

95 

96#: Turns CER octet stream into an ASN.1 object. 

97#: 

98#: Takes CER octet-stream and decode it into an ASN.1 object 

99#: (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which 

100#: may be a scalar or an arbitrary nested structure. 

101#: 

102#: Parameters 

103#: ---------- 

104#: substrate: :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2) 

105#: CER octet-stream 

106#: 

107#: Keyword Args 

108#: ------------ 

109#: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative 

110#: A pyasn1 type object to act as a template guiding the decoder. Depending on the ASN.1 structure 

111#: being decoded, *asn1Spec* may or may not be required. Most common reason for 

112#: it to require is that ASN.1 structure is encoded in *IMPLICIT* tagging mode. 

113#: 

114#: Returns 

115#: ------- 

116#: : :py:class:`tuple` 

117#: A tuple of pyasn1 object recovered from CER substrate (:py:class:`~pyasn1.type.base.PyAsn1Item` derivative) 

118#: and the unprocessed trailing portion of the *substrate* (may be empty) 

119#: 

120#: Raises 

121#: ------ 

122#: ~pyasn1.error.PyAsn1Error, ~pyasn1.error.SubstrateUnderrunError 

123#: On decoding errors 

124#: 

125#: Examples 

126#: -------- 

127#: Decode CER serialisation without ASN.1 schema 

128#: 

129#: .. code-block:: pycon 

130#: 

131#: >>> s, _ = decode(b'0\x80\x02\x01\x01\x02\x01\x02\x02\x01\x03\x00\x00') 

132#: >>> str(s) 

133#: SequenceOf: 

134#: 1 2 3 

135#: 

136#: Decode CER serialisation with ASN.1 schema 

137#: 

138#: .. code-block:: pycon 

139#: 

140#: >>> seq = SequenceOf(componentType=Integer()) 

141#: >>> s, _ = decode(b'0\x80\x02\x01\x01\x02\x01\x02\x02\x01\x03\x00\x00', asn1Spec=seq) 

142#: >>> str(s) 

143#: SequenceOf: 

144#: 1 2 3 

145#: 

146decode = Decoder()