Coverage Report

Created: 2026-07-25 06:05

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