rasn/ber/
de.rs

1//! # Decoding BER
2
3mod config;
4pub(super) mod parser;
5
6use super::identifier::Identifier;
7use crate::{
8    types::{
9        self,
10        oid::{MAX_OID_FIRST_OCTET, MAX_OID_SECOND_OCTET},
11        Constraints, Enumerated, Tag,
12    },
13    Decode,
14};
15use alloc::{borrow::ToOwned, string::ToString, vec::Vec};
16use chrono::{DateTime, FixedOffset, NaiveDateTime, TimeZone};
17use parser::ParseNumberError;
18
19pub use self::config::DecoderOptions;
20
21pub use crate::error::DecodeError;
22pub use crate::error::{BerDecodeErrorKind, CodecDecodeError, DecodeErrorKind, DerDecodeErrorKind};
23type Result<T, E = DecodeError> = core::result::Result<T, E>;
24
25const EOC: &[u8] = &[0, 0];
26
27/// A BER and variants decoder. Capable of decoding BER, CER, and DER.
28pub struct Decoder<'input> {
29    input: &'input [u8],
30    config: DecoderOptions,
31    initial_len: usize,
32}
33
34impl<'input> Decoder<'input> {
35    /// Return the current codec `Codec` variant
36    #[must_use]
37    pub fn codec(&self) -> crate::Codec {
38        self.config.current_codec()
39    }
40    /// Create a new [`Decoder`] from the given `input` and `config`.
41    #[must_use]
42    pub fn new(input: &'input [u8], config: DecoderOptions) -> Self {
43        Self {
44            input,
45            config,
46            initial_len: input.len(),
47        }
48    }
49
50    /// Return a number of the decoded bytes by this decoder
51    #[must_use]
52    pub fn decoded_len(&self) -> usize {
53        self.initial_len - self.input.len()
54    }
55
56    fn parse_eoc(&mut self) -> Result<()> {
57        let (i, _) = nom::bytes::streaming::tag(EOC)(self.input)
58            .map_err(|e| DecodeError::map_nom_err(e, self.codec()))?;
59        self.input = i;
60        Ok(())
61    }
62
63    pub(crate) fn parse_value(&mut self, tag: Tag) -> Result<(Identifier, Option<&'input [u8]>)> {
64        let (input, (identifier, contents)) =
65            self::parser::parse_value(&self.config, self.input, Some(tag))?;
66        self.input = input;
67        Ok((identifier, contents))
68    }
69
70    pub(crate) fn parse_primitive_value(&mut self, tag: Tag) -> Result<(Identifier, &'input [u8])> {
71        let (input, (identifier, contents)) =
72            self::parser::parse_value(&self.config, self.input, Some(tag))?;
73        self.input = input;
74        match contents {
75            Some(contents) => Ok((identifier, contents)),
76            None => Err(BerDecodeErrorKind::IndefiniteLengthNotAllowed.into()),
77        }
78    }
79
80    /// Parses a constructed ASN.1 value, checking the `tag`, and optionally
81    /// checking if the identifier is marked as encoded. This should be true
82    /// in all cases except explicit prefixes.
83    fn parse_constructed_contents<D, F>(
84        &mut self,
85        tag: Tag,
86        check_identifier: bool,
87        decode_fn: F,
88    ) -> Result<D>
89    where
90        F: FnOnce(&mut Self) -> Result<D>,
91    {
92        let (identifier, contents) = self.parse_value(tag)?;
93
94        BerDecodeErrorKind::assert_tag(tag, identifier.tag)?;
95
96        if check_identifier && identifier.is_primitive() {
97            return Err(BerDecodeErrorKind::InvalidConstructedIdentifier.into());
98        }
99
100        let (streaming, contents) = match contents {
101            Some(contents) => (false, contents),
102            None => (true, self.input),
103        };
104
105        let mut inner = Self::new(contents, self.config);
106
107        let result = (decode_fn)(&mut inner)?;
108
109        if streaming {
110            self.input = inner.input;
111            self.parse_eoc()?;
112        } else if !inner.input.is_empty() {
113            return Err(DecodeError::unexpected_extra_data(
114                inner.input.len(),
115                self.codec(),
116            ));
117        }
118
119        Ok(result)
120    }
121    /// Decode an object identifier from a byte slice in BER format.
122    /// Function is public to be used by other codecs.
123    pub fn decode_object_identifier_from_bytes(
124        &self,
125        data: &[u8],
126    ) -> Result<crate::types::ObjectIdentifier, DecodeError> {
127        let (mut contents, root_octets) =
128            parser::parse_base128_number(data).map_err(|e| match e {
129                ParseNumberError::Nom(e) => DecodeError::map_nom_err(e, self.codec()),
130                ParseNumberError::Overflow => DecodeError::integer_overflow(32u32, self.codec()),
131            })?;
132        let first: u32;
133        let second: u32;
134        const MAX_OID_THRESHOLD: u32 = MAX_OID_SECOND_OCTET + 1;
135        if root_octets > MAX_OID_FIRST_OCTET * MAX_OID_THRESHOLD + MAX_OID_SECOND_OCTET {
136            first = MAX_OID_FIRST_OCTET;
137            second = root_octets - MAX_OID_FIRST_OCTET * MAX_OID_THRESHOLD;
138        } else {
139            second = root_octets % MAX_OID_THRESHOLD;
140            first = (root_octets - second) / MAX_OID_THRESHOLD;
141        }
142
143        // preallocate some capacity for the OID arcs, maxing out at 16 elements
144        // to prevent excessive preallocation from malformed or malicious
145        // packets
146        let mut buffer = alloc::vec::Vec::with_capacity(core::cmp::min(contents.len() + 2, 16));
147        buffer.push(first);
148        buffer.push(second);
149
150        while !contents.is_empty() {
151            let (c, number) = parser::parse_base128_number(contents).map_err(|e| match e {
152                ParseNumberError::Nom(e) => DecodeError::map_nom_err(e, self.codec()),
153                ParseNumberError::Overflow => DecodeError::integer_overflow(32u32, self.codec()),
154            })?;
155            contents = c;
156            buffer.push(number);
157        }
158        crate::types::ObjectIdentifier::new(buffer)
159            .ok_or_else(|| BerDecodeErrorKind::InvalidObjectIdentifier.into())
160    }
161    /// Parse any GeneralizedTime string, allowing for any from ASN.1 definition
162    /// TODO, move to type itself?
163    pub fn parse_any_generalized_time_string(
164        string: alloc::string::String,
165    ) -> Result<types::GeneralizedTime, DecodeError> {
166        // Reference https://obj-sys.com/asn1tutorial/node14.html
167        // If data contains ., 3 decimal places of seconds are expected
168        // If data contains explict Z, result is UTC
169        // If data contains + or -, explicit timezone is given
170        // If neither Z nor + nor -, purely local time is implied
171        let len = string.len();
172        // Helper function to deal with fractions and without timezone
173        let parse_without_timezone = |string: &str| -> Result<NaiveDateTime, DecodeError> {
174            // Handle both decimal cases (dot . and comma , )
175            let string: &str = &string.replace(',', ".");
176            if string.contains('.') {
177                // Use chrono to parse the string every time, since we don't the know the number of decimals places
178                NaiveDateTime::parse_from_str(string, "%Y%m%d%H%.f")
179                    .or_else(|_| NaiveDateTime::parse_from_str(string, "%Y%m%d%H%M%.f"))
180                    .or_else(|_| NaiveDateTime::parse_from_str(string, "%Y%m%d%H%M%S%.f"))
181                    .map_err(|_| BerDecodeErrorKind::invalid_date(string.to_string()).into())
182            } else {
183                let fmt_string = match string.len() {
184                    8 => "%Y%m%d",
185                    10 => "%Y%m%d%H",
186                    12 => "%Y%m%d%H%M",
187                    14 => "%Y%m%d%H%M%S",
188                    _ => "",
189                };
190                match fmt_string.len() {
191                    l if l > 0 => NaiveDateTime::parse_from_str(string, fmt_string)
192                        .map_err(|_| BerDecodeErrorKind::invalid_date(string.to_string()).into()),
193                    _ => Err(BerDecodeErrorKind::invalid_date(string.to_string()).into()),
194                }
195            }
196        };
197        if string.ends_with('Z') {
198            let naive = parse_without_timezone(&string[..len - 1])?;
199            return Ok(naive.and_utc().into());
200        }
201        // Check for timezone offset
202        if len > 5
203            && string
204                .chars()
205                .nth(len - 5)
206                .map_or(false, |c| c == '+' || c == '-')
207        {
208            let naive = parse_without_timezone(&string[..len - 5])?;
209            let sign = match string.chars().nth(len - 5) {
210                Some('+') => 1,
211                Some('-') => -1,
212                _ => {
213                    return Err(BerDecodeErrorKind::invalid_date(string.to_string()).into());
214                }
215            };
216            let offset_hours = string
217                .chars()
218                .skip(len - 4)
219                .take(2)
220                .collect::<alloc::string::String>()
221                .parse::<i32>()
222                .map_err(|_| BerDecodeErrorKind::invalid_date(string.to_string()))?;
223            let offset_minutes = string
224                .chars()
225                .skip(len - 2)
226                .take(2)
227                .collect::<alloc::string::String>()
228                .parse::<i32>()
229                .map_err(|_| BerDecodeErrorKind::invalid_date(string.to_string()))?;
230            if offset_hours > 23 || offset_minutes > 59 {
231                return Err(BerDecodeErrorKind::invalid_date(string.to_string()).into());
232            }
233            let offset = FixedOffset::east_opt(sign * (offset_hours * 3600 + offset_minutes * 60))
234                .ok_or_else(|| BerDecodeErrorKind::invalid_date(string.to_string()))?;
235            return Ok(TimeZone::from_local_datetime(&offset, &naive)
236                .single()
237                .ok_or_else(|| BerDecodeErrorKind::invalid_date(string.to_string()))?);
238        }
239
240        // Parse without timezone details
241        let naive = parse_without_timezone(&string)?;
242        Ok(naive.and_utc().into())
243    }
244    /// Enforce CER/DER restrictions defined in Section 11.7, strictly raise error on non-compliant
245    pub fn parse_canonical_generalized_time_string(
246        string: alloc::string::String,
247    ) -> Result<types::GeneralizedTime, DecodeError> {
248        let len = string.len();
249        // Helper function to deal with fractions of seconds and without timezone
250        let parse_without_timezone =
251            |string: &str| -> core::result::Result<NaiveDateTime, DecodeError> {
252                let len = string.len();
253                if string.contains('.') {
254                    // https://github.com/chronotope/chrono/issues/238#issuecomment-378737786
255                    NaiveDateTime::parse_from_str(string, "%Y%m%d%H%M%S%.f")
256                        .map_err(|_| BerDecodeErrorKind::invalid_date(string.to_string()).into())
257                } else if len == 14 {
258                    NaiveDateTime::parse_from_str(string, "%Y%m%d%H%M%S")
259                        .map_err(|_| BerDecodeErrorKind::invalid_date(string.to_string()).into())
260                } else {
261                    // CER/DER encoding rules don't allow for timezone offset +/
262                    // Or missing seconds/minutes/hours
263                    // Or comma , instead of dot .
264                    // Or local time without timezone
265                    Err(BerDecodeErrorKind::invalid_date(string.to_string()).into())
266                }
267            };
268        if string.ends_with('Z') {
269            let naive = parse_without_timezone(&string[..len - 1])?;
270            Ok(naive.and_utc().into())
271        } else {
272            Err(BerDecodeErrorKind::invalid_date(string.to_string()).into())
273        }
274    }
275    /// Parse any UTCTime string, can be any from ASN.1 definition
276    /// TODO, move to type itself?
277    pub fn parse_any_utc_time_string(
278        string: alloc::string::String,
279    ) -> Result<types::UtcTime, DecodeError> {
280        // When compared to GeneralizedTime, UTC time has no fractions.
281        let len = string.len();
282        // Largest string, e.g. "820102070000-0500".len() == 17
283        if len > 17 {
284            return Err(BerDecodeErrorKind::invalid_date(string.to_string()).into());
285        }
286        let format = if string.contains('Z') {
287            if len == 11 {
288                "%y%m%d%H%MZ"
289            } else {
290                "%y%m%d%H%M%SZ"
291            }
292        } else if len == 15 {
293            "%y%m%d%H%M%z"
294        } else {
295            "%y%m%d%H%M%S%z"
296        };
297        match len {
298            11 | 13 => {
299                let naive = NaiveDateTime::parse_from_str(&string, format)
300                    .map_err(|_| BerDecodeErrorKind::invalid_date(string.to_string()))?;
301                Ok(naive.and_utc())
302            }
303            15 | 17 => Ok(DateTime::parse_from_str(&string, format)
304                .map_err(|_| BerDecodeErrorKind::invalid_date(string.to_string()))?
305                .into()),
306            _ => Err(BerDecodeErrorKind::invalid_date(string.to_string()).into()),
307        }
308    }
309
310    /// Enforce CER/DER restrictions defined in Section 11.8, strictly raise error on non-compliant
311    pub fn parse_canonical_utc_time_string(string: &str) -> Result<types::UtcTime, DecodeError> {
312        let len = string.len();
313        if string.ends_with('Z') {
314            let naive = match len {
315                13 => NaiveDateTime::parse_from_str(string, "%y%m%d%H%M%SZ")
316                    .map_err(|_| BerDecodeErrorKind::invalid_date(string.to_string()))?,
317                _ => Err(BerDecodeErrorKind::invalid_date(string.to_string()))?,
318            };
319            Ok(naive.and_utc())
320        } else {
321            Err(BerDecodeErrorKind::invalid_date(string.to_string()).into())
322        }
323    }
324}
325
326impl<'input> crate::Decoder for Decoder<'input> {
327    type Error = DecodeError;
328
329    fn codec(&self) -> crate::Codec {
330        Self::codec(self)
331    }
332    fn decode_any(&mut self) -> Result<types::Any> {
333        let (mut input, (identifier, contents)) =
334            self::parser::parse_value(&self.config, self.input, None)?;
335
336        if contents.is_none() {
337            let (i, _) = self::parser::parse_encoded_value(
338                &self.config,
339                self.input,
340                identifier.tag,
341                |input, _| Ok(alloc::vec::Vec::from(input)),
342            )?;
343            input = i;
344        }
345        let diff = self.input.len() - input.len();
346        let contents = &self.input[..diff];
347        self.input = input;
348
349        Ok(types::Any {
350            contents: contents.to_vec(),
351        })
352    }
353
354    fn decode_bool(&mut self, tag: Tag) -> Result<bool> {
355        let (_, contents) = self.parse_primitive_value(tag)?;
356        DecodeError::assert_length(1, contents.len(), self.codec())?;
357        Ok(match contents[0] {
358            0 => false,
359            0xFF => true,
360            _ if self.config.encoding_rules.is_ber() => true,
361            _ => {
362                return Err(DecodeError::from_kind(
363                    DecodeErrorKind::InvalidBool { value: contents[0] },
364                    self.codec(),
365                ))
366            }
367        })
368    }
369
370    fn decode_enumerated<E: Enumerated>(&mut self, tag: Tag) -> Result<E> {
371        let discriminant = self.decode_integer::<isize>(tag, <_>::default())?;
372
373        E::from_discriminant(discriminant)
374            .ok_or_else(|| DecodeError::discriminant_value_not_found(discriminant, self.codec()))
375    }
376
377    fn decode_integer<I: types::IntegerType>(&mut self, tag: Tag, _: Constraints) -> Result<I> {
378        I::try_from_bytes(self.parse_primitive_value(tag)?.1, self.codec())
379    }
380
381    fn decode_octet_string(&mut self, tag: Tag, _: Constraints) -> Result<Vec<u8>> {
382        let (identifier, contents) = self.parse_value(tag)?;
383
384        if identifier.is_primitive() {
385            match contents {
386                Some(c) => Ok(c.to_vec()),
387                None => Err(BerDecodeErrorKind::IndefiniteLengthNotAllowed.into()),
388            }
389        } else if identifier.is_constructed() && self.config.encoding_rules.is_der() {
390            Err(DerDecodeErrorKind::ConstructedEncodingNotAllowed.into())
391        } else {
392            let mut buffer = Vec::new();
393
394            if let Some(mut contents) = contents {
395                while !contents.is_empty() {
396                    let (c, mut vec) = self::parser::parse_encoded_value(
397                        &self.config,
398                        contents,
399                        Tag::OCTET_STRING,
400                        |input, _| Ok(alloc::vec::Vec::from(input)),
401                    )?;
402                    contents = c;
403
404                    buffer.append(&mut vec);
405                }
406            } else {
407                while !self.input.starts_with(EOC) {
408                    let (c, mut vec) = self::parser::parse_encoded_value(
409                        &self.config,
410                        self.input,
411                        Tag::OCTET_STRING,
412                        |input, _| Ok(alloc::vec::Vec::from(input)),
413                    )?;
414                    self.input = c;
415
416                    buffer.append(&mut vec);
417                }
418
419                self.parse_eoc()?;
420            }
421
422            Ok(buffer)
423        }
424    }
425
426    fn decode_null(&mut self, tag: Tag) -> Result<()> {
427        let (_, contents) = self.parse_primitive_value(tag)?;
428        DecodeError::assert_length(0, contents.len(), self.codec())?;
429        Ok(())
430    }
431
432    fn decode_object_identifier(&mut self, tag: Tag) -> Result<crate::types::ObjectIdentifier> {
433        let contents = self.parse_primitive_value(tag)?.1;
434        self.decode_object_identifier_from_bytes(contents)
435    }
436
437    fn decode_bit_string(&mut self, tag: Tag, _: Constraints) -> Result<types::BitString> {
438        let (input, bs) =
439            self::parser::parse_encoded_value(&self.config, self.input, tag, |input, codec| {
440                let Some(unused_bits) = input.first().copied() else {
441                    return Ok(types::BitString::new());
442                };
443
444                match unused_bits {
445                    // TODO: https://github.com/myrrlyn/bitvec/issues/72
446                    bits @ 0..=7 => {
447                        let mut buffer = input[1..].to_owned();
448                        if let Some(last) = buffer.last_mut() {
449                            *last &= !((1 << bits) - 1);
450                        }
451
452                        let mut string = types::BitString::from_vec(buffer);
453                        let bit_length = string
454                            .len()
455                            .checked_sub(bits as usize)
456                            .ok_or_else(|| DecodeError::invalid_bit_string(unused_bits, codec))?;
457                        string.truncate(bit_length);
458
459                        Ok(string)
460                    }
461                    _ => Err(DecodeError::invalid_bit_string(unused_bits, codec)),
462                }
463            })?;
464
465        self.input = input;
466        Ok(bs)
467    }
468
469    fn decode_visible_string(
470        &mut self,
471        tag: Tag,
472        constraints: Constraints,
473    ) -> Result<types::VisibleString, Self::Error> {
474        types::VisibleString::try_from(self.decode_octet_string(tag, constraints)?).map_err(|e| {
475            DecodeError::string_conversion_failed(
476                types::Tag::VISIBLE_STRING,
477                e.to_string(),
478                self.codec(),
479            )
480        })
481    }
482
483    fn decode_ia5_string(
484        &mut self,
485        tag: Tag,
486        constraints: Constraints,
487    ) -> Result<types::Ia5String> {
488        types::Ia5String::try_from(self.decode_octet_string(tag, constraints)?).map_err(|e| {
489            DecodeError::string_conversion_failed(
490                types::Tag::IA5_STRING,
491                e.to_string(),
492                self.codec(),
493            )
494        })
495    }
496
497    fn decode_printable_string(
498        &mut self,
499        tag: Tag,
500        constraints: Constraints,
501    ) -> Result<types::PrintableString> {
502        types::PrintableString::try_from(self.decode_octet_string(tag, constraints)?).map_err(|e| {
503            DecodeError::string_conversion_failed(
504                types::Tag::PRINTABLE_STRING,
505                e.to_string(),
506                self.codec(),
507            )
508        })
509    }
510
511    fn decode_numeric_string(
512        &mut self,
513        tag: Tag,
514        constraints: Constraints,
515    ) -> Result<types::NumericString> {
516        types::NumericString::try_from(self.decode_octet_string(tag, constraints)?).map_err(|e| {
517            DecodeError::string_conversion_failed(
518                types::Tag::NUMERIC_STRING,
519                e.to_string(),
520                self.codec(),
521            )
522        })
523    }
524
525    fn decode_teletex_string(
526        &mut self,
527        tag: Tag,
528        constraints: Constraints,
529    ) -> Result<types::TeletexString> {
530        Ok(types::TeletexString::from(
531            self.decode_octet_string(tag, constraints)?,
532        ))
533    }
534
535    fn decode_bmp_string(&mut self, _: Tag, _constraints: Constraints) -> Result<types::BmpString> {
536        todo!()
537    }
538
539    fn decode_utf8_string(
540        &mut self,
541        tag: Tag,
542        constraints: Constraints,
543    ) -> Result<types::Utf8String> {
544        let vec = self.decode_octet_string(tag, constraints)?;
545        types::Utf8String::from_utf8(vec).map_err(|e| {
546            DecodeError::string_conversion_failed(
547                types::Tag::UTF8_STRING,
548                e.to_string(),
549                self.codec(),
550            )
551        })
552    }
553
554    fn decode_general_string(
555        &mut self,
556        tag: Tag,
557        constraints: Constraints,
558    ) -> Result<types::GeneralString> {
559        <types::GeneralString>::try_from(self.decode_octet_string(tag, constraints)?).map_err(|e| {
560            DecodeError::string_conversion_failed(
561                types::Tag::GENERAL_STRING,
562                e.to_string(),
563                self.codec(),
564            )
565        })
566    }
567
568    fn decode_generalized_time(&mut self, tag: Tag) -> Result<types::GeneralizedTime> {
569        let string = self.decode_utf8_string(tag, <_>::default())?;
570        if self.config.encoding_rules.is_ber() {
571            Self::parse_any_generalized_time_string(string)
572        } else {
573            Self::parse_canonical_generalized_time_string(string)
574        }
575    }
576
577    fn decode_utc_time(&mut self, tag: Tag) -> Result<types::UtcTime> {
578        // Reference https://obj-sys.com/asn1tutorial/node15.html
579        let string = self.decode_utf8_string(tag, <_>::default())?;
580        if self.config.encoding_rules.is_ber() {
581            Self::parse_any_utc_time_string(string)
582        } else {
583            Self::parse_canonical_utc_time_string(&string)
584        }
585    }
586
587    fn decode_sequence_of<D: Decode>(
588        &mut self,
589        tag: Tag,
590        _: Constraints,
591    ) -> Result<Vec<D>, Self::Error> {
592        self.parse_constructed_contents(tag, true, |decoder| {
593            let mut items = Vec::new();
594
595            if decoder.input.is_empty() {
596                return Ok(items);
597            }
598
599            while let Ok(item) = D::decode(decoder) {
600                items.push(item);
601
602                if decoder.input.is_empty() {
603                    return Ok(items);
604                }
605            }
606
607            Ok(items)
608        })
609    }
610
611    fn decode_set_of<D: Decode + Ord>(
612        &mut self,
613        tag: Tag,
614        _: Constraints,
615    ) -> Result<types::SetOf<D>, Self::Error> {
616        self.parse_constructed_contents(tag, true, |decoder| {
617            let mut items = types::SetOf::new();
618
619            while let Ok(item) = D::decode(decoder) {
620                items.insert(item);
621            }
622
623            Ok(items)
624        })
625    }
626
627    fn decode_sequence<
628        D: crate::types::Constructed,
629        DF: FnOnce() -> D,
630        F: FnOnce(&mut Self) -> Result<D>,
631    >(
632        &mut self,
633        tag: Tag,
634        default_initializer_fn: Option<DF>,
635        decode_fn: F,
636    ) -> Result<D> {
637        self.parse_constructed_contents(tag, true, |decoder| {
638            // If there are no fields, or the input is empty and we know that
639            // all fields are optional or default fields, we call the default
640            // initializer and skip calling the decode function at all.
641            if D::FIELDS.is_empty()
642                || (D::FIELDS.len() == D::FIELDS.number_of_optional_and_default_fields()
643                    && decoder.input.is_empty())
644            {
645                if let Some(default_initializer_fn) = default_initializer_fn {
646                    return Ok((default_initializer_fn)());
647                }
648                return Err(DecodeError::from_kind(
649                    DecodeErrorKind::UnexpectedEmptyInput,
650                    decoder.codec(),
651                ));
652            }
653            (decode_fn)(decoder)
654        })
655    }
656
657    fn decode_explicit_prefix<D: Decode>(&mut self, tag: Tag) -> Result<D> {
658        self.parse_constructed_contents(tag, false, D::decode)
659    }
660
661    fn decode_set<FIELDS, SET, D, F>(
662        &mut self,
663        tag: Tag,
664        _decode_fn: D,
665        field_fn: F,
666    ) -> Result<SET, Self::Error>
667    where
668        SET: Decode + crate::types::Constructed,
669        FIELDS: Decode,
670        D: Fn(&mut Self, usize, Tag) -> Result<FIELDS, Self::Error>,
671        F: FnOnce(Vec<FIELDS>) -> Result<SET, Self::Error>,
672    {
673        self.parse_constructed_contents(tag, true, |decoder| {
674            let mut fields = Vec::new();
675
676            while let Ok(value) = FIELDS::decode(decoder) {
677                fields.push(value);
678            }
679
680            (field_fn)(fields)
681        })
682    }
683
684    fn decode_optional<D: Decode>(&mut self) -> Result<Option<D>, Self::Error> {
685        if D::TAG == Tag::EOC {
686            Ok(D::decode(self).ok())
687        } else {
688            self.decode_optional_with_tag(D::TAG)
689        }
690    }
691
692    /// Decode an the optional value in a `SEQUENCE` or `SET` with `tag`.
693    /// Passing the correct tag is required even when used with codecs where
694    /// the tag is not present.
695    fn decode_optional_with_tag<D: Decode>(&mut self, tag: Tag) -> Result<Option<D>, Self::Error> {
696        Ok(D::decode_with_tag(self, tag).ok())
697    }
698
699    fn decode_optional_with_constraints<D: Decode>(
700        &mut self,
701        constraints: Constraints,
702    ) -> Result<Option<D>, Self::Error> {
703        Ok(D::decode_with_constraints(self, constraints).ok())
704    }
705
706    fn decode_optional_with_tag_and_constraints<D: Decode>(
707        &mut self,
708        tag: Tag,
709        constraints: Constraints,
710    ) -> Result<Option<D>, Self::Error> {
711        Ok(D::decode_with_tag_and_constraints(self, tag, constraints).ok())
712    }
713
714    fn decode_choice<D>(&mut self, _: Constraints) -> Result<D, Self::Error>
715    where
716        D: crate::types::DecodeChoice,
717    {
718        let (_, identifier) = parser::parse_identifier_octet(self.input).map_err(|e| match e {
719            ParseNumberError::Nom(e) => DecodeError::map_nom_err(e, self.codec()),
720            ParseNumberError::Overflow => DecodeError::integer_overflow(32u32, self.codec()),
721        })?;
722        D::from_tag(self, identifier.tag)
723    }
724
725    fn decode_extension_addition_with_constraints<D>(
726        &mut self,
727        // Constraints are irrelevant using BER
728        _: Constraints,
729    ) -> core::result::Result<Option<D>, Self::Error>
730    where
731        D: Decode,
732    {
733        <Option<D>>::decode(self)
734    }
735
736    fn decode_extension_addition_group<D: Decode + crate::types::Constructed>(
737        &mut self,
738    ) -> Result<Option<D>, Self::Error> {
739        <Option<D>>::decode(self)
740    }
741}
742
743#[cfg(test)]
744mod tests {
745    use alloc::string::String;
746
747    #[derive(Clone, Copy, Hash, Debug, PartialEq)]
748    struct C2;
749    impl AsnType for C2 {
750        const TAG: Tag = Tag::new(Class::Context, 2);
751    }
752
753    #[derive(Clone, Copy, Hash, Debug, PartialEq)]
754    struct A3;
755    impl AsnType for A3 {
756        const TAG: Tag = Tag::new(Class::Application, 3);
757    }
758
759    #[derive(Clone, Copy, Hash, Debug, PartialEq)]
760    struct A7;
761    impl AsnType for A7 {
762        const TAG: Tag = Tag::new(Class::Application, 7);
763    }
764
765    use super::*;
766    use crate::types::*;
767
768    fn decode<T: crate::Decode>(input: &[u8]) -> Result<T, DecodeError> {
769        let mut decoder = self::Decoder::new(input, self::DecoderOptions::ber());
770        match T::decode(&mut decoder) {
771            Ok(result) => {
772                assert_eq!(decoder.decoded_len(), input.len());
773                Ok(result)
774            }
775            Err(e) => Err(e),
776        }
777    }
778
779    #[test]
780    fn boolean() {
781        assert!(decode::<bool>(&[0x01, 0x01, 0xff]).unwrap());
782        assert!(!decode::<bool>(&[0x01, 0x01, 0x00]).unwrap());
783    }
784
785    #[test]
786    fn tagged_boolean() {
787        assert_eq!(
788            Explicit::<C2, _>::new(true),
789            decode(&[0xa2, 0x03, 0x01, 0x01, 0xff]).unwrap()
790        );
791    }
792
793    #[test]
794    fn integer() {
795        assert_eq!(
796            32768,
797            decode::<i32>(&[0x02, 0x03, 0x00, 0x80, 0x00,]).unwrap()
798        );
799        assert_eq!(32767, decode::<i32>(&[0x02, 0x02, 0x7f, 0xff]).unwrap());
800        assert_eq!(256, decode::<i16>(&[0x02, 0x02, 0x01, 0x00]).unwrap());
801        assert_eq!(255, decode::<i16>(&[0x02, 0x02, 0x00, 0xff]).unwrap());
802        assert_eq!(128, decode::<i16>(&[0x02, 0x02, 0x00, 0x80]).unwrap());
803        assert_eq!(127, decode::<i8>(&[0x02, 0x01, 0x7f]).unwrap());
804        assert_eq!(1, decode::<i8>(&[0x02, 0x01, 0x01]).unwrap());
805        assert_eq!(0, decode::<i8>(&[0x02, 0x01, 0x00]).unwrap());
806        assert_eq!(-1, decode::<i8>(&[0x02, 0x01, 0xff]).unwrap());
807        assert_eq!(-128, decode::<i16>(&[0x02, 0x01, 0x80]).unwrap());
808        assert_eq!(-129i16, decode::<i16>(&[0x02, 0x02, 0xff, 0x7f]).unwrap());
809        assert_eq!(-256i16, decode::<i16>(&[0x02, 0x02, 0xff, 0x00]).unwrap());
810        assert_eq!(-32768i32, decode::<i32>(&[0x02, 0x02, 0x80, 0x00]).unwrap());
811        assert_eq!(
812            -32769i32,
813            decode::<i32>(&[0x02, 0x03, 0xff, 0x7f, 0xff]).unwrap()
814        );
815
816        let mut data = [0u8; 261];
817        data[0] = 0x02;
818        data[1] = 0x82;
819        data[2] = 0x01;
820        data[3] = 0x01;
821        data[4] = 0x01;
822        let mut bigint = num_bigint::BigInt::from(1);
823        bigint <<= 2048;
824        assert_eq!(bigint, decode::<num_bigint::BigInt>(&data).unwrap());
825    }
826
827    #[test]
828    fn octet_string() {
829        let octet_string = types::OctetString::from(alloc::vec![1, 2, 3, 4, 5, 6]);
830        let primitive_encoded = &[0x4, 0x6, 1, 2, 3, 4, 5, 6];
831        let constructed_encoded = &[0x24, 0x80, 0x4, 0x4, 1, 2, 3, 4, 0x4, 0x2, 5, 6, 0x0, 0x0];
832
833        assert_eq!(
834            octet_string,
835            decode::<types::OctetString>(primitive_encoded).unwrap()
836        );
837        assert_eq!(
838            octet_string,
839            decode::<types::OctetString>(constructed_encoded).unwrap()
840        );
841    }
842
843    #[test]
844    fn bit_string() {
845        let mut bitstring =
846            types::BitString::from_vec([0x0A, 0x3B, 0x5F, 0x29, 0x1C, 0xD0][..].to_owned());
847        bitstring.truncate(bitstring.len() - 4);
848
849        let primitive_encoded: types::BitString =
850            decode(&[0x03, 0x07, 0x04, 0x0A, 0x3B, 0x5F, 0x29, 0x1C, 0xD0][..]).unwrap();
851
852        let constructed_encoded: types::BitString = decode(
853            &[
854                0x23, 0x80, // TAG + LENGTH
855                0x03, 0x03, 0x00, 0x0A, 0x3B, // Part 1
856                0x03, 0x05, 0x04, 0x5F, 0x29, 0x1C, 0xD0, // Part 2
857                0x00, 0x00, // EOC
858            ][..],
859        )
860        .unwrap();
861
862        assert_eq!(bitstring, primitive_encoded);
863        assert_eq!(bitstring, constructed_encoded);
864    }
865
866    #[test]
867    fn utf8_string() {
868        let name = String::from("Jones");
869        let primitive = &[0x0C, 0x05, 0x4A, 0x6F, 0x6E, 0x65, 0x73];
870        let definite_constructed = &[
871            0x2C, 0x09, // TAG + LENGTH
872            0x04, 0x03, // PART 1 TLV
873            0x4A, 0x6F, 0x6E, 0x04, 0x02, // PART 2 TLV
874            0x65, 0x73,
875        ];
876        let indefinite_constructed = &[
877            0x2C, 0x80, // TAG + LENGTH
878            0x04, 0x03, // PART 1 TLV
879            0x4A, 0x6F, 0x6E, 0x04, 0x02, // PART 2 TLV
880            0x65, 0x73, 0x00, 0x00,
881        ];
882
883        assert_eq!(name, decode::<String>(primitive).unwrap());
884        assert_eq!(name, decode::<String>(definite_constructed).unwrap());
885        assert_eq!(name, decode::<String>(indefinite_constructed).unwrap());
886    }
887
888    #[test]
889    fn utc_time() {
890        let time =
891            crate::types::GeneralizedTime::parse_from_str("991231235959+0000", "%y%m%d%H%M%S%z")
892                .unwrap();
893        // 991231235959Z
894        let has_z = &[
895            0x17, 0x0D, 0x39, 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39,
896            0x5A,
897        ];
898        // 991231235959+0000
899        let has_noz = &[
900            0x17, 0x11, 0x39, 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39,
901            0x2B, 0x30, 0x30, 0x30, 0x30,
902        ];
903        assert_eq!(
904            time,
905            decode::<chrono::DateTime::<chrono::Utc>>(has_z).unwrap()
906        );
907
908        assert_eq!(
909            time,
910            crate::der::decode::<crate::types::UtcTime>(has_z).unwrap()
911        );
912
913        assert_eq!(
914            time,
915            decode::<chrono::DateTime::<chrono::Utc>>(has_noz).unwrap()
916        );
917        assert!(crate::der::decode::<crate::types::UtcTime>(has_noz).is_err());
918    }
919
920    #[test]
921    fn generalized_time() {
922        let time = crate::types::GeneralizedTime::parse_from_str(
923            "20001231205959.999+0000",
924            "%Y%m%d%H%M%S%.3f%z",
925        )
926        .unwrap();
927        let has_z = &[
928            0x18, 0x13, 0x32, 0x30, 0x30, 0x30, 0x31, 0x32, 0x33, 0x31, 0x32, 0x30, 0x35, 0x39,
929            0x35, 0x39, 0x2E, 0x39, 0x39, 0x39, 0x5A,
930        ];
931        assert_eq!(
932            time,
933            decode::<chrono::DateTime::<chrono::FixedOffset>>(has_z).unwrap()
934        );
935    }
936
937    #[test]
938    fn sequence_of() {
939        let vec = alloc::vec!["Jon", "es"];
940        let from_raw: Vec<String> = decode(
941            &[
942                0x30, 0x9, 0x0C, 0x03, 0x4A, 0x6F, 0x6E, 0x0C, 0x02, 0x65, 0x73,
943            ][..],
944        )
945        .unwrap();
946
947        assert_eq!(vec, from_raw);
948    }
949
950    #[test]
951    fn sequence() {
952        use types::Ia5String;
953        // Taken from examples in 8.9 of X.690.
954        #[derive(Debug, PartialEq)]
955        struct Foo {
956            name: Ia5String,
957            ok: bool,
958        }
959
960        impl types::Constructed for Foo {
961            const FIELDS: types::fields::Fields = types::fields::Fields::from_static(&[
962                types::fields::Field::new_required(Ia5String::TAG, Ia5String::TAG_TREE, "name"),
963                types::fields::Field::new_required(bool::TAG, bool::TAG_TREE, "ok"),
964            ]);
965        }
966
967        impl types::AsnType for Foo {
968            const TAG: Tag = Tag::SEQUENCE;
969        }
970
971        impl Decode for Foo {
972            fn decode_with_tag_and_constraints<D: crate::Decoder>(
973                decoder: &mut D,
974                tag: Tag,
975                _: Constraints,
976            ) -> Result<Self, D::Error> {
977                decoder.decode_sequence(tag, None::<fn() -> Self>, |sequence| {
978                    let name: Ia5String = Ia5String::decode(sequence)?;
979                    let ok: bool = bool::decode(sequence)?;
980                    Ok(Self { name, ok })
981                })
982            }
983        }
984
985        let foo = Foo {
986            name: String::from("Smith").try_into().unwrap(),
987            ok: true,
988        };
989        let bytes = &[
990            0x30, 0x0A, // TAG + LENGTH
991            0x16, 0x05, 0x53, 0x6d, 0x69, 0x74, 0x68, // Ia5String "Smith"
992            0x01, 0x01, 0xff, // BOOL True
993        ];
994
995        assert_eq!(foo, decode(bytes).unwrap());
996    }
997
998    #[test]
999    fn tagging() {
1000        type Type1 = VisibleString;
1001        type Type2 = Implicit<A3, Type1>;
1002        type Type3 = Explicit<C2, Type2>;
1003        type Type4 = Implicit<A7, Type3>;
1004        type Type5 = Implicit<C2, Type2>;
1005
1006        let jones = String::from("Jones");
1007        let jones1 = Type1::try_from(jones).unwrap();
1008        let jones2 = Type2::from(jones1.clone());
1009        let jones3 = Type3::from(jones2.clone());
1010        let jones4 = Type4::from(jones3.clone());
1011        let jones5 = Type5::from(jones2.clone());
1012
1013        assert_eq!(
1014            jones1,
1015            decode(&[0x1A, 0x05, 0x4A, 0x6F, 0x6E, 0x65, 0x73]).unwrap()
1016        );
1017        assert_eq!(
1018            jones2,
1019            decode(&[0x43, 0x05, 0x4A, 0x6F, 0x6E, 0x65, 0x73]).unwrap()
1020        );
1021        assert_eq!(
1022            jones3,
1023            decode(&[0xa2, 0x07, 0x43, 0x5, 0x4A, 0x6F, 0x6E, 0x65, 0x73]).unwrap()
1024        );
1025        assert_eq!(
1026            jones4,
1027            decode(&[0x67, 0x07, 0x43, 0x5, 0x4A, 0x6F, 0x6E, 0x65, 0x73]).unwrap()
1028        );
1029        assert_eq!(
1030            jones5,
1031            decode(&[0x82, 0x05, 0x4A, 0x6F, 0x6E, 0x65, 0x73]).unwrap()
1032        );
1033    }
1034
1035    #[test]
1036    fn flip1() {
1037        let _ = decode::<Open>(&[
1038            0x10, 0x10, 0x23, 0x00, 0xfe, 0x7f, 0x10, 0x03, 0x00, 0xff, 0xe4, 0x04, 0x50, 0x10,
1039            0x50, 0x10, 0x10, 0x10,
1040        ]);
1041    }
1042
1043    #[test]
1044    fn any() {
1045        let expected = &[0x1A, 0x05, 0x4A, 0x6F, 0x6E, 0x65, 0x73];
1046        assert_eq!(
1047            Any {
1048                contents: expected.to_vec()
1049            },
1050            decode(expected).unwrap()
1051        );
1052    }
1053
1054    #[test]
1055    fn any_indefinite() {
1056        let any = &[
1057            0x30, 0x80, 0x2C, 0x80, 0x04, 0x03, 0x4A, 0x6F, 0x6E, 0x04, 0x02, 0x65, 0x73, 0x00,
1058            0x00, 0x00, 0x00,
1059        ];
1060        assert_eq!(
1061            Any {
1062                contents: any.to_vec()
1063            },
1064            decode(any).unwrap(),
1065        );
1066    }
1067
1068    #[test]
1069    fn any_indefinite_fail_no_eoc() {
1070        let any = &[
1071            0x30, 0x80, 0x2C, 0x80, 0x04, 0x03, 0x4A, 0x6F, 0x6E, 0x04, 0x02, 0x65, 0x73, 0x00,
1072            0x00,
1073        ];
1074        assert!(decode::<Any>(any).is_err());
1075    }
1076
1077    #[test]
1078    fn decoding_oid() {
1079        use crate::Decoder;
1080
1081        let mut decoder =
1082            super::Decoder::new(&[0x06, 0x03, 0x88, 0x37, 0x01], DecoderOptions::der());
1083        let oid = decoder.decode_object_identifier(Tag::OBJECT_IDENTIFIER);
1084        assert!(oid.is_ok());
1085        let oid = oid.unwrap();
1086        assert_eq!(ObjectIdentifier::new([2, 999, 1].to_vec()).unwrap(), oid);
1087    }
1088}