@@ -7,25 +7,41 @@ use pyo3::types::PyAnyMethods;
77
88use crate :: asn1:: big_byte_slice_to_py_int;
99use crate :: declarative_asn1:: types:: {
10- type_to_tag, AnnotatedType , GeneralizedTime , PrintableString , Type , UtcTime ,
10+ type_to_tag, AnnotatedType , Encoding , GeneralizedTime , PrintableString , Type , UtcTime ,
1111} ;
1212use crate :: error:: CryptographyError ;
1313
1414type ParseResult < T > = Result < T , CryptographyError > ;
1515
16+ fn read_value < ' a , T : asn1:: SimpleAsn1Readable < ' a > > (
17+ parser : & mut Parser < ' a > ,
18+ encoding : & Option < pyo3:: Py < Encoding > > ,
19+ ) -> ParseResult < T > {
20+ let value = match encoding {
21+ Some ( e) => match e. get ( ) {
22+ Encoding :: Implicit ( n) => parser. read_implicit_element :: < T > ( * n) ,
23+ Encoding :: Explicit ( n) => parser. read_explicit_element :: < T > ( * n) ,
24+ } ,
25+ None => parser. read_element :: < T > ( ) ,
26+ } ?;
27+ Ok ( value)
28+ }
29+
1630fn decode_pybool < ' a > (
1731 py : pyo3:: Python < ' a > ,
1832 parser : & mut Parser < ' a > ,
33+ encoding : & Option < pyo3:: Py < Encoding > > ,
1934) -> ParseResult < pyo3:: Bound < ' a , pyo3:: types:: PyBool > > {
20- let value = parser . read_element :: < bool > ( ) ?;
35+ let value = read_value :: < bool > ( parser , encoding ) ?;
2136 Ok ( pyo3:: types:: PyBool :: new ( py, value) . to_owned ( ) )
2237}
2338
2439fn decode_pyint < ' a > (
2540 py : pyo3:: Python < ' a > ,
2641 parser : & mut Parser < ' a > ,
42+ encoding : & Option < pyo3:: Py < Encoding > > ,
2743) -> ParseResult < pyo3:: Bound < ' a , pyo3:: types:: PyInt > > {
28- let value = parser . read_element :: < asn1:: BigInt < ' a > > ( ) ?;
44+ let value = read_value :: < asn1:: BigInt < ' a > > ( parser , encoding ) ?;
2945 let pyint =
3046 big_byte_slice_to_py_int ( py, value. as_bytes ( ) ) ?. cast_into :: < pyo3:: types:: PyInt > ( ) ?;
3147 Ok ( pyint)
@@ -34,33 +50,37 @@ fn decode_pyint<'a>(
3450fn decode_pybytes < ' a > (
3551 py : pyo3:: Python < ' a > ,
3652 parser : & mut Parser < ' a > ,
53+ encoding : & Option < pyo3:: Py < Encoding > > ,
3754) -> ParseResult < pyo3:: Bound < ' a , pyo3:: types:: PyBytes > > {
38- let value = parser . read_element :: < & [ u8 ] > ( ) ?;
55+ let value = read_value :: < & [ u8 ] > ( parser , encoding ) ?;
3956 Ok ( pyo3:: types:: PyBytes :: new ( py, value) )
4057}
4158
4259fn decode_pystr < ' a > (
4360 py : pyo3:: Python < ' a > ,
4461 parser : & mut Parser < ' a > ,
62+ encoding : & Option < pyo3:: Py < Encoding > > ,
4563) -> ParseResult < pyo3:: Bound < ' a , pyo3:: types:: PyString > > {
46- let value = parser . read_element :: < asn1:: Utf8String < ' a > > ( ) ?;
64+ let value = read_value :: < asn1:: Utf8String < ' a > > ( parser , encoding ) ?;
4765 Ok ( pyo3:: types:: PyString :: new ( py, value. as_str ( ) ) )
4866}
4967
5068fn decode_printable_string < ' a > (
5169 py : pyo3:: Python < ' a > ,
5270 parser : & mut Parser < ' a > ,
71+ encoding : & Option < pyo3:: Py < Encoding > > ,
5372) -> ParseResult < pyo3:: Bound < ' a , PrintableString > > {
54- let value = parser . read_element :: < asn1:: PrintableString < ' a > > ( ) ?. as_str ( ) ;
73+ let value = read_value :: < asn1:: PrintableString < ' a > > ( parser , encoding ) ?. as_str ( ) ;
5574 let inner = pyo3:: types:: PyString :: new ( py, value) . unbind ( ) ;
5675 Ok ( pyo3:: Bound :: new ( py, PrintableString { inner } ) ?)
5776}
5877
5978fn decode_utc_time < ' a > (
6079 py : pyo3:: Python < ' a > ,
6180 parser : & mut Parser < ' a > ,
81+ encoding : & Option < pyo3:: Py < Encoding > > ,
6282) -> ParseResult < pyo3:: Bound < ' a , UtcTime > > {
63- let value = parser . read_element :: < asn1:: UtcTime > ( ) ?;
83+ let value = read_value :: < asn1:: UtcTime > ( parser , encoding ) ?;
6484 let dt = value. as_datetime ( ) ;
6585
6686 let inner = crate :: x509:: datetime_to_py_utc ( py, dt) ?
@@ -73,8 +93,9 @@ fn decode_utc_time<'a>(
7393fn decode_generalized_time < ' a > (
7494 py : pyo3:: Python < ' a > ,
7595 parser : & mut Parser < ' a > ,
96+ encoding : & Option < pyo3:: Py < Encoding > > ,
7697) -> ParseResult < pyo3:: Bound < ' a , GeneralizedTime > > {
77- let value = parser . read_element :: < asn1:: GeneralizedTime > ( ) ?;
98+ let value = read_value :: < asn1:: GeneralizedTime > ( parser , encoding ) ?;
7899 let dt = value. as_datetime ( ) ;
79100
80101 let microseconds = match value. nanoseconds ( ) {
@@ -102,11 +123,12 @@ pub(crate) fn decode_annotated_type<'a>(
102123 ann_type : & AnnotatedType ,
103124) -> ParseResult < pyo3:: Bound < ' a , pyo3:: PyAny > > {
104125 let inner = ann_type. inner . get ( ) ;
126+ let encoding = & ann_type. annotation . get ( ) . encoding ;
105127
106128 // Handle DEFAULT annotation if field is not present (by
107129 // returning the default value)
108130 if let Some ( default) = & ann_type. annotation . get ( ) . default {
109- let expected_tag = type_to_tag ( inner) ;
131+ let expected_tag = type_to_tag ( inner, encoding ) ;
110132 let next_tag = parser. peek_tag ( ) ;
111133 if next_tag != Some ( expected_tag) {
112134 return Ok ( default. clone_ref ( py) . into_bound ( py) ) ;
@@ -115,7 +137,7 @@ pub(crate) fn decode_annotated_type<'a>(
115137
116138 let decoded = match & inner {
117139 Type :: Sequence ( cls, fields) => {
118- let seq_parse_result = parser . read_element :: < asn1:: Sequence < ' _ > > ( ) ?;
140+ let seq_parse_result = read_value :: < asn1:: Sequence < ' _ > > ( parser , encoding ) ?;
119141
120142 seq_parse_result. parse ( |d| -> ParseResult < pyo3:: Bound < ' a , pyo3:: PyAny > > {
121143 let kwargs = pyo3:: types:: PyDict :: new ( py) ;
@@ -130,19 +152,27 @@ pub(crate) fn decode_annotated_type<'a>(
130152 } ) ?
131153 }
132154 Type :: Option ( cls) => {
133- let inner_tag = type_to_tag ( cls. get ( ) . inner . get ( ) ) ;
155+ let inner_tag = type_to_tag ( cls. get ( ) . inner . get ( ) , encoding ) ;
134156 match parser. peek_tag ( ) {
135- Some ( t) if t == inner_tag => decode_annotated_type ( py, parser, cls. get ( ) ) ?,
157+ Some ( t) if t == inner_tag => {
158+ // Since for optional types the annotations are enforced to be associated with the Option
159+ // (instead of the inner type), when decoding the inner type we add the annotations of the Option
160+ let inner_ann_type = AnnotatedType {
161+ inner : cls. get ( ) . inner . clone_ref ( py) ,
162+ annotation : ann_type. annotation . clone_ref ( py) ,
163+ } ;
164+ decode_annotated_type ( py, parser, & inner_ann_type) ?
165+ }
136166 _ => pyo3:: types:: PyNone :: get ( py) . to_owned ( ) . into_any ( ) ,
137167 }
138168 }
139- Type :: PyBool ( ) => decode_pybool ( py, parser) ?. into_any ( ) ,
140- Type :: PyInt ( ) => decode_pyint ( py, parser) ?. into_any ( ) ,
141- Type :: PyBytes ( ) => decode_pybytes ( py, parser) ?. into_any ( ) ,
142- Type :: PyStr ( ) => decode_pystr ( py, parser) ?. into_any ( ) ,
143- Type :: PrintableString ( ) => decode_printable_string ( py, parser) ?. into_any ( ) ,
144- Type :: UtcTime ( ) => decode_utc_time ( py, parser) ?. into_any ( ) ,
145- Type :: GeneralizedTime ( ) => decode_generalized_time ( py, parser) ?. into_any ( ) ,
169+ Type :: PyBool ( ) => decode_pybool ( py, parser, encoding ) ?. into_any ( ) ,
170+ Type :: PyInt ( ) => decode_pyint ( py, parser, encoding ) ?. into_any ( ) ,
171+ Type :: PyBytes ( ) => decode_pybytes ( py, parser, encoding ) ?. into_any ( ) ,
172+ Type :: PyStr ( ) => decode_pystr ( py, parser, encoding ) ?. into_any ( ) ,
173+ Type :: PrintableString ( ) => decode_printable_string ( py, parser, encoding ) ?. into_any ( ) ,
174+ Type :: UtcTime ( ) => decode_utc_time ( py, parser, encoding ) ?. into_any ( ) ,
175+ Type :: GeneralizedTime ( ) => decode_generalized_time ( py, parser, encoding ) ?. into_any ( ) ,
146176 } ;
147177
148178 match & ann_type. annotation . get ( ) . default {
0 commit comments