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 crate::{calendar, time, Error};
16
pub(crate) use ring::io::der::{CONSTRUCTED, CONTEXT_SPECIFIC};
17

            
18
// Copied (and extended) from ring's src/der.rs
19
#[allow(clippy::upper_case_acronyms)]
20
#[derive(Clone, Copy, Eq, PartialEq)]
21
#[repr(u8)]
22
pub(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, // 0x30
30
    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

            
39
impl From<Tag> for usize {
40
    #[allow(clippy::as_conversions)]
41
    fn from(tag: Tag) -> Self {
42
        tag as Self
43
    }
44
}
45

            
46
impl From<Tag> for u8 {
47
    #[allow(clippy::as_conversions)]
48
    fn from(tag: Tag) -> Self {
49
        tag as Self
50
    } // XXX: narrowing conversion.
51
}
52

            
53
#[inline(always)]
54
pub(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)]
66
pub(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

            
78
pub(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

            
90
// TODO: investigate taking decoder as a reference to reduce generated code
91
// size.
92
pub(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

            
101
pub(crate) struct Value<'a> {
102
    value: untrusted::Input<'a>,
103
}
104

            
105
impl<'a> Value<'a> {
106
    pub(crate) fn value(&self) -> untrusted::Input<'a> {
107
        self.value
108
    }
109
}
110

            
111
pub(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)]
124
pub(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)]
131
pub(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); // High tag number form is not allowed.
138
    }
139

            
140
    // If the high order bit of the first byte is set to zero then the length
141
    // is encoded in the seven remaining bits of that byte. Otherwise, those
142
    // seven bits represent the number of bytes used to encode the length.
143
    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); // Not the canonical encoding.
149
            }
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); // Not the canonical encoding.
158
            }
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); // Not the canonical encoding.
168
            }
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); // Not the canonical encoding.
182
            }
183
            combined
184
        }
185
        _ => {
186
            return Err(Error::BadDer); // We don't support longer lengths.
187
        }
188
    };
189

            
190
    if length >= size_limit {
191
        return Err(Error::BadDer); // The length is larger than the caller accepts.
192
    }
193

            
194
    let inner = input.read_bytes(length)?;
195
    Ok((tag, inner))
196
}
197

            
198
// Long-form DER encoded lengths of two bytes can express lengths up to the following limit.
199
//
200
// The upstream ring::io::der::read_tag_and_get_value() function limits itself to up to two byte
201
// long-form DER lengths, and so this limit represents the maximum length that was possible to
202
// read before the introduction of the read_tag_and_get_value_limited function.
203
pub(crate) const TWO_BYTE_DER_SIZE: usize = LONG_FORM_LEN_TWO_BYTES_MAX;
204

            
205
// The maximum size of a DER value that Webpki can support reading.
206
//
207
// Webpki limits itself to four byte long-form DER lengths, and so this limit represents
208
// the maximum size tagged DER value that can be read for any purpose.
209
pub(crate) const MAX_DER_SIZE: usize = LONG_FORM_LEN_FOUR_BYTES_MAX;
210

            
211
// DER Tag identifiers have two forms:
212
// * Low tag number form (for tags values in the range [0..30]
213
// * High tag number form (for tag values in the range [31..]
214
// We only support low tag number form.
215
const HIGH_TAG_RANGE_START: u8 = 31;
216

            
217
// DER length octets have two forms:
218
// * Short form: 1 octet supporting lengths between 0 and 127.
219
// * Long definite form: 2 to 127 octets, number of octets encoded into first octet.
220
const SHORT_FORM_LEN_MAX: u8 = 128;
221

            
222
// Leading octet for long definite form DER length expressed in second byte.
223
const LONG_FORM_LEN_ONE_BYTE: u8 = 0x81;
224

            
225
// Maximum size that can be expressed in a one byte long form len.
226
const LONG_FORM_LEN_ONE_BYTE_MAX: usize = 0xff;
227

            
228
// Leading octet for long definite form DER length expressed in subsequent two bytes.
229
const LONG_FORM_LEN_TWO_BYTES: u8 = 0x82;
230

            
231
// Maximum size that can be expressed in a two byte long form len.
232
const LONG_FORM_LEN_TWO_BYTES_MAX: usize = 0xff_ff;
233

            
234
// Leading octet for long definite form DER length expressed in subsequent three bytes.
235
const LONG_FORM_LEN_THREE_BYTES: u8 = 0x83;
236

            
237
// Maximum size that can be expressed in a three byte long form len.
238
const LONG_FORM_LEN_THREE_BYTES_MAX: usize = 0xff_ff_ff;
239

            
240
// Leading octet for long definite form DER length expressed in subsequent four bytes.
241
const LONG_FORM_LEN_FOUR_BYTES: u8 = 0x84;
242

            
243
// Maximum size that can be expressed in a four byte long form der len.
244
const LONG_FORM_LEN_FOUR_BYTES_MAX: usize = 0xff_ff_ff_ff;
245

            
246
// TODO: investigate taking decoder as a reference to reduce generated code
247
// size.
248
pub(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>
255
where
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

            
269
pub(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

            
281
pub(crate) struct BitStringFlags<'a> {
282
    raw_bits: &'a [u8],
283
}
284

            
285
impl<'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

            
298
// ASN.1 BIT STRING fields for sets of flags are encoded in DER with some peculiar details related
299
// to padding. Notably this means we expect a Tag::BitString, a length, an indicator of the number
300
// of bits of padding, and then the actual bit values. See this Stack Overflow discussion[0], and
301
// ITU X690-0207[1] Section 8.6 and Section 11.2 for more information.
302
//
303
// [0]: https://security.stackexchange.com/a/10396
304
// [1]: https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
305
pub(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
        // ITU X690-0207 11.2:
310
        //   "The initial octet shall encode, as an unsigned binary integer with bit 1 as the least
311
        //   significant bit, the number of unused bits in the final subsequent octet.
312
        //   The number shall be in the range zero to seven"
313
        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
        // It's illegal to have more than 7 bits of padding. Similarly, if the raw bitflags
317
        // are empty there should be no padding.
318
        if padding_bits > 7 || (raw_bits.is_empty() && padding_bits != 0) {
319
            return Err(Error::BadDer);
320
        }
321

            
322
        // If there are padding bits then the last bit of the last raw byte must be 0 or the
323
        // distinguished encoding rules are not being followed.
324
        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

            
334
// Like mozilla::pkix, we accept the nonconformant explicit encoding of
335
// the default value (false) for compatibility with real-world certificates.
336
pub(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

            
349
pub(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

            
353
pub(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

            
408
macro_rules! oid {
409
    ( $first:expr, $second:expr, $( $tail:expr ),* ) =>
410
    (
411
        [(40 * $first) + $second, $( $tail ),*]
412
    )
413
}
414

            
415
#[cfg(test)]
416
mod tests {
417
    #[test]
418
    fn test_optional_boolean() {
419
        use super::{optional_boolean, Error};
420

            
421
        // Empty input results in false
422
        assert!(!optional_boolean(&mut bytes_reader(&[])).unwrap());
423

            
424
        // Optional, so another data type results in false
425
        assert!(!optional_boolean(&mut bytes_reader(&[0x05, 0x00])).unwrap());
426

            
427
        // Only 0x00 and 0xff are accepted values
428
        assert_eq!(
429
            optional_boolean(&mut bytes_reader(&[0x01, 0x01, 0x42])).unwrap_err(),
430
            Error::BadDer,
431
        );
432

            
433
        // True
434
        assert!(optional_boolean(&mut bytes_reader(&[0x01, 0x01, 0xff])).unwrap());
435

            
436
        // False
437
        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
        // Unexpected type
445
        assert_eq!(
446
            bit_string_with_no_unused_bits(&mut bytes_reader(&[0x01, 0x01, 0xff])).unwrap_err(),
447
            Error::BadDer,
448
        );
449

            
450
        // Unexpected nonexistent type
451
        assert_eq!(
452
            bit_string_with_no_unused_bits(&mut bytes_reader(&[0x42, 0xff, 0xff])).unwrap_err(),
453
            Error::BadDer,
454
        );
455

            
456
        // Unexpected empty input
457
        assert_eq!(
458
            bit_string_with_no_unused_bits(&mut bytes_reader(&[])).unwrap_err(),
459
            Error::BadDer,
460
        );
461

            
462
        // Valid input with non-zero unused bits
463
        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
        // Valid input
470
        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
            // DER with short-form length encoded as three bytes.
488
            &[EXAMPLE_TAG, 0x83, 0xFF, 0xFF, 0xFF].as_slice(),
489
            // DER with short-form length encoded as four bytes.
490
            &[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
            // read_tag_and_get_value should reject DER with encoded lengths larger than two
496
            // bytes as BadDer.
497
            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
        // read_tag_and_get_value_limited_high_form should reject DER with "high tag number form" tags.
510
        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
            // Two byte length, with expressed length < 128.
522
            &[EXAMPLE_TAG, 0x81, 0x01].as_slice(),
523
            // Three byte length, with expressed length < 256.
524
            &[EXAMPLE_TAG, 0x82, 0x00, 0x01].as_slice(),
525
            // Four byte length, with expressed length, < 65536.
526
            &[EXAMPLE_TAG, 0x83, 0x00, 0x00, 0x01].as_slice(),
527
            // Five byte length, with expressed length < 16777216.
528
            &[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
            // read_tag_and_get_value_limited should reject DER with non-canonical lengths.
534
            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)] // infallible.
606
    const EXAMPLE_TAG: u8 = super::Tag::Sequence as u8;
607

            
608
    #[cfg(feature = "alloc")]
609
    #[allow(clippy::as_conversions)] // test code.
610
    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)] // infallible.
631
    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, // BitString
639
            0x2,           // 2 bytes of content.
640
            0x08,          // 8 bit of padding (illegal!).
641
            0x06,          // 1 byte of bit flags asserting bits 5 and 6.
642
        ]));
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, // BitString
650
            0x2,           // 2 bytes of content.
651
            0x01,          // 1 bit of padding.
652
                           // No flags value (illegal with padding!).
653
        ]));
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, // BitString
661
            0x2,           // 2 bytes of content.
662
            0x01,          // 1 bit of padding.
663
            0xFF,          // Flag data with
664
            0x00,          // trailing zeros.
665
        ]));
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, // BitString
678
            0x2,           // 2 bytes of content.
679
            0x01,          // 1 bit of padding.
680
            0x06,          // 1 byte of bit flags asserting bits 5 and 6.
681
        ]));
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
        // NB: Bits 5 and 6 should be set.
690
        assert!(res.bit_set(5));
691
        assert!(res.bit_set(6));
692
        assert!(!res.bit_set(7));
693
        assert!(!res.bit_set(8));
694
        // Bits outside the range of values shouldn't be considered set.
695
        assert!(!res.bit_set(256));
696
    }
697
}