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 | |
15 | use core::marker::PhantomData; |
16 | |
17 | use crate::{error::DerTypeId, Error}; |
18 | |
19 | #[derive (Debug)] |
20 | pub struct DerIterator<'a, T> { |
21 | reader: untrusted::Reader<'a>, |
22 | marker: PhantomData<T>, |
23 | } |
24 | |
25 | impl<'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 | |
35 | impl<'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 | |
43 | pub(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 | |
50 | pub(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)] |
58 | pub(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 | |
75 | pub(crate) const CONSTRUCTED: u8 = 0x20; |
76 | pub(crate) const CONTEXT_SPECIFIC: u8 = 0x80; |
77 | |
78 | impl From<Tag> for usize { |
79 | #[allow (clippy::as_conversions)] |
80 | fn from(tag: Tag) -> Self { |
81 | tag as Self |
82 | } |
83 | } |
84 | |
85 | impl 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)] |
93 | pub(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 | |
105 | pub(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. |
119 | pub(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 | |
128 | pub(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)] |
141 | pub(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)] |
148 | pub(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. |
220 | pub(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. |
226 | pub(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. |
232 | const 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. |
237 | const SHORT_FORM_LEN_MAX: u8 = 128; |
238 | |
239 | // Leading octet for long definite form DER length expressed in second byte. |
240 | const LONG_FORM_LEN_ONE_BYTE: u8 = 0x81; |
241 | |
242 | // Maximum size that can be expressed in a one byte long form len. |
243 | const LONG_FORM_LEN_ONE_BYTE_MAX: usize = 0xff; |
244 | |
245 | // Leading octet for long definite form DER length expressed in subsequent two bytes. |
246 | const LONG_FORM_LEN_TWO_BYTES: u8 = 0x82; |
247 | |
248 | // Maximum size that can be expressed in a two byte long form len. |
249 | const LONG_FORM_LEN_TWO_BYTES_MAX: usize = 0xff_ff; |
250 | |
251 | // Leading octet for long definite form DER length expressed in subsequent three bytes. |
252 | const LONG_FORM_LEN_THREE_BYTES: u8 = 0x83; |
253 | |
254 | // Maximum size that can be expressed in a three byte long form len. |
255 | const 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. |
258 | const LONG_FORM_LEN_FOUR_BYTES: u8 = 0x84; |
259 | |
260 | // Maximum size that can be expressed in a four byte long form der len. |
261 | const 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. |
265 | pub(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 | |
283 | pub(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 | |
300 | pub(crate) struct BitStringFlags<'a> { |
301 | raw_bits: &'a [u8], |
302 | } |
303 | |
304 | impl<'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 |
324 | pub(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 | |
351 | impl<'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 | |
362 | pub(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 | |
389 | pub(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. |
395 | impl<'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 | |
416 | macro_rules! oid { |
417 | ( $first:expr, $second:expr, $( $tail:expr ),* ) => |
418 | ( |
419 | [(40 * $first) + $second, $( $tail ),*] |
420 | ) |
421 | } |
422 | |
423 | #[cfg (test)] |
424 | mod 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 | |