1mod 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
27pub struct Decoder<'input> {
29 input: &'input [u8],
30 config: DecoderOptions,
31 initial_len: usize,
32}
33
34impl<'input> Decoder<'input> {
35 #[must_use]
37 pub fn codec(&self) -> crate::Codec {
38 self.config.current_codec()
39 }
40 #[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 #[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 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 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 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 pub fn parse_any_generalized_time_string(
164 string: alloc::string::String,
165 ) -> Result<types::GeneralizedTime, DecodeError> {
166 let len = string.len();
172 let parse_without_timezone = |string: &str| -> Result<NaiveDateTime, DecodeError> {
174 let string: &str = &string.replace(',', ".");
176 if string.contains('.') {
177 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 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 let naive = parse_without_timezone(&string)?;
242 Ok(naive.and_utc().into())
243 }
244 pub fn parse_canonical_generalized_time_string(
246 string: alloc::string::String,
247 ) -> Result<types::GeneralizedTime, DecodeError> {
248 let len = string.len();
249 let parse_without_timezone =
251 |string: &str| -> core::result::Result<NaiveDateTime, DecodeError> {
252 let len = string.len();
253 if string.contains('.') {
254 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 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 pub fn parse_any_utc_time_string(
278 string: alloc::string::String,
279 ) -> Result<types::UtcTime, DecodeError> {
280 let len = string.len();
282 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 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 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 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 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 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,
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, 0x03, 0x03, 0x00, 0x0A, 0x3B, 0x03, 0x05, 0x04, 0x5F, 0x29, 0x1C, 0xD0, 0x00, 0x00, ][..],
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, 0x04, 0x03, 0x4A, 0x6F, 0x6E, 0x04, 0x02, 0x65, 0x73,
875 ];
876 let indefinite_constructed = &[
877 0x2C, 0x80, 0x04, 0x03, 0x4A, 0x6F, 0x6E, 0x04, 0x02, 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 let has_z = &[
895 0x17, 0x0D, 0x39, 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39,
896 0x5A,
897 ];
898 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 #[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, 0x16, 0x05, 0x53, 0x6d, 0x69, 0x74, 0x68, 0x01, 0x01, 0xff, ];
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}