1// Copyright 2015 Brian Smith.
2//
3// Permission to use, copy, modify, and/or distribute this software for any
4// purpose with or without fee is hereby granted, provided that the above
5// copyright notice and this permission notice appear in all copies.
6//
7// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
8// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
10// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15use core::marker::PhantomData;
16
17use crate::{error::DerTypeId, Error};
18
19#[derive(Debug)]
20pub struct DerIterator<'a, T> {
21 reader: untrusted::Reader<'a>,
22 marker: PhantomData<T>,
23}
24
25impl<'a, T> DerIterator<'a, T> {
26 /// [`DerIterator`] will consume all of the bytes in `input` reading values of type `T`.
27 pub(crate) fn new(input: untrusted::Input<'a>) -> Self {
28 Self {
29 reader: untrusted::Reader::new(input),
30 marker: PhantomData,
31 }
32 }
33}
34
35impl<'a, T: FromDer<'a>> Iterator for DerIterator<'a, T> {
36 type Item = Result<T, Error>;
37
38 fn next(&mut self) -> Option<Self::Item> {
39 (!self.reader.at_end()).then(|| T::from_der(&mut self.reader))
40 }
41}
42
43pub(crate) trait FromDer<'a>: Sized + 'a {
44 /// Parse a value of type `Self` from the given DER-encoded input.
45 fn from_der(reader: &mut untrusted::Reader<'a>) -> Result<Self, Error>;
46
47 const TYPE_ID: DerTypeId;
48}
49
50pub(crate) fn read_all<'a, T: FromDer<'a>>(input: untrusted::Input<'a>) -> Result<T, Error> {
51 input.read_all(incomplete_read:Error::TrailingData(T::TYPE_ID), T::from_der)
52}
53
54// Copied (and extended) from ring's src/der.rs
55#[allow(clippy::upper_case_acronyms)]
56#[derive(Clone, Copy, Eq, PartialEq)]
57#[repr(u8)]
58pub(crate) enum Tag {
59 Boolean = 0x01,
60 Integer = 0x02,
61 BitString = 0x03,
62 OctetString = 0x04,
63 OID = 0x06,
64 Enum = 0x0A,
65 Sequence = CONSTRUCTED | 0x10, // 0x30
66 UTCTime = 0x17,
67 GeneralizedTime = 0x18,
68
69 #[allow(clippy::identity_op)]
70 ContextSpecificConstructed0 = CONTEXT_SPECIFIC | CONSTRUCTED | 0,
71 ContextSpecificConstructed1 = CONTEXT_SPECIFIC | CONSTRUCTED | 1,
72 ContextSpecificConstructed3 = CONTEXT_SPECIFIC | CONSTRUCTED | 3,
73}
74
75pub(crate) const CONSTRUCTED: u8 = 0x20;
76pub(crate) const CONTEXT_SPECIFIC: u8 = 0x80;
77
78impl From<Tag> for usize {
79 #[allow(clippy::as_conversions)]
80 fn from(tag: Tag) -> Self {
81 tag as Self
82 }
83}
84
85impl From<Tag> for u8 {
86 #[allow(clippy::as_conversions)]
87 fn from(tag: Tag) -> Self {
88 tag as Self
89 } // XXX: narrowing conversion.
90}
91
92#[inline(always)]
93pub(crate) fn expect_tag_and_get_value_limited<'a>(
94 input: &mut untrusted::Reader<'a>,
95 tag: Tag,
96 size_limit: usize,
97) -> Result<untrusted::Input<'a>, Error> {
98 let (actual_tag: u8, inner: Input<'_>) = read_tag_and_get_value_limited(input, size_limit)?;
99 if usize::from(tag) != usize::from(actual_tag) {
100 return Err(Error::BadDer);
101 }
102 Ok(inner)
103}
104
105pub(crate) fn nested_limited<'a, R>(
106 input: &mut untrusted::Reader<'a>,
107 tag: Tag,
108 error: Error,
109 decoder: impl FnOnce(&mut untrusted::Reader<'a>) -> Result<R, Error>,
110 size_limit: usize,
111) -> Result<R, Error> {
112 expect_tag_and_get_value_limited(input, tag, size_limit)
113 .map_err(|_| error)?
114 .read_all(incomplete_read:error, read:decoder)
115}
116
117// TODO: investigate taking decoder as a reference to reduce generated code
118// size.
119pub(crate) fn nested<'a, R>(
120 input: &mut untrusted::Reader<'a>,
121 tag: Tag,
122 error: Error,
123 decoder: impl FnOnce(&mut untrusted::Reader<'a>) -> Result<R, Error>,
124) -> Result<R, Error> {
125 nested_limited(input, tag, error, decoder, TWO_BYTE_DER_SIZE)
126}
127
128pub(crate) fn expect_tag<'a>(
129 input: &mut untrusted::Reader<'a>,
130 tag: Tag,
131) -> Result<untrusted::Input<'a>, Error> {
132 let (actual_tag: u8, value: Input<'_>) = read_tag_and_get_value_limited(input, TWO_BYTE_DER_SIZE)?;
133 if usize::from(tag) != usize::from(actual_tag) {
134 return Err(Error::BadDer);
135 }
136
137 Ok(value)
138}
139
140#[inline(always)]
141pub(crate) fn read_tag_and_get_value<'a>(
142 input: &mut untrusted::Reader<'a>,
143) -> Result<(u8, untrusted::Input<'a>), Error> {
144 read_tag_and_get_value_limited(input, TWO_BYTE_DER_SIZE)
145}
146
147#[inline(always)]
148pub(crate) fn read_tag_and_get_value_limited<'a>(
149 input: &mut untrusted::Reader<'a>,
150 size_limit: usize,
151) -> Result<(u8, untrusted::Input<'a>), Error> {
152 let tag = input.read_byte().map_err(end_of_input_err)?;
153 if (tag & HIGH_TAG_RANGE_START) == HIGH_TAG_RANGE_START {
154 return Err(Error::BadDer); // High tag number form is not allowed.
155 }
156
157 // If the high order bit of the first byte is set to zero then the length
158 // is encoded in the seven remaining bits of that byte. Otherwise, those
159 // seven bits represent the number of bytes used to encode the length.
160 let length = match input.read_byte().map_err(end_of_input_err)? {
161 n if (n & SHORT_FORM_LEN_MAX) == 0 => usize::from(n),
162 LONG_FORM_LEN_ONE_BYTE => {
163 let length_byte = input.read_byte().map_err(end_of_input_err)?;
164 if length_byte < SHORT_FORM_LEN_MAX {
165 return Err(Error::BadDer); // Not the canonical encoding.
166 }
167 usize::from(length_byte)
168 }
169 LONG_FORM_LEN_TWO_BYTES => {
170 let length_byte_one = usize::from(input.read_byte().map_err(end_of_input_err)?);
171 let length_byte_two = usize::from(input.read_byte().map_err(end_of_input_err)?);
172 let combined = (length_byte_one << 8) | length_byte_two;
173 if combined <= LONG_FORM_LEN_ONE_BYTE_MAX {
174 return Err(Error::BadDer); // Not the canonical encoding.
175 }
176 combined
177 }
178 LONG_FORM_LEN_THREE_BYTES => {
179 let length_byte_one = usize::from(input.read_byte().map_err(end_of_input_err)?);
180 let length_byte_two = usize::from(input.read_byte().map_err(end_of_input_err)?);
181 let length_byte_three = usize::from(input.read_byte().map_err(end_of_input_err)?);
182 let combined = (length_byte_one << 16) | (length_byte_two << 8) | length_byte_three;
183 if combined <= LONG_FORM_LEN_TWO_BYTES_MAX {
184 return Err(Error::BadDer); // Not the canonical encoding.
185 }
186 combined
187 }
188 LONG_FORM_LEN_FOUR_BYTES => {
189 let length_byte_one = usize::from(input.read_byte().map_err(end_of_input_err)?);
190 let length_byte_two = usize::from(input.read_byte().map_err(end_of_input_err)?);
191 let length_byte_three = usize::from(input.read_byte().map_err(end_of_input_err)?);
192 let length_byte_four = usize::from(input.read_byte().map_err(end_of_input_err)?);
193 let combined = (length_byte_one << 24)
194 | (length_byte_two << 16)
195 | (length_byte_three << 8)
196 | length_byte_four;
197 if combined <= LONG_FORM_LEN_THREE_BYTES_MAX {
198 return Err(Error::BadDer); // Not the canonical encoding.
199 }
200 combined
201 }
202 _ => {
203 return Err(Error::BadDer); // We don't support longer lengths.
204 }
205 };
206
207 if length >= size_limit {
208 return Err(Error::BadDer); // The length is larger than the caller accepts.
209 }
210
211 let inner = input.read_bytes(length).map_err(end_of_input_err)?;
212 Ok((tag, inner))
213}
214
215// Long-form DER encoded lengths of two bytes can express lengths up to the following limit.
216//
217// The upstream ring::io::der::read_tag_and_get_value() function limits itself to up to two byte
218// long-form DER lengths, and so this limit represents the maximum length that was possible to
219// read before the introduction of the read_tag_and_get_value_limited function.
220pub(crate) const TWO_BYTE_DER_SIZE: usize = LONG_FORM_LEN_TWO_BYTES_MAX;
221
222// The maximum size of a DER value that Webpki can support reading.
223//
224// Webpki limits itself to four byte long-form DER lengths, and so this limit represents
225// the maximum size tagged DER value that can be read for any purpose.
226pub(crate) const MAX_DER_SIZE: usize = LONG_FORM_LEN_FOUR_BYTES_MAX;
227
228// DER Tag identifiers have two forms:
229// * Low tag number form (for tags values in the range [0..30]
230// * High tag number form (for tag values in the range [31..]
231// We only support low tag number form.
232const HIGH_TAG_RANGE_START: u8 = 31;
233
234// DER length octets have two forms:
235// * Short form: 1 octet supporting lengths between 0 and 127.
236// * Long definite form: 2 to 127 octets, number of octets encoded into first octet.
237const SHORT_FORM_LEN_MAX: u8 = 128;
238
239// Leading octet for long definite form DER length expressed in second byte.
240const LONG_FORM_LEN_ONE_BYTE: u8 = 0x81;
241
242// Maximum size that can be expressed in a one byte long form len.
243const LONG_FORM_LEN_ONE_BYTE_MAX: usize = 0xff;
244
245// Leading octet for long definite form DER length expressed in subsequent two bytes.
246const LONG_FORM_LEN_TWO_BYTES: u8 = 0x82;
247
248// Maximum size that can be expressed in a two byte long form len.
249const LONG_FORM_LEN_TWO_BYTES_MAX: usize = 0xff_ff;
250
251// Leading octet for long definite form DER length expressed in subsequent three bytes.
252const LONG_FORM_LEN_THREE_BYTES: u8 = 0x83;
253
254// Maximum size that can be expressed in a three byte long form len.
255const LONG_FORM_LEN_THREE_BYTES_MAX: usize = 0xff_ff_ff;
256
257// Leading octet for long definite form DER length expressed in subsequent four bytes.
258const LONG_FORM_LEN_FOUR_BYTES: u8 = 0x84;
259
260// Maximum size that can be expressed in a four byte long form der len.
261const LONG_FORM_LEN_FOUR_BYTES_MAX: usize = 0xff_ff_ff_ff;
262
263// TODO: investigate taking decoder as a reference to reduce generated code
264// size.
265pub(crate) fn nested_of_mut<'a>(
266 input: &mut untrusted::Reader<'a>,
267 outer_tag: Tag,
268 inner_tag: Tag,
269 error: Error,
270 mut decoder: impl FnMut(&mut untrusted::Reader<'a>) -> Result<(), Error>,
271) -> Result<(), Error> {
272 nested(input, outer_tag, error, |outer: &mut Reader<'_>| {
273 loop {
274 nested(input:outer, inner_tag, error, |inner: &mut Reader<'_>| decoder(inner))?;
275 if outer.at_end() {
276 break;
277 }
278 }
279 Ok(())
280 })
281}
282
283pub(crate) fn bit_string_with_no_unused_bits<'a>(
284 input: &mut untrusted::Reader<'a>,
285) -> Result<untrusted::Input<'a>, Error> {
286 nested(
287 input,
288 Tag::BitString,
289 Error::TrailingData(DerTypeId::BitString),
290 |value: &mut Reader<'_>| {
291 let unused_bits_at_end: u8 = value.read_byte().map_err(|_| Error::BadDer)?;
292 if unused_bits_at_end != 0 {
293 return Err(Error::BadDer);
294 }
295 Ok(value.read_bytes_to_end())
296 },
297 )
298}
299
300pub(crate) struct BitStringFlags<'a> {
301 raw_bits: &'a [u8],
302}
303
304impl<'a> BitStringFlags<'a> {
305 pub(crate) fn bit_set(&self, bit: usize) -> bool {
306 let byte_index: usize = bit / 8;
307 let bit_shift: usize = 7 - (bit % 8);
308
309 if self.raw_bits.len() < (byte_index + 1) {
310 false
311 } else {
312 ((self.raw_bits[byte_index] >> bit_shift) & 1) != 0
313 }
314 }
315}
316
317// ASN.1 BIT STRING fields for sets of flags are encoded in DER with some peculiar details related
318// to padding. Notably this means we expect an indicator of the number of bits of padding, and then
319// the actual bit values. See this Stack Overflow discussion[0], and ITU X690-0207[1] Section 8.6
320// and Section 11.2 for more information.
321//
322// [0]: https://security.stackexchange.com/a/10396
323// [1]: https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
324pub(crate) fn bit_string_flags(input: untrusted::Input) -> Result<BitStringFlags<'_>, Error> {
325 input.read_all(Error::BadDer, |bit_string| {
326 // ITU X690-0207 11.2:
327 // "The initial octet shall encode, as an unsigned binary integer with bit 1 as the least
328 // significant bit, the number of unused bits in the final subsequent octet.
329 // The number shall be in the range zero to seven"
330 let padding_bits = bit_string.read_byte().map_err(|_| Error::BadDer)?;
331 let raw_bits = bit_string.read_bytes_to_end().as_slice_less_safe();
332
333 // It's illegal to have more than 7 bits of padding. Similarly, if the raw bitflags
334 // are empty there should be no padding.
335 if padding_bits > 7 || (raw_bits.is_empty() && padding_bits != 0) {
336 return Err(Error::BadDer);
337 }
338
339 // If there are padding bits then the last bit of the last raw byte must be 0 or the
340 // distinguished encoding rules are not being followed.
341 let last_byte = raw_bits[raw_bits.len() - 1];
342 let padding_mask = (1 << padding_bits) - 1;
343
344 match padding_bits > 0 && (last_byte & padding_mask) != 0 {
345 true => Err(Error::BadDer),
346 false => Ok(BitStringFlags { raw_bits }),
347 }
348 })
349}
350
351impl<'a> FromDer<'a> for u8 {
352 fn from_der(reader: &mut untrusted::Reader<'a>) -> Result<Self, Error> {
353 match *nonnegative_integer(input:reader)?.as_slice_less_safe() {
354 [b: u8] => Ok(b),
355 _ => Err(Error::BadDer),
356 }
357 }
358
359 const TYPE_ID: DerTypeId = DerTypeId::U8;
360}
361
362pub(crate) fn nonnegative_integer<'a>(
363 input: &mut untrusted::Reader<'a>,
364) -> Result<untrusted::Input<'a>, Error> {
365 let value: Input<'_> = expect_tag(input, Tag::Integer)?;
366 match value
367 .as_slice_less_safe()
368 .split_first()
369 .ok_or(err:Error::BadDer)?
370 {
371 // Zero or leading zero.
372 (0, rest: &[u8]) => {
373 match rest.first() {
374 // Zero
375 None => Ok(value),
376 // Necessary leading zero.
377 Some(&second: u8) if second & 0x80 == 0x80 => Ok(untrusted::Input::from(bytes:rest)),
378 // Unnecessary leading zero.
379 _ => Err(Error::BadDer),
380 }
381 }
382 // Positive value with no leading zero.
383 (first: &u8, _) if first & 0x80 == 0x00 => Ok(value),
384 // Negative value.
385 (_, _) => Err(Error::BadDer),
386 }
387}
388
389pub(crate) fn end_of_input_err(_: untrusted::EndOfInput) -> Error {
390 Error::BadDer
391}
392
393// Like mozilla::pkix, we accept the nonconformant explicit encoding of
394// the default value (false) for compatibility with real-world certificates.
395impl<'a> FromDer<'a> for bool {
396 fn from_der(reader: &mut untrusted::Reader<'a>) -> Result<Self, Error> {
397 if !reader.peek(Tag::Boolean.into()) {
398 return Ok(false);
399 }
400
401 nested(
402 input:reader,
403 Tag::Boolean,
404 Error::TrailingData(Self::TYPE_ID),
405 |input: &mut Reader<'_>| match input.read_byte() {
406 Ok(0xff) => Ok(true),
407 Ok(0x00) => Ok(false),
408 _ => Err(Error::BadDer),
409 },
410 )
411 }
412
413 const TYPE_ID: DerTypeId = DerTypeId::Bool;
414}
415
416macro_rules! oid {
417 ( $first:expr, $second:expr, $( $tail:expr ),* ) =>
418 (
419 [(40 * $first) + $second, $( $tail ),*]
420 )
421}
422
423#[cfg(test)]
424mod tests {
425 use super::DerTypeId;
426
427 #[test]
428 fn test_optional_boolean() {
429 use super::{Error, FromDer};
430
431 // Empty input results in false
432 assert!(!bool::from_der(&mut bytes_reader(&[])).unwrap());
433
434 // Optional, so another data type results in false
435 assert!(!bool::from_der(&mut bytes_reader(&[0x05, 0x00])).unwrap());
436
437 // Only 0x00 and 0xff are accepted values
438 assert_eq!(
439 Err(Error::BadDer),
440 bool::from_der(&mut bytes_reader(&[0x01, 0x01, 0x42]))
441 );
442
443 // True
444 assert!(bool::from_der(&mut bytes_reader(&[0x01, 0x01, 0xff])).unwrap());
445
446 // False
447 assert!(!bool::from_der(&mut bytes_reader(&[0x01, 0x01, 0x00])).unwrap());
448 }
449
450 #[test]
451 fn test_bit_string_with_no_unused_bits() {
452 use super::{bit_string_with_no_unused_bits, Error};
453
454 // Unexpected type
455 assert_eq!(
456 bit_string_with_no_unused_bits(&mut bytes_reader(&[0x01, 0x01, 0xff])).unwrap_err(),
457 Error::TrailingData(DerTypeId::BitString),
458 );
459
460 // Unexpected nonexistent type
461 assert_eq!(
462 bit_string_with_no_unused_bits(&mut bytes_reader(&[0x42, 0xff, 0xff])).unwrap_err(),
463 Error::TrailingData(DerTypeId::BitString),
464 );
465
466 // Unexpected empty input
467 assert_eq!(
468 bit_string_with_no_unused_bits(&mut bytes_reader(&[])).unwrap_err(),
469 Error::TrailingData(DerTypeId::BitString),
470 );
471
472 // Valid input with non-zero unused bits
473 assert_eq!(
474 bit_string_with_no_unused_bits(&mut bytes_reader(&[0x03, 0x03, 0x04, 0x12, 0x34]))
475 .unwrap_err(),
476 Error::BadDer,
477 );
478
479 // Valid input
480 assert_eq!(
481 bit_string_with_no_unused_bits(&mut bytes_reader(&[0x03, 0x03, 0x00, 0x12, 0x34]))
482 .unwrap()
483 .as_slice_less_safe(),
484 &[0x12, 0x34],
485 );
486 }
487
488 fn bytes_reader(bytes: &[u8]) -> untrusted::Reader {
489 return untrusted::Reader::new(untrusted::Input::from(bytes));
490 }
491
492 #[test]
493 fn read_tag_and_get_value_default_limit() {
494 use super::{read_tag_and_get_value, Error};
495
496 let inputs = &[
497 // DER with short-form length encoded as three bytes.
498 &[EXAMPLE_TAG, 0x83, 0xFF, 0xFF, 0xFF].as_slice(),
499 // DER with short-form length encoded as four bytes.
500 &[EXAMPLE_TAG, 0x84, 0xFF, 0xFF, 0xFF, 0xFF].as_slice(),
501 ];
502
503 for input in inputs {
504 let mut bytes = untrusted::Reader::new(untrusted::Input::from(input));
505 // read_tag_and_get_value should reject DER with encoded lengths larger than two
506 // bytes as BadDer.
507 assert!(matches!(
508 read_tag_and_get_value(&mut bytes),
509 Err(Error::BadDer)
510 ));
511 }
512 }
513
514 #[test]
515 fn read_tag_and_get_value_limited_high_form() {
516 use super::{read_tag_and_get_value_limited, Error, LONG_FORM_LEN_TWO_BYTES_MAX};
517
518 let mut bytes = untrusted::Reader::new(untrusted::Input::from(&[0xFF]));
519 // read_tag_and_get_value_limited_high_form should reject DER with "high tag number form" tags.
520 assert!(matches!(
521 read_tag_and_get_value_limited(&mut bytes, LONG_FORM_LEN_TWO_BYTES_MAX),
522 Err(Error::BadDer)
523 ));
524 }
525
526 #[test]
527 fn read_tag_and_get_value_limited_non_canonical() {
528 use super::{read_tag_and_get_value_limited, Error, LONG_FORM_LEN_TWO_BYTES_MAX};
529
530 let inputs = &[
531 // Two byte length, with expressed length < 128.
532 &[EXAMPLE_TAG, 0x81, 0x01].as_slice(),
533 // Three byte length, with expressed length < 256.
534 &[EXAMPLE_TAG, 0x82, 0x00, 0x01].as_slice(),
535 // Four byte length, with expressed length, < 65536.
536 &[EXAMPLE_TAG, 0x83, 0x00, 0x00, 0x01].as_slice(),
537 // Five byte length, with expressed length < 16777216.
538 &[EXAMPLE_TAG, 0x84, 0x00, 0x00, 0x00, 0x01].as_slice(),
539 ];
540
541 for input in inputs {
542 let mut bytes = untrusted::Reader::new(untrusted::Input::from(input));
543 // read_tag_and_get_value_limited should reject DER with non-canonical lengths.
544 assert!(matches!(
545 read_tag_and_get_value_limited(&mut bytes, LONG_FORM_LEN_TWO_BYTES_MAX),
546 Err(Error::BadDer)
547 ));
548 }
549 }
550
551 #[test]
552 #[cfg(feature = "alloc")]
553 fn read_tag_and_get_value_limited_limits() {
554 use super::{read_tag_and_get_value_limited, Error};
555
556 let short_input = &[0xFF];
557 let short_input_encoded = &[
558 &[EXAMPLE_TAG],
559 der_encode_length(short_input.len()).as_slice(),
560 short_input,
561 ]
562 .concat();
563
564 let long_input = &[1_u8; 65537];
565 let long_input_encoded = &[
566 &[EXAMPLE_TAG],
567 der_encode_length(long_input.len()).as_slice(),
568 long_input,
569 ]
570 .concat();
571
572 struct Testcase<'a> {
573 input: &'a [u8],
574 limit: usize,
575 err: Option<Error>,
576 }
577
578 let testcases = &[
579 Testcase {
580 input: short_input_encoded,
581 limit: 1,
582 err: Some(Error::BadDer),
583 },
584 Testcase {
585 input: short_input_encoded,
586 limit: short_input_encoded.len() + 1,
587 err: None,
588 },
589 Testcase {
590 input: long_input_encoded,
591 limit: long_input.len(),
592 err: Some(Error::BadDer),
593 },
594 Testcase {
595 input: long_input_encoded,
596 limit: long_input.len() + 1,
597 err: None,
598 },
599 ];
600
601 for tc in testcases {
602 let mut bytes = untrusted::Reader::new(untrusted::Input::from(tc.input));
603
604 let res = read_tag_and_get_value_limited(&mut bytes, tc.limit);
605 match tc.err {
606 None => assert!(res.is_ok()),
607 Some(e) => {
608 let actual = res.unwrap_err();
609 assert_eq!(actual, e)
610 }
611 }
612 }
613 }
614
615 #[allow(clippy::as_conversions)] // infallible.
616 const EXAMPLE_TAG: u8 = super::Tag::Sequence as u8;
617
618 #[cfg(feature = "alloc")]
619 #[allow(clippy::as_conversions)] // test code.
620 fn der_encode_length(length: usize) -> Vec<u8> {
621 if length < 128 {
622 vec![length as u8]
623 } else {
624 let mut encoded: Vec<u8> = Vec::new();
625 let mut remaining_length = length;
626
627 while remaining_length > 0 {
628 let byte = (remaining_length & 0xFF) as u8;
629 encoded.insert(0, byte);
630 remaining_length >>= 8;
631 }
632
633 let length_octet = encoded.len() as u8 | 0x80;
634 encoded.insert(0, length_octet);
635
636 encoded
637 }
638 }
639
640 #[test]
641 fn misencoded_bit_string_flags() {
642 use super::{bit_string_flags, Error};
643
644 let bad_padding_example = untrusted::Input::from(&[
645 0x08, // 8 bit of padding (illegal!).
646 0x06, // 1 byte of bit flags asserting bits 5 and 6.
647 ]);
648 assert!(matches!(
649 bit_string_flags(bad_padding_example),
650 Err(Error::BadDer)
651 ));
652
653 let bad_padding_example = untrusted::Input::from(&[
654 0x01, // 1 bit of padding.
655 // No flags value (illegal with padding!).
656 ]);
657 assert!(matches!(
658 bit_string_flags(bad_padding_example),
659 Err(Error::BadDer)
660 ));
661 }
662
663 #[test]
664 fn valid_bit_string_flags() {
665 use super::bit_string_flags;
666
667 let example_key_usage = untrusted::Input::from(&[
668 0x01, // 1 bit of padding.
669 0x06, // 1 byte of bit flags asserting bits 5 and 6.
670 ]);
671 let res = bit_string_flags(example_key_usage).unwrap();
672
673 assert!(!res.bit_set(0));
674 assert!(!res.bit_set(1));
675 assert!(!res.bit_set(2));
676 assert!(!res.bit_set(3));
677 assert!(!res.bit_set(4));
678 // NB: Bits 5 and 6 should be set.
679 assert!(res.bit_set(5));
680 assert!(res.bit_set(6));
681 assert!(!res.bit_set(7));
682 assert!(!res.bit_set(8));
683 // Bits outside the range of values shouldn't be considered set.
684 assert!(!res.bit_set(256));
685 }
686
687 #[test]
688 fn test_small_nonnegative_integer() {
689 use super::{Error, FromDer, Tag};
690
691 for value in 0..=127 {
692 let data = [Tag::Integer.into(), 1, value];
693 let mut rd = untrusted::Reader::new(untrusted::Input::from(&data));
694 assert_eq!(u8::from_der(&mut rd), Ok(value),);
695 }
696
697 for value in 128..=255 {
698 let data = [Tag::Integer.into(), 2, 0x00, value];
699 let mut rd = untrusted::Reader::new(untrusted::Input::from(&data));
700 assert_eq!(u8::from_der(&mut rd), Ok(value),);
701 }
702
703 // not an integer
704 assert_eq!(
705 u8::from_der(&mut untrusted::Reader::new(untrusted::Input::from(&[
706 Tag::Sequence.into(),
707 1,
708 1
709 ]))),
710 Err(Error::BadDer)
711 );
712
713 // negative
714 assert_eq!(
715 u8::from_der(&mut untrusted::Reader::new(untrusted::Input::from(&[
716 Tag::Integer.into(),
717 1,
718 0xff
719 ]))),
720 Err(Error::BadDer)
721 );
722
723 // positive but too large
724 assert_eq!(
725 u8::from_der(&mut untrusted::Reader::new(untrusted::Input::from(&[
726 Tag::Integer.into(),
727 2,
728 0x01,
729 0x00
730 ]))),
731 Err(Error::BadDer)
732 );
733
734 // unnecessary leading zero
735 assert_eq!(
736 u8::from_der(&mut untrusted::Reader::new(untrusted::Input::from(&[
737 Tag::Integer.into(),
738 2,
739 0x00,
740 0x05
741 ]))),
742 Err(Error::BadDer)
743 );
744
745 // truncations
746 assert_eq!(
747 u8::from_der(&mut untrusted::Reader::new(untrusted::Input::from(&[]))),
748 Err(Error::BadDer)
749 );
750
751 assert_eq!(
752 u8::from_der(&mut untrusted::Reader::new(untrusted::Input::from(&[
753 Tag::Integer.into(),
754 ]))),
755 Err(Error::BadDer)
756 );
757
758 assert_eq!(
759 u8::from_der(&mut untrusted::Reader::new(untrusted::Input::from(&[
760 Tag::Integer.into(),
761 1,
762 ]))),
763 Err(Error::BadDer)
764 );
765
766 assert_eq!(
767 u8::from_der(&mut untrusted::Reader::new(untrusted::Input::from(&[
768 Tag::Integer.into(),
769 2,
770 0
771 ]))),
772 Err(Error::BadDer)
773 );
774 }
775}
776