Coverage Report

Created: 2025-09-27 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rustls-webpki-0.103.5/src/der.rs
Line
Count
Source
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
#[cfg(feature = "alloc")]
16
use alloc::vec::Vec;
17
use core::marker::PhantomData;
18
19
use crate::{Error, error::DerTypeId};
20
21
#[derive(Debug)]
22
pub struct DerIterator<'a, T> {
23
    reader: untrusted::Reader<'a>,
24
    marker: PhantomData<T>,
25
}
26
27
impl<'a, T> DerIterator<'a, T> {
28
    /// [`DerIterator`] will consume all of the bytes in `input` reading values of type `T`.
29
0
    pub(crate) fn new(input: untrusted::Input<'a>) -> Self {
30
0
        Self {
31
0
            reader: untrusted::Reader::new(input),
32
0
            marker: PhantomData,
33
0
        }
34
0
    }
Unexecuted instantiation: <webpki::der::DerIterator<webpki::subject_name::GeneralName>>::new
Unexecuted instantiation: <webpki::der::DerIterator<webpki::cert::CrlDistributionPoint>>::new
Unexecuted instantiation: <webpki::der::DerIterator<webpki::crl::types::BorrowedRevokedCert>>::new
35
}
36
37
impl<'a, T: FromDer<'a>> Iterator for DerIterator<'a, T> {
38
    type Item = Result<T, Error>;
39
40
0
    fn next(&mut self) -> Option<Self::Item> {
41
0
        (!self.reader.at_end()).then(|| T::from_der(&mut self.reader))
Unexecuted instantiation: <webpki::der::DerIterator<webpki::subject_name::GeneralName> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <webpki::der::DerIterator<webpki::cert::CrlDistributionPoint> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <webpki::der::DerIterator<webpki::crl::types::BorrowedRevokedCert> as core::iter::traits::iterator::Iterator>::next::{closure#0}
42
0
    }
Unexecuted instantiation: <webpki::der::DerIterator<webpki::subject_name::GeneralName> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <webpki::der::DerIterator<webpki::cert::CrlDistributionPoint> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <webpki::der::DerIterator<webpki::crl::types::BorrowedRevokedCert> as core::iter::traits::iterator::Iterator>::next
43
}
44
45
pub(crate) trait FromDer<'a>: Sized + 'a {
46
    /// Parse a value of type `Self` from the given DER-encoded input.
47
    fn from_der(reader: &mut untrusted::Reader<'a>) -> Result<Self, Error>;
48
49
    const TYPE_ID: DerTypeId;
50
}
51
52
1.60k
pub(crate) fn read_all<'a, T: FromDer<'a>>(input: untrusted::Input<'a>) -> Result<T, Error> {
53
1.60k
    input.read_all(Error::TrailingData(T::TYPE_ID), T::from_der)
54
1.60k
}
webpki::der::read_all::<webpki::signed_data::SubjectPublicKeyInfo>
Line
Count
Source
52
1.60k
pub(crate) fn read_all<'a, T: FromDer<'a>>(input: untrusted::Input<'a>) -> Result<T, Error> {
53
1.60k
    input.read_all(Error::TrailingData(T::TYPE_ID), T::from_der)
54
1.60k
}
Unexecuted instantiation: webpki::der::read_all::<webpki::subject_name::GeneralName>
Unexecuted instantiation: webpki::der::read_all::<webpki::crl::types::RevocationReason>
Unexecuted instantiation: webpki::der::read_all::<webpki::crl::types::BorrowedCertRevocationList>
55
56
// Copied (and extended) from ring's src/der.rs
57
#[allow(clippy::upper_case_acronyms)]
58
#[derive(Clone, Copy, Eq, PartialEq)]
59
#[repr(u8)]
60
pub(crate) enum Tag {
61
    Boolean = 0x01,
62
    Integer = 0x02,
63
    BitString = 0x03,
64
    OctetString = 0x04,
65
    OID = 0x06,
66
    Enum = 0x0A,
67
    Sequence = CONSTRUCTED | 0x10, // 0x30
68
    UTCTime = 0x17,
69
    GeneralizedTime = 0x18,
70
71
    #[allow(clippy::identity_op)]
72
    ContextSpecificConstructed0 = CONTEXT_SPECIFIC | CONSTRUCTED | 0,
73
    ContextSpecificConstructed1 = CONTEXT_SPECIFIC | CONSTRUCTED | 1,
74
    ContextSpecificConstructed3 = CONTEXT_SPECIFIC | CONSTRUCTED | 3,
75
}
76
77
pub(crate) const CONSTRUCTED: u8 = 0x20;
78
pub(crate) const CONTEXT_SPECIFIC: u8 = 0x80;
79
80
impl From<Tag> for usize {
81
    #[allow(clippy::as_conversions)]
82
500k
    fn from(tag: Tag) -> Self {
83
500k
        tag as Self
84
500k
    }
85
}
86
87
impl From<Tag> for u8 {
88
    #[allow(clippy::as_conversions)]
89
75.4k
    fn from(tag: Tag) -> Self {
90
75.4k
        tag as Self
91
75.4k
    } // XXX: narrowing conversion.
92
}
93
94
#[inline(always)]
95
200k
pub(crate) fn expect_tag_and_get_value_limited<'a>(
96
200k
    input: &mut untrusted::Reader<'a>,
97
200k
    tag: Tag,
98
200k
    size_limit: usize,
99
200k
) -> Result<untrusted::Input<'a>, Error> {
100
200k
    let (actual_tag, inner) = read_tag_and_get_value_limited(input, size_limit)?;
101
199k
    if usize::from(tag) != usize::from(actual_tag) {
102
76
        return Err(Error::BadDer);
103
199k
    }
104
199k
    Ok(inner)
105
200k
}
106
107
184k
pub(crate) fn nested_limited<'a, R>(
108
184k
    input: &mut untrusted::Reader<'a>,
109
184k
    tag: Tag,
110
184k
    error: Error,
111
184k
    decoder: impl FnOnce(&mut untrusted::Reader<'a>) -> Result<R, Error>,
112
184k
    size_limit: usize,
113
184k
) -> Result<R, Error> {
114
184k
    match expect_tag_and_get_value_limited(input, tag, size_limit) {
115
183k
        Ok(value) => value.read_all(error, decoder),
116
778
        Err(_) => Err(error),
117
    }
118
184k
}
Unexecuted instantiation: webpki::der::nested_limited::<rustls_pki_types::TrustAnchor, webpki::trust_anchor::extract_trust_anchor_from_v1_cert_der::{closure#0}::{closure#0}::{closure#0}>
Unexecuted instantiation: webpki::der::nested_limited::<rustls_pki_types::TrustAnchor, webpki::trust_anchor::extract_trust_anchor_from_v1_cert_der::{closure#0}::{closure#0}>
webpki::der::nested_limited::<rustls_pki_types::UnixTime, <rustls_pki_types::UnixTime as webpki::der::FromDer>::from_der::{closure#0}>
Line
Count
Source
107
3.61k
pub(crate) fn nested_limited<'a, R>(
108
3.61k
    input: &mut untrusted::Reader<'a>,
109
3.61k
    tag: Tag,
110
3.61k
    error: Error,
111
3.61k
    decoder: impl FnOnce(&mut untrusted::Reader<'a>) -> Result<R, Error>,
112
3.61k
    size_limit: usize,
113
3.61k
) -> Result<R, Error> {
114
3.61k
    match expect_tag_and_get_value_limited(input, tag, size_limit) {
115
3.54k
        Ok(value) => value.read_all(error, decoder),
116
76
        Err(_) => Err(error),
117
    }
118
3.61k
}
Unexecuted instantiation: webpki::der::nested_limited::<webpki::cert::CrlDistributionPoint, <webpki::cert::CrlDistributionPoint as webpki::der::FromDer>::from_der::{closure#0}>
webpki::der::nested_limited::<untrusted::input::Input, webpki::der::bit_string_with_no_unused_bits::{closure#0}>
Line
Count
Source
107
17.5k
pub(crate) fn nested_limited<'a, R>(
108
17.5k
    input: &mut untrusted::Reader<'a>,
109
17.5k
    tag: Tag,
110
17.5k
    error: Error,
111
17.5k
    decoder: impl FnOnce(&mut untrusted::Reader<'a>) -> Result<R, Error>,
112
17.5k
    size_limit: usize,
113
17.5k
) -> Result<R, Error> {
114
17.5k
    match expect_tag_and_get_value_limited(input, tag, size_limit) {
115
17.4k
        Ok(value) => value.read_all(error, decoder),
116
131
        Err(_) => Err(error),
117
    }
118
17.5k
}
Unexecuted instantiation: webpki::der::nested_limited::<webpki::crl::types::BorrowedRevokedCert, <webpki::crl::types::BorrowedRevokedCert as webpki::der::FromDer>::from_der::{closure#0}>
webpki::der::nested_limited::<(untrusted::input::Input, webpki::signed_data::SignedData), <webpki::cert::Cert>::from_der::{closure#0}::{closure#0}>
Line
Count
Source
107
16.2k
pub(crate) fn nested_limited<'a, R>(
108
16.2k
    input: &mut untrusted::Reader<'a>,
109
16.2k
    tag: Tag,
110
16.2k
    error: Error,
111
16.2k
    decoder: impl FnOnce(&mut untrusted::Reader<'a>) -> Result<R, Error>,
112
16.2k
    size_limit: usize,
113
16.2k
) -> Result<R, Error> {
114
16.2k
    match expect_tag_and_get_value_limited(input, tag, size_limit) {
115
16.1k
        Ok(value) => value.read_all(error, decoder),
116
107
        Err(_) => Err(error),
117
    }
118
16.2k
}
Unexecuted instantiation: webpki::der::nested_limited::<(untrusted::input::Input, webpki::signed_data::SignedData), <webpki::crl::types::BorrowedCertRevocationList as webpki::der::FromDer>::from_der::{closure#0}>
webpki::der::nested_limited::<bool, <bool as webpki::der::FromDer>::from_der::{closure#0}>
Line
Count
Source
107
27.7k
pub(crate) fn nested_limited<'a, R>(
108
27.7k
    input: &mut untrusted::Reader<'a>,
109
27.7k
    tag: Tag,
110
27.7k
    error: Error,
111
27.7k
    decoder: impl FnOnce(&mut untrusted::Reader<'a>) -> Result<R, Error>,
112
27.7k
    size_limit: usize,
113
27.7k
) -> Result<R, Error> {
114
27.7k
    match expect_tag_and_get_value_limited(input, tag, size_limit) {
115
27.7k
        Ok(value) => value.read_all(error, decoder),
116
70
        Err(_) => Err(error),
117
    }
118
27.7k
}
webpki::der::nested_limited::<(), webpki::der::nested_of_mut<<webpki::cert::Cert>::from_der::{closure#1}::{closure#0}::{closure#0}>::{closure#0}>
Line
Count
Source
107
15.5k
pub(crate) fn nested_limited<'a, R>(
108
15.5k
    input: &mut untrusted::Reader<'a>,
109
15.5k
    tag: Tag,
110
15.5k
    error: Error,
111
15.5k
    decoder: impl FnOnce(&mut untrusted::Reader<'a>) -> Result<R, Error>,
112
15.5k
    size_limit: usize,
113
15.5k
) -> Result<R, Error> {
114
15.5k
    match expect_tag_and_get_value_limited(input, tag, size_limit) {
115
15.4k
        Ok(value) => value.read_all(error, decoder),
116
111
        Err(_) => Err(error),
117
    }
118
15.5k
}
Unexecuted instantiation: webpki::der::nested_limited::<(), webpki::der::nested_of_mut<<webpki::crl::types::BorrowedCertRevocationList as webpki::der::FromDer>::from_der::{closure#1}::{closure#0}::{closure#0}>::{closure#0}>
webpki::der::nested_limited::<(), webpki::der::nested_of_mut<<webpki::cert::Cert>::from_der::{closure#1}::{closure#0}::{closure#0}>::{closure#0}::{closure#0}>
Line
Count
Source
107
71.9k
pub(crate) fn nested_limited<'a, R>(
108
71.9k
    input: &mut untrusted::Reader<'a>,
109
71.9k
    tag: Tag,
110
71.9k
    error: Error,
111
71.9k
    decoder: impl FnOnce(&mut untrusted::Reader<'a>) -> Result<R, Error>,
112
71.9k
    size_limit: usize,
113
71.9k
) -> Result<R, Error> {
114
71.9k
    match expect_tag_and_get_value_limited(input, tag, size_limit) {
115
71.8k
        Ok(value) => value.read_all(error, decoder),
116
116
        Err(_) => Err(error),
117
    }
118
71.9k
}
Unexecuted instantiation: webpki::der::nested_limited::<(), webpki::der::nested_of_mut<<webpki::crl::types::BorrowedCertRevocationList as webpki::der::FromDer>::from_der::{closure#1}::{closure#0}::{closure#0}>::{closure#0}::{closure#0}>
webpki::der::nested_limited::<(), <webpki::cert::Cert>::from_der::{closure#1}::{closure#0}>
Line
Count
Source
107
15.6k
pub(crate) fn nested_limited<'a, R>(
108
15.6k
    input: &mut untrusted::Reader<'a>,
109
15.6k
    tag: Tag,
110
15.6k
    error: Error,
111
15.6k
    decoder: impl FnOnce(&mut untrusted::Reader<'a>) -> Result<R, Error>,
112
15.6k
    size_limit: usize,
113
15.6k
) -> Result<R, Error> {
114
15.6k
    match expect_tag_and_get_value_limited(input, tag, size_limit) {
115
15.5k
        Ok(value) => value.read_all(error, decoder),
116
91
        Err(_) => Err(error),
117
    }
118
15.6k
}
Unexecuted instantiation: webpki::der::nested_limited::<(), <webpki::crl::types::BorrowedCertRevocationList as webpki::der::FromDer>::from_der::{closure#1}::{closure#0}>
Unexecuted instantiation: webpki::der::nested_limited::<(), <webpki::crl::types::BorrowedRevokedCert as webpki::der::FromDer>::from_der::{closure#0}::{closure#1}>
Unexecuted instantiation: webpki::der::nested_limited::<(), <webpki::crl::types::IssuingDistributionPoint>::from_der::{closure#0}>
webpki::der::nested_limited::<(), webpki::cert::version3::{closure#0}>
Line
Count
Source
107
15.8k
pub(crate) fn nested_limited<'a, R>(
108
15.8k
    input: &mut untrusted::Reader<'a>,
109
15.8k
    tag: Tag,
110
15.8k
    error: Error,
111
15.8k
    decoder: impl FnOnce(&mut untrusted::Reader<'a>) -> Result<R, Error>,
112
15.8k
    size_limit: usize,
113
15.8k
) -> Result<R, Error> {
114
15.8k
    match expect_tag_and_get_value_limited(input, tag, size_limit) {
115
15.7k
        Ok(value) => value.read_all(error, decoder),
116
76
        Err(_) => Err(error),
117
    }
118
15.8k
}
119
120
// TODO: investigate taking decoder as a reference to reduce generated code
121
// size.
122
184k
pub(crate) fn nested<'a, R>(
123
184k
    input: &mut untrusted::Reader<'a>,
124
184k
    tag: Tag,
125
184k
    error: Error,
126
184k
    decoder: impl FnOnce(&mut untrusted::Reader<'a>) -> Result<R, Error>,
127
184k
) -> Result<R, Error> {
128
184k
    nested_limited(input, tag, error, decoder, TWO_BYTE_DER_SIZE)
129
184k
}
Unexecuted instantiation: webpki::der::nested::<rustls_pki_types::TrustAnchor, webpki::trust_anchor::extract_trust_anchor_from_v1_cert_der::{closure#0}::{closure#0}::{closure#0}>
Unexecuted instantiation: webpki::der::nested::<rustls_pki_types::TrustAnchor, webpki::trust_anchor::extract_trust_anchor_from_v1_cert_der::{closure#0}::{closure#0}>
webpki::der::nested::<rustls_pki_types::UnixTime, <rustls_pki_types::UnixTime as webpki::der::FromDer>::from_der::{closure#0}>
Line
Count
Source
122
3.61k
pub(crate) fn nested<'a, R>(
123
3.61k
    input: &mut untrusted::Reader<'a>,
124
3.61k
    tag: Tag,
125
3.61k
    error: Error,
126
3.61k
    decoder: impl FnOnce(&mut untrusted::Reader<'a>) -> Result<R, Error>,
127
3.61k
) -> Result<R, Error> {
128
3.61k
    nested_limited(input, tag, error, decoder, TWO_BYTE_DER_SIZE)
129
3.61k
}
Unexecuted instantiation: webpki::der::nested::<webpki::cert::CrlDistributionPoint, <webpki::cert::CrlDistributionPoint as webpki::der::FromDer>::from_der::{closure#0}>
webpki::der::nested::<untrusted::input::Input, webpki::der::bit_string_with_no_unused_bits::{closure#0}>
Line
Count
Source
122
17.5k
pub(crate) fn nested<'a, R>(
123
17.5k
    input: &mut untrusted::Reader<'a>,
124
17.5k
    tag: Tag,
125
17.5k
    error: Error,
126
17.5k
    decoder: impl FnOnce(&mut untrusted::Reader<'a>) -> Result<R, Error>,
127
17.5k
) -> Result<R, Error> {
128
17.5k
    nested_limited(input, tag, error, decoder, TWO_BYTE_DER_SIZE)
129
17.5k
}
Unexecuted instantiation: webpki::der::nested::<webpki::crl::types::BorrowedRevokedCert, <webpki::crl::types::BorrowedRevokedCert as webpki::der::FromDer>::from_der::{closure#0}>
webpki::der::nested::<(untrusted::input::Input, webpki::signed_data::SignedData), <webpki::cert::Cert>::from_der::{closure#0}::{closure#0}>
Line
Count
Source
122
16.2k
pub(crate) fn nested<'a, R>(
123
16.2k
    input: &mut untrusted::Reader<'a>,
124
16.2k
    tag: Tag,
125
16.2k
    error: Error,
126
16.2k
    decoder: impl FnOnce(&mut untrusted::Reader<'a>) -> Result<R, Error>,
127
16.2k
) -> Result<R, Error> {
128
16.2k
    nested_limited(input, tag, error, decoder, TWO_BYTE_DER_SIZE)
129
16.2k
}
webpki::der::nested::<bool, <bool as webpki::der::FromDer>::from_der::{closure#0}>
Line
Count
Source
122
27.7k
pub(crate) fn nested<'a, R>(
123
27.7k
    input: &mut untrusted::Reader<'a>,
124
27.7k
    tag: Tag,
125
27.7k
    error: Error,
126
27.7k
    decoder: impl FnOnce(&mut untrusted::Reader<'a>) -> Result<R, Error>,
127
27.7k
) -> Result<R, Error> {
128
27.7k
    nested_limited(input, tag, error, decoder, TWO_BYTE_DER_SIZE)
129
27.7k
}
webpki::der::nested::<(), webpki::der::nested_of_mut<<webpki::cert::Cert>::from_der::{closure#1}::{closure#0}::{closure#0}>::{closure#0}>
Line
Count
Source
122
15.5k
pub(crate) fn nested<'a, R>(
123
15.5k
    input: &mut untrusted::Reader<'a>,
124
15.5k
    tag: Tag,
125
15.5k
    error: Error,
126
15.5k
    decoder: impl FnOnce(&mut untrusted::Reader<'a>) -> Result<R, Error>,
127
15.5k
) -> Result<R, Error> {
128
15.5k
    nested_limited(input, tag, error, decoder, TWO_BYTE_DER_SIZE)
129
15.5k
}
Unexecuted instantiation: webpki::der::nested::<(), webpki::der::nested_of_mut<<webpki::crl::types::BorrowedCertRevocationList as webpki::der::FromDer>::from_der::{closure#1}::{closure#0}::{closure#0}>::{closure#0}>
webpki::der::nested::<(), webpki::der::nested_of_mut<<webpki::cert::Cert>::from_der::{closure#1}::{closure#0}::{closure#0}>::{closure#0}::{closure#0}>
Line
Count
Source
122
71.9k
pub(crate) fn nested<'a, R>(
123
71.9k
    input: &mut untrusted::Reader<'a>,
124
71.9k
    tag: Tag,
125
71.9k
    error: Error,
126
71.9k
    decoder: impl FnOnce(&mut untrusted::Reader<'a>) -> Result<R, Error>,
127
71.9k
) -> Result<R, Error> {
128
71.9k
    nested_limited(input, tag, error, decoder, TWO_BYTE_DER_SIZE)
129
71.9k
}
Unexecuted instantiation: webpki::der::nested::<(), webpki::der::nested_of_mut<<webpki::crl::types::BorrowedCertRevocationList as webpki::der::FromDer>::from_der::{closure#1}::{closure#0}::{closure#0}>::{closure#0}::{closure#0}>
webpki::der::nested::<(), <webpki::cert::Cert>::from_der::{closure#1}::{closure#0}>
Line
Count
Source
122
15.6k
pub(crate) fn nested<'a, R>(
123
15.6k
    input: &mut untrusted::Reader<'a>,
124
15.6k
    tag: Tag,
125
15.6k
    error: Error,
126
15.6k
    decoder: impl FnOnce(&mut untrusted::Reader<'a>) -> Result<R, Error>,
127
15.6k
) -> Result<R, Error> {
128
15.6k
    nested_limited(input, tag, error, decoder, TWO_BYTE_DER_SIZE)
129
15.6k
}
Unexecuted instantiation: webpki::der::nested::<(), <webpki::crl::types::BorrowedCertRevocationList as webpki::der::FromDer>::from_der::{closure#1}::{closure#0}>
Unexecuted instantiation: webpki::der::nested::<(), <webpki::crl::types::BorrowedRevokedCert as webpki::der::FromDer>::from_der::{closure#0}::{closure#1}>
Unexecuted instantiation: webpki::der::nested::<(), <webpki::crl::types::IssuingDistributionPoint>::from_der::{closure#0}>
webpki::der::nested::<(), webpki::cert::version3::{closure#0}>
Line
Count
Source
122
15.8k
pub(crate) fn nested<'a, R>(
123
15.8k
    input: &mut untrusted::Reader<'a>,
124
15.8k
    tag: Tag,
125
15.8k
    error: Error,
126
15.8k
    decoder: impl FnOnce(&mut untrusted::Reader<'a>) -> Result<R, Error>,
127
15.8k
) -> Result<R, Error> {
128
15.8k
    nested_limited(input, tag, error, decoder, TWO_BYTE_DER_SIZE)
129
15.8k
}
130
131
300k
pub(crate) fn expect_tag<'a>(
132
300k
    input: &mut untrusted::Reader<'a>,
133
300k
    tag: Tag,
134
300k
) -> Result<untrusted::Input<'a>, Error> {
135
300k
    let (actual_tag, value) = read_tag_and_get_value_limited(input, TWO_BYTE_DER_SIZE)?;
136
300k
    if usize::from(tag) != usize::from(actual_tag) {
137
45
        return Err(Error::BadDer);
138
300k
    }
139
140
300k
    Ok(value)
141
300k
}
142
143
#[inline(always)]
144
3.43k
pub(crate) fn read_tag_and_get_value<'a>(
145
3.43k
    input: &mut untrusted::Reader<'a>,
146
3.43k
) -> Result<(u8, untrusted::Input<'a>), Error> {
147
3.43k
    read_tag_and_get_value_limited(input, TWO_BYTE_DER_SIZE)
148
3.43k
}
149
150
#[inline(always)]
151
504k
pub(crate) fn read_tag_and_get_value_limited<'a>(
152
504k
    input: &mut untrusted::Reader<'a>,
153
504k
    size_limit: usize,
154
504k
) -> Result<(u8, untrusted::Input<'a>), Error> {
155
504k
    let tag = input.read_byte().map_err(end_of_input_err)?;
156
504k
    if (tag & HIGH_TAG_RANGE_START) == HIGH_TAG_RANGE_START {
157
34
        return Err(Error::BadDer); // High tag number form is not allowed.
158
504k
    }
159
160
    // If the high order bit of the first byte is set to zero then the length
161
    // is encoded in the seven remaining bits of that byte. Otherwise, those
162
    // seven bits represent the number of bytes used to encode the length.
163
504k
    let length = match input.read_byte().map_err(end_of_input_err)? {
164
504k
        n if (n & SHORT_FORM_LEN_MAX) == 0 => usize::from(n),
165
        LONG_FORM_LEN_ONE_BYTE => {
166
31.0k
            let length_byte = input.read_byte().map_err(end_of_input_err)?;
167
30.9k
            if length_byte < SHORT_FORM_LEN_MAX {
168
28
                return Err(Error::BadDer); // Not the canonical encoding.
169
30.9k
            }
170
30.9k
            usize::from(length_byte)
171
        }
172
        LONG_FORM_LEN_TWO_BYTES => {
173
32.4k
            let length_byte_one = usize::from(input.read_byte().map_err(end_of_input_err)?);
174
32.4k
            let length_byte_two = usize::from(input.read_byte().map_err(end_of_input_err)?);
175
32.4k
            let combined = (length_byte_one << 8) | length_byte_two;
176
32.4k
            if combined <= LONG_FORM_LEN_ONE_BYTE_MAX {
177
23
                return Err(Error::BadDer); // Not the canonical encoding.
178
32.4k
            }
179
32.4k
            combined
180
        }
181
        LONG_FORM_LEN_THREE_BYTES => {
182
166
            let length_byte_one = usize::from(input.read_byte().map_err(end_of_input_err)?);
183
152
            let length_byte_two = usize::from(input.read_byte().map_err(end_of_input_err)?);
184
136
            let length_byte_three = usize::from(input.read_byte().map_err(end_of_input_err)?);
185
122
            let combined = (length_byte_one << 16) | (length_byte_two << 8) | length_byte_three;
186
122
            if combined <= LONG_FORM_LEN_TWO_BYTES_MAX {
187
22
                return Err(Error::BadDer); // Not the canonical encoding.
188
100
            }
189
100
            combined
190
        }
191
        LONG_FORM_LEN_FOUR_BYTES => {
192
235
            let length_byte_one = usize::from(input.read_byte().map_err(end_of_input_err)?);
193
221
            let length_byte_two = usize::from(input.read_byte().map_err(end_of_input_err)?);
194
204
            let length_byte_three = usize::from(input.read_byte().map_err(end_of_input_err)?);
195
190
            let length_byte_four = usize::from(input.read_byte().map_err(end_of_input_err)?);
196
177
            let combined = (length_byte_one << 24)
197
177
                | (length_byte_two << 16)
198
177
                | (length_byte_three << 8)
199
177
                | length_byte_four;
200
177
            if combined <= LONG_FORM_LEN_THREE_BYTES_MAX {
201
24
                return Err(Error::BadDer); // Not the canonical encoding.
202
153
            }
203
153
            combined
204
        }
205
        _ => {
206
90
            return Err(Error::BadDer); // We don't support longer lengths.
207
        }
208
    };
209
210
504k
    if length >= size_limit {
211
253
        return Err(Error::BadDer); // The length is larger than the caller accepts.
212
503k
    }
213
214
503k
    let inner = input.read_bytes(length).map_err(end_of_input_err)?;
215
503k
    Ok((tag, inner))
216
504k
}
217
218
/// Prepend `bytes` with the given ASN.1 [`Tag`] and appropriately encoded length byte(s).
219
/// Useful for "adding back" ASN.1 bytes to parsed content.
220
#[cfg(feature = "alloc")]
221
#[allow(clippy::as_conversions)]
222
0
pub(crate) fn asn1_wrap(tag: Tag, bytes: &[u8]) -> Vec<u8> {
223
0
    let len = bytes.len();
224
    // The length is encoded differently depending on how many bytes there are
225
0
    if len < usize::from(SHORT_FORM_LEN_MAX) {
226
        // Short form: the length is encoded using a single byte
227
        // Contents: Tag byte, single length byte, and passed bytes
228
0
        let mut ret = Vec::with_capacity(2 + len);
229
0
        ret.push(tag.into()); // Tag byte
230
0
        ret.push(len as u8); // Single length byte
231
0
        ret.extend_from_slice(bytes); // Passed bytes
232
0
        ret
233
    } else {
234
        // Long form: The length is encoded using multiple bytes
235
        // Contents: Tag byte, number-of-length-bytes byte, length bytes, and passed bytes
236
        // The first byte indicates how many more bytes will be used to encode the length
237
        // First, get a big-endian representation of the byte slice's length
238
0
        let size = len.to_be_bytes();
239
        // Find the number of leading empty bytes in that representation
240
        // This will determine the smallest number of bytes we need to encode the length
241
0
        let leading_zero_bytes = size
242
0
            .iter()
243
0
            .position(|&byte| byte != 0)
244
0
            .unwrap_or(size.len());
245
0
        assert!(leading_zero_bytes < size.len());
246
        // Number of bytes used - number of not needed bytes = smallest number needed
247
0
        let encoded_bytes = size.len() - leading_zero_bytes;
248
0
        let mut ret = Vec::with_capacity(2 + encoded_bytes + len);
249
        // Indicate this is a number-of-length-bytes byte by setting the high order bit
250
0
        let number_of_length_bytes_byte = SHORT_FORM_LEN_MAX + encoded_bytes as u8;
251
0
        ret.push(tag.into()); // Tag byte
252
0
        ret.push(number_of_length_bytes_byte); // Number-of-length-bytes byte
253
0
        ret.extend_from_slice(&size[leading_zero_bytes..]); // Length bytes
254
0
        ret.extend_from_slice(bytes); // Passed bytes
255
0
        ret
256
    }
257
0
}
258
259
// Long-form DER encoded lengths of two bytes can express lengths up to the following limit.
260
//
261
// The upstream ring::io::der::read_tag_and_get_value() function limits itself to up to two byte
262
// long-form DER lengths, and so this limit represents the maximum length that was possible to
263
// read before the introduction of the read_tag_and_get_value_limited function.
264
pub(crate) const TWO_BYTE_DER_SIZE: usize = LONG_FORM_LEN_TWO_BYTES_MAX;
265
266
// The maximum size of a DER value that Webpki can support reading.
267
//
268
// Webpki limits itself to four byte long-form DER lengths, and so this limit represents
269
// the maximum size tagged DER value that can be read for any purpose.
270
pub(crate) const MAX_DER_SIZE: usize = LONG_FORM_LEN_FOUR_BYTES_MAX;
271
272
// DER Tag identifiers have two forms:
273
// * Low tag number form (for tags values in the range [0..30]
274
// * High tag number form (for tag values in the range [31..]
275
// We only support low tag number form.
276
const HIGH_TAG_RANGE_START: u8 = 31;
277
278
// DER length octets have two forms:
279
// * Short form: 1 octet supporting lengths between 0 and 127.
280
// * Long definite form: 2 to 127 octets, number of octets encoded into first octet.
281
const SHORT_FORM_LEN_MAX: u8 = 128;
282
283
// Leading octet for long definite form DER length expressed in second byte.
284
const LONG_FORM_LEN_ONE_BYTE: u8 = 0x81;
285
286
// Maximum size that can be expressed in a one byte long form len.
287
const LONG_FORM_LEN_ONE_BYTE_MAX: usize = 0xff;
288
289
// Leading octet for long definite form DER length expressed in subsequent two bytes.
290
const LONG_FORM_LEN_TWO_BYTES: u8 = 0x82;
291
292
// Maximum size that can be expressed in a two byte long form len.
293
const LONG_FORM_LEN_TWO_BYTES_MAX: usize = 0xff_ff;
294
295
// Leading octet for long definite form DER length expressed in subsequent three bytes.
296
const LONG_FORM_LEN_THREE_BYTES: u8 = 0x83;
297
298
// Maximum size that can be expressed in a three byte long form len.
299
const LONG_FORM_LEN_THREE_BYTES_MAX: usize = 0xff_ff_ff;
300
301
// Leading octet for long definite form DER length expressed in subsequent four bytes.
302
const LONG_FORM_LEN_FOUR_BYTES: u8 = 0x84;
303
304
// Maximum size that can be expressed in a four byte long form der len.
305
const LONG_FORM_LEN_FOUR_BYTES_MAX: usize = 0xff_ff_ff_ff;
306
307
// TODO: investigate taking decoder as a reference to reduce generated code
308
// size.
309
15.5k
pub(crate) fn nested_of_mut<'a>(
310
15.5k
    input: &mut untrusted::Reader<'a>,
311
15.5k
    outer_tag: Tag,
312
15.5k
    inner_tag: Tag,
313
15.5k
    error: Error,
314
15.5k
    allow_empty: bool,
315
15.5k
    mut decoder: impl FnMut(&mut untrusted::Reader<'a>) -> Result<(), Error>,
316
15.5k
) -> Result<(), Error> {
317
15.5k
    nested(input, outer_tag, error.clone(), |outer| {
318
15.4k
        if allow_empty && outer.at_end() {
319
3
            return Ok(());
320
15.4k
        }
321
        loop {
322
71.9k
            nested(outer, inner_tag, error.clone(), |inner| decoder(inner))?;
webpki::der::nested_of_mut::<<webpki::cert::Cert>::from_der::{closure#1}::{closure#0}::{closure#0}>::{closure#0}::{closure#0}
Line
Count
Source
322
71.8k
            nested(outer, inner_tag, error.clone(), |inner| decoder(inner))?;
Unexecuted instantiation: webpki::der::nested_of_mut::<<webpki::crl::types::BorrowedCertRevocationList as webpki::der::FromDer>::from_der::{closure#1}::{closure#0}::{closure#0}>::{closure#0}::{closure#0}
323
71.6k
            if outer.at_end() {
324
15.1k
                break;
325
56.4k
            }
326
        }
327
15.1k
        Ok(())
328
15.4k
    })
webpki::der::nested_of_mut::<<webpki::cert::Cert>::from_der::{closure#1}::{closure#0}::{closure#0}>::{closure#0}
Line
Count
Source
317
15.4k
    nested(input, outer_tag, error.clone(), |outer| {
318
15.4k
        if allow_empty && outer.at_end() {
319
3
            return Ok(());
320
15.4k
        }
321
        loop {
322
71.9k
            nested(outer, inner_tag, error.clone(), |inner| decoder(inner))?;
323
71.6k
            if outer.at_end() {
324
15.1k
                break;
325
56.4k
            }
326
        }
327
15.1k
        Ok(())
328
15.4k
    })
Unexecuted instantiation: webpki::der::nested_of_mut::<<webpki::crl::types::BorrowedCertRevocationList as webpki::der::FromDer>::from_der::{closure#1}::{closure#0}::{closure#0}>::{closure#0}
329
15.5k
}
webpki::der::nested_of_mut::<<webpki::cert::Cert>::from_der::{closure#1}::{closure#0}::{closure#0}>
Line
Count
Source
309
15.5k
pub(crate) fn nested_of_mut<'a>(
310
15.5k
    input: &mut untrusted::Reader<'a>,
311
15.5k
    outer_tag: Tag,
312
15.5k
    inner_tag: Tag,
313
15.5k
    error: Error,
314
15.5k
    allow_empty: bool,
315
15.5k
    mut decoder: impl FnMut(&mut untrusted::Reader<'a>) -> Result<(), Error>,
316
15.5k
) -> Result<(), Error> {
317
15.5k
    nested(input, outer_tag, error.clone(), |outer| {
318
        if allow_empty && outer.at_end() {
319
            return Ok(());
320
        }
321
        loop {
322
            nested(outer, inner_tag, error.clone(), |inner| decoder(inner))?;
323
            if outer.at_end() {
324
                break;
325
            }
326
        }
327
        Ok(())
328
    })
329
15.5k
}
Unexecuted instantiation: webpki::der::nested_of_mut::<<webpki::crl::types::BorrowedCertRevocationList as webpki::der::FromDer>::from_der::{closure#1}::{closure#0}::{closure#0}>
330
331
17.5k
pub(crate) fn bit_string_with_no_unused_bits<'a>(
332
17.5k
    input: &mut untrusted::Reader<'a>,
333
17.5k
) -> Result<untrusted::Input<'a>, Error> {
334
17.5k
    nested(
335
17.5k
        input,
336
17.5k
        Tag::BitString,
337
17.5k
        Error::TrailingData(DerTypeId::BitString),
338
17.4k
        |value| {
339
17.4k
            let unused_bits_at_end = value.read_byte().map_err(|_| Error::BadDer)?;
340
17.4k
            if unused_bits_at_end != 0 {
341
6
                return Err(Error::BadDer);
342
17.4k
            }
343
17.4k
            Ok(value.read_bytes_to_end())
344
17.4k
        },
345
    )
346
17.5k
}
347
348
pub(crate) struct BitStringFlags<'a> {
349
    raw_bits: &'a [u8],
350
}
351
352
impl BitStringFlags<'_> {
353
0
    pub(crate) fn bit_set(&self, bit: usize) -> bool {
354
0
        let byte_index = bit / 8;
355
0
        let bit_shift = 7 - (bit % 8);
356
357
0
        if self.raw_bits.len() < (byte_index + 1) {
358
0
            false
359
        } else {
360
0
            ((self.raw_bits[byte_index] >> bit_shift) & 1) != 0
361
        }
362
0
    }
363
}
364
365
// ASN.1 BIT STRING fields for sets of flags are encoded in DER with some peculiar details related
366
// to padding. Notably this means we expect an indicator of the number of bits of padding, and then
367
// the actual bit values. See this Stack Overflow discussion[0], and ITU X690-0207[1] Section 8.6
368
// and Section 11.2 for more information.
369
//
370
// [0]: https://security.stackexchange.com/a/10396
371
// [1]: https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
372
0
pub(crate) fn bit_string_flags(input: untrusted::Input<'_>) -> Result<BitStringFlags<'_>, Error> {
373
0
    input.read_all(Error::BadDer, |bit_string| {
374
        // ITU X690-0207 11.2:
375
        //   "The initial octet shall encode, as an unsigned binary integer with bit 1 as the least
376
        //   significant bit, the number of unused bits in the final subsequent octet.
377
        //   The number shall be in the range zero to seven"
378
0
        let padding_bits = bit_string.read_byte().map_err(|_| Error::BadDer)?;
379
0
        let raw_bits = bit_string.read_bytes_to_end().as_slice_less_safe();
380
381
        // It's illegal to have more than 7 bits of padding. Similarly, if the raw bitflags
382
        // are empty there should be no padding.
383
0
        if padding_bits > 7 || (raw_bits.is_empty() && padding_bits != 0) {
384
0
            return Err(Error::BadDer);
385
0
        }
386
387
        // If there are padding bits then the last bit of the last raw byte must be 0 or the
388
        // distinguished encoding rules are not being followed.
389
0
        let last_byte = raw_bits[raw_bits.len() - 1];
390
0
        let padding_mask = (1 << padding_bits) - 1;
391
392
0
        match padding_bits > 0 && (last_byte & padding_mask) != 0 {
393
0
            true => Err(Error::BadDer),
394
0
            false => Ok(BitStringFlags { raw_bits }),
395
        }
396
0
    })
397
0
}
398
399
impl<'a> FromDer<'a> for u8 {
400
15.7k
    fn from_der(reader: &mut untrusted::Reader<'a>) -> Result<Self, Error> {
401
15.7k
        match *nonnegative_integer(reader)?.as_slice_less_safe() {
402
15.7k
            [b] => Ok(b),
403
4
            _ => Err(Error::BadDer),
404
        }
405
15.7k
    }
406
407
    const TYPE_ID: DerTypeId = DerTypeId::U8;
408
}
409
410
15.7k
pub(crate) fn nonnegative_integer<'a>(
411
15.7k
    input: &mut untrusted::Reader<'a>,
412
15.7k
) -> Result<untrusted::Input<'a>, Error> {
413
15.7k
    let value = expect_tag(input, Tag::Integer)?;
414
15.7k
    match value
415
15.7k
        .as_slice_less_safe()
416
15.7k
        .split_first()
417
15.7k
        .ok_or(Error::BadDer)?
418
    {
419
        // Zero or leading zero.
420
14
        (0, rest) => {
421
14
            match rest.first() {
422
                // Zero
423
5
                None => Ok(value),
424
                // Necessary leading zero.
425
9
                Some(&second) if second & 0x80 == 0x80 => Ok(untrusted::Input::from(rest)),
426
                // Unnecessary leading zero.
427
5
                _ => Err(Error::BadDer),
428
            }
429
        }
430
        // Positive value with no leading zero.
431
15.7k
        (first, _) if first & 0x80 == 0x00 => Ok(value),
432
        // Negative value.
433
9
        (_, _) => Err(Error::BadDer),
434
    }
435
15.7k
}
436
437
667
pub(crate) fn end_of_input_err(_: untrusted::EndOfInput) -> Error {
438
667
    Error::BadDer
439
667
}
440
441
// Like mozilla::pkix, we accept the nonconformant explicit encoding of
442
// the default value (false) for compatibility with real-world certificates.
443
impl<'a> FromDer<'a> for bool {
444
71.8k
    fn from_der(reader: &mut untrusted::Reader<'a>) -> Result<Self, Error> {
445
71.8k
        if !reader.peek(Tag::Boolean.into()) {
446
44.0k
            return Ok(false);
447
27.7k
        }
448
449
27.7k
        nested(
450
27.7k
            reader,
451
27.7k
            Tag::Boolean,
452
27.7k
            Error::TrailingData(Self::TYPE_ID),
453
27.7k
            |input| match input.read_byte() {
454
27.4k
                Ok(0xff) => Ok(true),
455
216
                Ok(0x00) => Ok(false),
456
6
                _ => Err(Error::BadDer),
457
27.7k
            },
458
        )
459
71.8k
    }
460
461
    const TYPE_ID: DerTypeId = DerTypeId::Bool;
462
}
463
464
macro_rules! oid {
465
    ( $first:expr, $second:expr, $( $tail:expr ),* ) =>
466
    (
467
        [(40 * $first) + $second, $( $tail ),*]
468
    )
469
}
470
471
#[cfg(test)]
472
mod tests {
473
    use super::DerTypeId;
474
    use std::prelude::v1::*;
475
476
    #[cfg(feature = "alloc")]
477
    #[test]
478
    fn test_asn1_wrap() {
479
        // Prepend stuff to `bytes` to put it in a DER SEQUENCE.
480
        let wrap_in_sequence = |bytes: &[u8]| super::asn1_wrap(super::Tag::Sequence, bytes);
481
482
        // Empty slice
483
        assert_eq!(vec![0x30, 0x00], wrap_in_sequence(&[]));
484
485
        // Small size
486
        assert_eq!(
487
            vec![0x30, 0x04, 0x00, 0x11, 0x22, 0x33],
488
            wrap_in_sequence(&[0x00, 0x11, 0x22, 0x33])
489
        );
490
491
        // Medium size
492
        let mut val = Vec::new();
493
        val.resize(255, 0x12);
494
        assert_eq!(
495
            vec![0x30, 0x81, 0xff, 0x12, 0x12, 0x12],
496
            wrap_in_sequence(&val)[..6]
497
        );
498
499
        // Large size
500
        let mut val = Vec::new();
501
        val.resize(4660, 0x12);
502
        wrap_in_sequence(&val);
503
        assert_eq!(
504
            vec![0x30, 0x82, 0x12, 0x34, 0x12, 0x12],
505
            wrap_in_sequence(&val)[..6]
506
        );
507
508
        // Huge size
509
        let mut val = Vec::new();
510
        val.resize(0xffff, 0x12);
511
        let result = wrap_in_sequence(&val);
512
        assert_eq!(vec![0x30, 0x82, 0xff, 0xff, 0x12, 0x12], result[..6]);
513
        assert_eq!(result.len(), 0xffff + 4);
514
515
        // Gigantic size
516
        let mut val = Vec::new();
517
        val.resize(0x100000, 0x12);
518
        let result = wrap_in_sequence(&val);
519
        assert_eq!(vec![0x30, 0x83, 0x10, 0x00, 0x00, 0x12, 0x12], result[..7]);
520
        assert_eq!(result.len(), 0x100000 + 5);
521
522
        // Ludicrous size
523
        let mut val = Vec::new();
524
        val.resize(0x1000000, 0x12);
525
        let result = wrap_in_sequence(&val);
526
        assert_eq!(
527
            vec![0x30, 0x84, 0x01, 0x00, 0x00, 0x00, 0x12, 0x12],
528
            result[..8]
529
        );
530
        assert_eq!(result.len(), 0x1000000 + 6);
531
    }
532
533
    #[test]
534
    fn test_optional_boolean() {
535
        use super::{Error, FromDer};
536
537
        // Empty input results in false
538
        assert!(!bool::from_der(&mut bytes_reader(&[])).unwrap());
539
540
        // Optional, so another data type results in false
541
        assert!(!bool::from_der(&mut bytes_reader(&[0x05, 0x00])).unwrap());
542
543
        // Only 0x00 and 0xff are accepted values
544
        assert_eq!(
545
            Err(Error::BadDer),
546
            bool::from_der(&mut bytes_reader(&[0x01, 0x01, 0x42]))
547
        );
548
549
        // True
550
        assert!(bool::from_der(&mut bytes_reader(&[0x01, 0x01, 0xff])).unwrap());
551
552
        // False
553
        assert!(!bool::from_der(&mut bytes_reader(&[0x01, 0x01, 0x00])).unwrap());
554
    }
555
556
    #[test]
557
    fn test_bit_string_with_no_unused_bits() {
558
        use super::{Error, bit_string_with_no_unused_bits};
559
560
        // Unexpected type
561
        assert_eq!(
562
            bit_string_with_no_unused_bits(&mut bytes_reader(&[0x01, 0x01, 0xff])).unwrap_err(),
563
            Error::TrailingData(DerTypeId::BitString),
564
        );
565
566
        // Unexpected nonexistent type
567
        assert_eq!(
568
            bit_string_with_no_unused_bits(&mut bytes_reader(&[0x42, 0xff, 0xff])).unwrap_err(),
569
            Error::TrailingData(DerTypeId::BitString),
570
        );
571
572
        // Unexpected empty input
573
        assert_eq!(
574
            bit_string_with_no_unused_bits(&mut bytes_reader(&[])).unwrap_err(),
575
            Error::TrailingData(DerTypeId::BitString),
576
        );
577
578
        // Valid input with non-zero unused bits
579
        assert_eq!(
580
            bit_string_with_no_unused_bits(&mut bytes_reader(&[0x03, 0x03, 0x04, 0x12, 0x34]))
581
                .unwrap_err(),
582
            Error::BadDer,
583
        );
584
585
        // Valid input
586
        assert_eq!(
587
            bit_string_with_no_unused_bits(&mut bytes_reader(&[0x03, 0x03, 0x00, 0x12, 0x34]))
588
                .unwrap()
589
                .as_slice_less_safe(),
590
            &[0x12, 0x34],
591
        );
592
    }
593
594
    fn bytes_reader(bytes: &[u8]) -> untrusted::Reader<'_> {
595
        untrusted::Reader::new(untrusted::Input::from(bytes))
596
    }
597
598
    #[test]
599
    fn read_tag_and_get_value_default_limit() {
600
        use super::{Error, read_tag_and_get_value};
601
602
        let inputs = &[
603
            // DER with short-form length encoded as three bytes.
604
            &[EXAMPLE_TAG, 0x83, 0xFF, 0xFF, 0xFF].as_slice(),
605
            // DER with short-form length encoded as four bytes.
606
            &[EXAMPLE_TAG, 0x84, 0xFF, 0xFF, 0xFF, 0xFF].as_slice(),
607
        ];
608
609
        for input in inputs {
610
            let mut bytes = untrusted::Reader::new(untrusted::Input::from(input));
611
            // read_tag_and_get_value should reject DER with encoded lengths larger than two
612
            // bytes as BadDer.
613
            assert!(matches!(
614
                read_tag_and_get_value(&mut bytes),
615
                Err(Error::BadDer)
616
            ));
617
        }
618
    }
619
620
    #[test]
621
    fn read_tag_and_get_value_limited_high_form() {
622
        use super::{Error, LONG_FORM_LEN_TWO_BYTES_MAX, read_tag_and_get_value_limited};
623
624
        let mut bytes = untrusted::Reader::new(untrusted::Input::from(&[0xFF]));
625
        // read_tag_and_get_value_limited_high_form should reject DER with "high tag number form" tags.
626
        assert!(matches!(
627
            read_tag_and_get_value_limited(&mut bytes, LONG_FORM_LEN_TWO_BYTES_MAX),
628
            Err(Error::BadDer)
629
        ));
630
    }
631
632
    #[test]
633
    fn read_tag_and_get_value_limited_non_canonical() {
634
        use super::{Error, LONG_FORM_LEN_TWO_BYTES_MAX, read_tag_and_get_value_limited};
635
636
        let inputs = &[
637
            // Two byte length, with expressed length < 128.
638
            &[EXAMPLE_TAG, 0x81, 0x01].as_slice(),
639
            // Three byte length, with expressed length < 256.
640
            &[EXAMPLE_TAG, 0x82, 0x00, 0x01].as_slice(),
641
            // Four byte length, with expressed length, < 65536.
642
            &[EXAMPLE_TAG, 0x83, 0x00, 0x00, 0x01].as_slice(),
643
            // Five byte length, with expressed length < 16777216.
644
            &[EXAMPLE_TAG, 0x84, 0x00, 0x00, 0x00, 0x01].as_slice(),
645
        ];
646
647
        for input in inputs {
648
            let mut bytes = untrusted::Reader::new(untrusted::Input::from(input));
649
            // read_tag_and_get_value_limited should reject DER with non-canonical lengths.
650
            assert!(matches!(
651
                read_tag_and_get_value_limited(&mut bytes, LONG_FORM_LEN_TWO_BYTES_MAX),
652
                Err(Error::BadDer)
653
            ));
654
        }
655
    }
656
657
    #[test]
658
    #[cfg(feature = "alloc")]
659
    fn read_tag_and_get_value_limited_limits() {
660
        use super::{Error, read_tag_and_get_value_limited};
661
662
        let short_input = &[0xFF];
663
        let short_input_encoded = &[
664
            &[EXAMPLE_TAG],
665
            der_encode_length(short_input.len()).as_slice(),
666
            short_input,
667
        ]
668
        .concat();
669
670
        let long_input = &[1_u8; 65537];
671
        let long_input_encoded = &[
672
            &[EXAMPLE_TAG],
673
            der_encode_length(long_input.len()).as_slice(),
674
            long_input,
675
        ]
676
        .concat();
677
678
        struct Testcase<'a> {
679
            input: &'a [u8],
680
            limit: usize,
681
            err: Option<Error>,
682
        }
683
684
        let testcases = &[
685
            Testcase {
686
                input: short_input_encoded,
687
                limit: 1,
688
                err: Some(Error::BadDer),
689
            },
690
            Testcase {
691
                input: short_input_encoded,
692
                limit: short_input_encoded.len() + 1,
693
                err: None,
694
            },
695
            Testcase {
696
                input: long_input_encoded,
697
                limit: long_input.len(),
698
                err: Some(Error::BadDer),
699
            },
700
            Testcase {
701
                input: long_input_encoded,
702
                limit: long_input.len() + 1,
703
                err: None,
704
            },
705
        ];
706
707
        for tc in testcases {
708
            let mut bytes = untrusted::Reader::new(untrusted::Input::from(tc.input));
709
710
            let res = read_tag_and_get_value_limited(&mut bytes, tc.limit);
711
            match &tc.err {
712
                None => assert!(res.is_ok()),
713
                Some(e) => {
714
                    let actual = res.unwrap_err();
715
                    assert_eq!(&actual, e)
716
                }
717
            }
718
        }
719
    }
720
721
    #[allow(clippy::as_conversions)] // infallible.
722
    const EXAMPLE_TAG: u8 = super::Tag::Sequence as u8;
723
724
    #[cfg(feature = "alloc")]
725
    #[allow(clippy::as_conversions)] // test code.
726
    fn der_encode_length(length: usize) -> Vec<u8> {
727
        if length < 128 {
728
            vec![length as u8]
729
        } else {
730
            let mut encoded: Vec<u8> = Vec::new();
731
            let mut remaining_length = length;
732
733
            while remaining_length > 0 {
734
                let byte = (remaining_length & 0xFF) as u8;
735
                encoded.insert(0, byte);
736
                remaining_length >>= 8;
737
            }
738
739
            let length_octet = encoded.len() as u8 | 0x80;
740
            encoded.insert(0, length_octet);
741
742
            encoded
743
        }
744
    }
745
746
    #[test]
747
    fn misencoded_bit_string_flags() {
748
        use super::{Error, bit_string_flags};
749
750
        let bad_padding_example = untrusted::Input::from(&[
751
            0x08, // 8 bit of padding (illegal!).
752
            0x06, // 1 byte of bit flags asserting bits 5 and 6.
753
        ]);
754
        assert!(matches!(
755
            bit_string_flags(bad_padding_example),
756
            Err(Error::BadDer)
757
        ));
758
759
        let bad_padding_example = untrusted::Input::from(&[
760
            0x01, // 1 bit of padding.
761
                 // No flags value (illegal with padding!).
762
        ]);
763
        assert!(matches!(
764
            bit_string_flags(bad_padding_example),
765
            Err(Error::BadDer)
766
        ));
767
    }
768
769
    #[test]
770
    fn valid_bit_string_flags() {
771
        use super::bit_string_flags;
772
773
        let example_key_usage = untrusted::Input::from(&[
774
            0x01, // 1 bit of padding.
775
            0x06, // 1 byte of bit flags asserting bits 5 and 6.
776
        ]);
777
        let res = bit_string_flags(example_key_usage).unwrap();
778
779
        assert!(!res.bit_set(0));
780
        assert!(!res.bit_set(1));
781
        assert!(!res.bit_set(2));
782
        assert!(!res.bit_set(3));
783
        assert!(!res.bit_set(4));
784
        // NB: Bits 5 and 6 should be set.
785
        assert!(res.bit_set(5));
786
        assert!(res.bit_set(6));
787
        assert!(!res.bit_set(7));
788
        assert!(!res.bit_set(8));
789
        // Bits outside the range of values shouldn't be considered set.
790
        assert!(!res.bit_set(256));
791
    }
792
793
    #[test]
794
    fn test_small_nonnegative_integer() {
795
        use super::{Error, FromDer, Tag};
796
797
        for value in 0..=127 {
798
            let data = [Tag::Integer.into(), 1, value];
799
            let mut rd = untrusted::Reader::new(untrusted::Input::from(&data));
800
            assert_eq!(u8::from_der(&mut rd), Ok(value),);
801
        }
802
803
        for value in 128..=255 {
804
            let data = [Tag::Integer.into(), 2, 0x00, value];
805
            let mut rd = untrusted::Reader::new(untrusted::Input::from(&data));
806
            assert_eq!(u8::from_der(&mut rd), Ok(value),);
807
        }
808
809
        // not an integer
810
        assert_eq!(
811
            u8::from_der(&mut untrusted::Reader::new(untrusted::Input::from(&[
812
                Tag::Sequence.into(),
813
                1,
814
                1
815
            ]))),
816
            Err(Error::BadDer)
817
        );
818
819
        // negative
820
        assert_eq!(
821
            u8::from_der(&mut untrusted::Reader::new(untrusted::Input::from(&[
822
                Tag::Integer.into(),
823
                1,
824
                0xff
825
            ]))),
826
            Err(Error::BadDer)
827
        );
828
829
        // positive but too large
830
        assert_eq!(
831
            u8::from_der(&mut untrusted::Reader::new(untrusted::Input::from(&[
832
                Tag::Integer.into(),
833
                2,
834
                0x01,
835
                0x00
836
            ]))),
837
            Err(Error::BadDer)
838
        );
839
840
        // unnecessary leading zero
841
        assert_eq!(
842
            u8::from_der(&mut untrusted::Reader::new(untrusted::Input::from(&[
843
                Tag::Integer.into(),
844
                2,
845
                0x00,
846
                0x05
847
            ]))),
848
            Err(Error::BadDer)
849
        );
850
851
        // truncations
852
        assert_eq!(
853
            u8::from_der(&mut untrusted::Reader::new(untrusted::Input::from(&[]))),
854
            Err(Error::BadDer)
855
        );
856
857
        assert_eq!(
858
            u8::from_der(&mut untrusted::Reader::new(untrusted::Input::from(&[
859
                Tag::Integer.into(),
860
            ]))),
861
            Err(Error::BadDer)
862
        );
863
864
        assert_eq!(
865
            u8::from_der(&mut untrusted::Reader::new(untrusted::Input::from(&[
866
                Tag::Integer.into(),
867
                1,
868
            ]))),
869
            Err(Error::BadDer)
870
        );
871
872
        assert_eq!(
873
            u8::from_der(&mut untrusted::Reader::new(untrusted::Input::from(&[
874
                Tag::Integer.into(),
875
                2,
876
                0
877
            ]))),
878
            Err(Error::BadDer)
879
        );
880
    }
881
}