1use crate::{calendar, time, Error};
16pub(crate) use ring::io::der::{CONSTRUCTED, CONTEXT_SPECIFIC};
17
18#[allow(clippy::upper_case_acronyms)]
20#[derive(Clone, Copy, Eq, PartialEq)]
21#[repr(u8)]
22pub(crate) enum Tag {
23 Boolean = 0x01,
24 Integer = 0x02,
25 BitString = 0x03,
26 OctetString = 0x04,
27 OID = 0x06,
28 Enum = 0x0A,
29 Sequence = CONSTRUCTED | 0x10, UTCTime = 0x17,
31 GeneralizedTime = 0x18,
32
33 #[allow(clippy::identity_op)]
34 ContextSpecificConstructed0 = CONTEXT_SPECIFIC | CONSTRUCTED | 0,
35 ContextSpecificConstructed1 = CONTEXT_SPECIFIC | CONSTRUCTED | 1,
36 ContextSpecificConstructed3 = CONTEXT_SPECIFIC | CONSTRUCTED | 3,
37}
38
39impl From<Tag> for usize {
40 #[allow(clippy::as_conversions)]
41 fn from(tag: Tag) -> Self {
42 tag as Self
43 }
44}
45
46impl From<Tag> for u8 {
47 #[allow(clippy::as_conversions)]
48 fn from(tag: Tag) -> Self {
49 tag as Self
50 } }
52
53#[inline(always)]
54pub(crate) fn expect_tag_and_get_value<'a>(
55 input: &mut untrusted::Reader<'a>,
56 tag: Tag,
57) -> Result<untrusted::Input<'a>, Error> {
58 let (actual_tag, inner) = read_tag_and_get_value(input)?;
59 if usize::from(tag) != usize::from(actual_tag) {
60 return Err(Error::BadDer);
61 }
62 Ok(inner)
63}
64
65#[inline(always)]
66pub(crate) fn expect_tag_and_get_value_limited<'a>(
67 input: &mut untrusted::Reader<'a>,
68 tag: Tag,
69 size_limit: usize,
70) -> Result<untrusted::Input<'a>, Error> {
71 let (actual_tag, inner) = read_tag_and_get_value_limited(input, size_limit)?;
72 if usize::from(tag) != usize::from(actual_tag) {
73 return Err(Error::BadDer);
74 }
75 Ok(inner)
76}
77
78pub(crate) fn nested_limited<'a, R, E: Copy>(
79 input: &mut untrusted::Reader<'a>,
80 tag: Tag,
81 error: E,
82 decoder: impl FnOnce(&mut untrusted::Reader<'a>) -> Result<R, E>,
83 size_limit: usize,
84) -> Result<R, E> {
85 expect_tag_and_get_value_limited(input, tag, size_limit)
86 .map_err(|_| error)?
87 .read_all(error, decoder)
88}
89
90pub(crate) fn nested<'a, R, E: Copy>(
93 input: &mut untrusted::Reader<'a>,
94 tag: Tag,
95 error: E,
96 decoder: impl FnOnce(&mut untrusted::Reader<'a>) -> Result<R, E>,
97) -> Result<R, E> {
98 nested_limited(input, tag, error, decoder, TWO_BYTE_DER_SIZE)
99}
100
101pub(crate) struct Value<'a> {
102 value: untrusted::Input<'a>,
103}
104
105impl<'a> Value<'a> {
106 pub(crate) fn value(&self) -> untrusted::Input<'a> {
107 self.value
108 }
109}
110
111pub(crate) fn expect_tag<'a>(
112 input: &mut untrusted::Reader<'a>,
113 tag: Tag,
114) -> Result<Value<'a>, Error> {
115 let (actual_tag, value) = read_tag_and_get_value(input)?;
116 if usize::from(tag) != usize::from(actual_tag) {
117 return Err(Error::BadDer);
118 }
119
120 Ok(Value { value })
121}
122
123#[inline(always)]
124pub(crate) fn read_tag_and_get_value<'a>(
125 input: &mut untrusted::Reader<'a>,
126) -> Result<(u8, untrusted::Input<'a>), Error> {
127 read_tag_and_get_value_limited(input, TWO_BYTE_DER_SIZE)
128}
129
130#[inline(always)]
131pub(crate) fn read_tag_and_get_value_limited<'a>(
132 input: &mut untrusted::Reader<'a>,
133 size_limit: usize,
134) -> Result<(u8, untrusted::Input<'a>), Error> {
135 let tag = input.read_byte()?;
136 if (tag & HIGH_TAG_RANGE_START) == HIGH_TAG_RANGE_START {
137 return Err(Error::BadDer); }
139
140 let length = match input.read_byte()? {
144 n if (n & SHORT_FORM_LEN_MAX) == 0 => usize::from(n),
145 LONG_FORM_LEN_ONE_BYTE => {
146 let length_byte = input.read_byte()?;
147 if length_byte < SHORT_FORM_LEN_MAX {
148 return Err(Error::BadDer); }
150 usize::from(length_byte)
151 }
152 LONG_FORM_LEN_TWO_BYTES => {
153 let length_byte_one = usize::from(input.read_byte()?);
154 let length_byte_two = usize::from(input.read_byte()?);
155 let combined = (length_byte_one << 8) | length_byte_two;
156 if combined <= LONG_FORM_LEN_ONE_BYTE_MAX {
157 return Err(Error::BadDer); }
159 combined
160 }
161 LONG_FORM_LEN_THREE_BYTES => {
162 let length_byte_one = usize::from(input.read_byte()?);
163 let length_byte_two = usize::from(input.read_byte()?);
164 let length_byte_three = usize::from(input.read_byte()?);
165 let combined = (length_byte_one << 16) | (length_byte_two << 8) | length_byte_three;
166 if combined <= LONG_FORM_LEN_TWO_BYTES_MAX {
167 return Err(Error::BadDer); }
169 combined
170 }
171 LONG_FORM_LEN_FOUR_BYTES => {
172 let length_byte_one = usize::from(input.read_byte()?);
173 let length_byte_two = usize::from(input.read_byte()?);
174 let length_byte_three = usize::from(input.read_byte()?);
175 let length_byte_four = usize::from(input.read_byte()?);
176 let combined = (length_byte_one << 24)
177 | (length_byte_two << 16)
178 | (length_byte_three << 8)
179 | length_byte_four;
180 if combined <= LONG_FORM_LEN_THREE_BYTES_MAX {
181 return Err(Error::BadDer); }
183 combined
184 }
185 _ => {
186 return Err(Error::BadDer); }
188 };
189
190 if length >= size_limit {
191 return Err(Error::BadDer); }
193
194 let inner = input.read_bytes(length)?;
195 Ok((tag, inner))
196}
197
198pub(crate) const TWO_BYTE_DER_SIZE: usize = LONG_FORM_LEN_TWO_BYTES_MAX;
204
205pub(crate) const MAX_DER_SIZE: usize = LONG_FORM_LEN_FOUR_BYTES_MAX;
210
211const HIGH_TAG_RANGE_START: u8 = 31;
216
217const SHORT_FORM_LEN_MAX: u8 = 128;
221
222const LONG_FORM_LEN_ONE_BYTE: u8 = 0x81;
224
225const LONG_FORM_LEN_ONE_BYTE_MAX: usize = 0xff;
227
228const LONG_FORM_LEN_TWO_BYTES: u8 = 0x82;
230
231const LONG_FORM_LEN_TWO_BYTES_MAX: usize = 0xff_ff;
233
234const LONG_FORM_LEN_THREE_BYTES: u8 = 0x83;
236
237const LONG_FORM_LEN_THREE_BYTES_MAX: usize = 0xff_ff_ff;
239
240const LONG_FORM_LEN_FOUR_BYTES: u8 = 0x84;
242
243const LONG_FORM_LEN_FOUR_BYTES_MAX: usize = 0xff_ff_ff_ff;
245
246pub(crate) fn nested_of_mut<'a, E>(
249 input: &mut untrusted::Reader<'a>,
250 outer_tag: Tag,
251 inner_tag: Tag,
252 error: E,
253 mut decoder: impl FnMut(&mut untrusted::Reader<'a>) -> Result<(), E>,
254) -> Result<(), E>
255where
256 E: Copy,
257{
258 nested(input, outer_tag, error, |outer| {
259 loop {
260 nested(outer, inner_tag, error, |inner| decoder(inner))?;
261 if outer.at_end() {
262 break;
263 }
264 }
265 Ok(())
266 })
267}
268
269pub(crate) fn bit_string_with_no_unused_bits<'a>(
270 input: &mut untrusted::Reader<'a>,
271) -> Result<untrusted::Input<'a>, Error> {
272 nested(input, Tag::BitString, Error::BadDer, |value| {
273 let unused_bits_at_end = value.read_byte().map_err(|_| Error::BadDer)?;
274 if unused_bits_at_end != 0 {
275 return Err(Error::BadDer);
276 }
277 Ok(value.read_bytes_to_end())
278 })
279}
280
281pub(crate) struct BitStringFlags<'a> {
282 raw_bits: &'a [u8],
283}
284
285impl<'a> BitStringFlags<'a> {
286 pub(crate) fn bit_set(&self, bit: usize) -> bool {
287 let byte_index = bit / 8;
288 let bit_shift = 7 - (bit % 8);
289
290 if self.raw_bits.len() < (byte_index + 1) {
291 false
292 } else {
293 ((self.raw_bits[byte_index] >> bit_shift) & 1) != 0
294 }
295 }
296}
297
298pub(crate) fn bit_string_flags<'a>(
306 input: &mut untrusted::Reader<'a>,
307) -> Result<BitStringFlags<'a>, Error> {
308 expect_tag_and_get_value(input, Tag::BitString)?.read_all(Error::BadDer, |bit_string| {
309 let padding_bits = bit_string.read_byte().map_err(|_| Error::BadDer)?;
314 let raw_bits = bit_string.read_bytes_to_end().as_slice_less_safe();
315
316 if padding_bits > 7 || (raw_bits.is_empty() && padding_bits != 0) {
319 return Err(Error::BadDer);
320 }
321
322 let last_byte = raw_bits[raw_bits.len() - 1];
325 let padding_mask = (1 << padding_bits) - 1;
326
327 match padding_bits > 0 && (last_byte & padding_mask) != 0 {
328 true => Err(Error::BadDer),
329 false => Ok(BitStringFlags { raw_bits }),
330 }
331 })
332}
333
334pub(crate) fn optional_boolean(input: &mut untrusted::Reader) -> Result<bool, Error> {
337 if !input.peek(Tag::Boolean.into()) {
338 return Ok(false);
339 }
340 nested(input, Tag::Boolean, Error::BadDer, |input| {
341 match input.read_byte() {
342 Ok(0xff) => Ok(true),
343 Ok(0x00) => Ok(false),
344 _ => Err(Error::BadDer),
345 }
346 })
347}
348
349pub(crate) fn small_nonnegative_integer(input: &mut untrusted::Reader) -> Result<u8, Error> {
350 ring::io::der::small_nonnegative_integer(input).map_err(|_| Error::BadDer)
351}
352
353pub(crate) fn time_choice(input: &mut untrusted::Reader) -> Result<time::Time, Error> {
354 let is_utc_time = input.peek(Tag::UTCTime.into());
355 let expected_tag = if is_utc_time {
356 Tag::UTCTime
357 } else {
358 Tag::GeneralizedTime
359 };
360
361 fn read_digit(inner: &mut untrusted::Reader) -> Result<u64, Error> {
362 const DIGIT: core::ops::RangeInclusive<u8> = b'0'..=b'9';
363 let b = inner.read_byte().map_err(|_| Error::BadDerTime)?;
364 if DIGIT.contains(&b) {
365 return Ok(u64::from(b - DIGIT.start()));
366 }
367 Err(Error::BadDerTime)
368 }
369
370 fn read_two_digits(inner: &mut untrusted::Reader, min: u64, max: u64) -> Result<u64, Error> {
371 let hi = read_digit(inner)?;
372 let lo = read_digit(inner)?;
373 let value = (hi * 10) + lo;
374 if value < min || value > max {
375 return Err(Error::BadDerTime);
376 }
377 Ok(value)
378 }
379
380 nested(input, expected_tag, Error::BadDer, |value| {
381 let (year_hi, year_lo) = if is_utc_time {
382 let lo = read_two_digits(value, 0, 99)?;
383 let hi = if lo >= 50 { 19 } else { 20 };
384 (hi, lo)
385 } else {
386 let hi = read_two_digits(value, 0, 99)?;
387 let lo = read_two_digits(value, 0, 99)?;
388 (hi, lo)
389 };
390
391 let year = (year_hi * 100) + year_lo;
392 let month = read_two_digits(value, 1, 12)?;
393 let days_in_month = calendar::days_in_month(year, month);
394 let day_of_month = read_two_digits(value, 1, days_in_month)?;
395 let hours = read_two_digits(value, 0, 23)?;
396 let minutes = read_two_digits(value, 0, 59)?;
397 let seconds = read_two_digits(value, 0, 59)?;
398
399 let time_zone = value.read_byte().map_err(|_| Error::BadDerTime)?;
400 if time_zone != b'Z' {
401 return Err(Error::BadDerTime);
402 }
403
404 calendar::time_from_ymdhms_utc(year, month, day_of_month, hours, minutes, seconds)
405 })
406}
407
408macro_rules! oid {
409 ( $first:expr, $second:expr, $( $tail:expr ),* ) =>
410 (
411 [(40 * $first) + $second, $( $tail ),*]
412 )
413}
414
415#[cfg(test)]
416mod tests {
417 #[test]
418 fn test_optional_boolean() {
419 use super::{optional_boolean, Error};
420
421 assert!(!optional_boolean(&mut bytes_reader(&[])).unwrap());
423
424 assert!(!optional_boolean(&mut bytes_reader(&[0x05, 0x00])).unwrap());
426
427 assert_eq!(
429 optional_boolean(&mut bytes_reader(&[0x01, 0x01, 0x42])).unwrap_err(),
430 Error::BadDer,
431 );
432
433 assert!(optional_boolean(&mut bytes_reader(&[0x01, 0x01, 0xff])).unwrap());
435
436 assert!(!optional_boolean(&mut bytes_reader(&[0x01, 0x01, 0x00])).unwrap());
438 }
439
440 #[test]
441 fn test_bit_string_with_no_unused_bits() {
442 use super::{bit_string_with_no_unused_bits, Error};
443
444 assert_eq!(
446 bit_string_with_no_unused_bits(&mut bytes_reader(&[0x01, 0x01, 0xff])).unwrap_err(),
447 Error::BadDer,
448 );
449
450 assert_eq!(
452 bit_string_with_no_unused_bits(&mut bytes_reader(&[0x42, 0xff, 0xff])).unwrap_err(),
453 Error::BadDer,
454 );
455
456 assert_eq!(
458 bit_string_with_no_unused_bits(&mut bytes_reader(&[])).unwrap_err(),
459 Error::BadDer,
460 );
461
462 assert_eq!(
464 bit_string_with_no_unused_bits(&mut bytes_reader(&[0x03, 0x03, 0x04, 0x12, 0x34]))
465 .unwrap_err(),
466 Error::BadDer,
467 );
468
469 assert_eq!(
471 bit_string_with_no_unused_bits(&mut bytes_reader(&[0x03, 0x03, 0x00, 0x12, 0x34]))
472 .unwrap()
473 .as_slice_less_safe(),
474 &[0x12, 0x34],
475 );
476 }
477
478 fn bytes_reader(bytes: &[u8]) -> untrusted::Reader {
479 return untrusted::Reader::new(untrusted::Input::from(bytes));
480 }
481
482 #[test]
483 fn read_tag_and_get_value_default_limit() {
484 use super::{read_tag_and_get_value, Error};
485
486 let inputs = &[
487 &[EXAMPLE_TAG, 0x83, 0xFF, 0xFF, 0xFF].as_slice(),
489 &[EXAMPLE_TAG, 0x84, 0xFF, 0xFF, 0xFF, 0xFF].as_slice(),
491 ];
492
493 for input in inputs {
494 let mut bytes = untrusted::Reader::new(untrusted::Input::from(input));
495 assert!(matches!(
498 read_tag_and_get_value(&mut bytes),
499 Err(Error::BadDer)
500 ));
501 }
502 }
503
504 #[test]
505 fn read_tag_and_get_value_limited_high_form() {
506 use super::{read_tag_and_get_value_limited, Error, LONG_FORM_LEN_TWO_BYTES_MAX};
507
508 let mut bytes = untrusted::Reader::new(untrusted::Input::from(&[0xFF]));
509 assert!(matches!(
511 read_tag_and_get_value_limited(&mut bytes, LONG_FORM_LEN_TWO_BYTES_MAX),
512 Err(Error::BadDer)
513 ));
514 }
515
516 #[test]
517 fn read_tag_and_get_value_limited_non_canonical() {
518 use super::{read_tag_and_get_value_limited, Error, LONG_FORM_LEN_TWO_BYTES_MAX};
519
520 let inputs = &[
521 &[EXAMPLE_TAG, 0x81, 0x01].as_slice(),
523 &[EXAMPLE_TAG, 0x82, 0x00, 0x01].as_slice(),
525 &[EXAMPLE_TAG, 0x83, 0x00, 0x00, 0x01].as_slice(),
527 &[EXAMPLE_TAG, 0x84, 0x00, 0x00, 0x00, 0x01].as_slice(),
529 ];
530
531 for input in inputs {
532 let mut bytes = untrusted::Reader::new(untrusted::Input::from(input));
533 assert!(matches!(
535 read_tag_and_get_value_limited(&mut bytes, LONG_FORM_LEN_TWO_BYTES_MAX),
536 Err(Error::BadDer)
537 ));
538 }
539 }
540
541 #[test]
542 #[cfg(feature = "alloc")]
543 fn read_tag_and_get_value_limited_limits() {
544 use super::{read_tag_and_get_value_limited, Error};
545
546 let short_input = &[0xFF];
547 let short_input_encoded = &[
548 &[EXAMPLE_TAG],
549 der_encode_length(short_input.len()).as_slice(),
550 short_input,
551 ]
552 .concat();
553
554 let long_input = &[1_u8; 65537];
555 let long_input_encoded = &[
556 &[EXAMPLE_TAG],
557 der_encode_length(long_input.len()).as_slice(),
558 long_input,
559 ]
560 .concat();
561
562 struct Testcase<'a> {
563 input: &'a [u8],
564 limit: usize,
565 err: Option<Error>,
566 }
567
568 let testcases = &[
569 Testcase {
570 input: short_input_encoded,
571 limit: 1,
572 err: Some(Error::BadDer),
573 },
574 Testcase {
575 input: short_input_encoded,
576 limit: short_input_encoded.len() + 1,
577 err: None,
578 },
579 Testcase {
580 input: long_input_encoded,
581 limit: long_input.len(),
582 err: Some(Error::BadDer),
583 },
584 Testcase {
585 input: long_input_encoded,
586 limit: long_input.len() + 1,
587 err: None,
588 },
589 ];
590
591 for tc in testcases {
592 let mut bytes = untrusted::Reader::new(untrusted::Input::from(tc.input));
593
594 let res = read_tag_and_get_value_limited(&mut bytes, tc.limit);
595 match tc.err {
596 None => assert!(res.is_ok()),
597 Some(e) => {
598 let actual = res.unwrap_err();
599 assert_eq!(actual, e)
600 }
601 }
602 }
603 }
604
605 #[allow(clippy::as_conversions)] const EXAMPLE_TAG: u8 = super::Tag::Sequence as u8;
607
608 #[cfg(feature = "alloc")]
609 #[allow(clippy::as_conversions)] fn der_encode_length(length: usize) -> Vec<u8> {
611 if length < 128 {
612 vec![length as u8]
613 } else {
614 let mut encoded: Vec<u8> = Vec::new();
615 let mut remaining_length = length;
616
617 while remaining_length > 0 {
618 let byte = (remaining_length & 0xFF) as u8;
619 encoded.insert(0, byte);
620 remaining_length >>= 8;
621 }
622
623 let length_octet = encoded.len() as u8 | 0x80;
624 encoded.insert(0, length_octet);
625
626 encoded
627 }
628 }
629
630 #[allow(clippy::as_conversions)] const BITSTRING_TAG: u8 = super::Tag::BitString as u8;
632
633 #[test]
634 fn misencoded_bit_string_flags() {
635 use super::{bit_string_flags, Error};
636
637 let mut bad_padding_example = untrusted::Reader::new(untrusted::Input::from(&[
638 BITSTRING_TAG, 0x2, 0x08, 0x06, ]));
643 assert!(matches!(
644 bit_string_flags(&mut bad_padding_example),
645 Err(Error::BadDer)
646 ));
647
648 let mut bad_padding_example = untrusted::Reader::new(untrusted::Input::from(&[
649 BITSTRING_TAG, 0x2, 0x01, ]));
654 assert!(matches!(
655 bit_string_flags(&mut bad_padding_example),
656 Err(Error::BadDer)
657 ));
658
659 let mut trailing_zeroes = untrusted::Reader::new(untrusted::Input::from(&[
660 BITSTRING_TAG, 0x2, 0x01, 0xFF, 0x00, ]));
666 assert!(matches!(
667 bit_string_flags(&mut trailing_zeroes),
668 Err(Error::BadDer)
669 ))
670 }
671
672 #[test]
673 fn valid_bit_string_flags() {
674 use super::bit_string_flags;
675
676 let mut example_key_usage = untrusted::Reader::new(untrusted::Input::from(&[
677 BITSTRING_TAG, 0x2, 0x01, 0x06, ]));
682 let res = bit_string_flags(&mut example_key_usage).unwrap();
683
684 assert!(!res.bit_set(0));
685 assert!(!res.bit_set(1));
686 assert!(!res.bit_set(2));
687 assert!(!res.bit_set(3));
688 assert!(!res.bit_set(4));
689 assert!(res.bit_set(5));
691 assert!(res.bit_set(6));
692 assert!(!res.bit_set(7));
693 assert!(!res.bit_set(8));
694 assert!(!res.bit_set(256));
696 }
697}