Coverage Report

Created: 2025-11-24 06:19

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