Coverage Report

Created: 2025-12-28 06:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rustls-webpki-0.102.8/src/signed_data.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
use crate::der::{self, FromDer};
16
use crate::error::{DerTypeId, Error};
17
use crate::verify_cert::Budget;
18
19
use pki_types::{AlgorithmIdentifier, SignatureVerificationAlgorithm};
20
21
#[cfg(feature = "alloc")]
22
use alloc::vec::Vec;
23
24
/// X.509 certificates and related items that are signed are almost always
25
/// encoded in the format "tbs||signatureAlgorithm||signature". This structure
26
/// captures this pattern as an owned data type.
27
#[cfg(feature = "alloc")]
28
#[derive(Clone, Debug)]
29
pub(crate) struct OwnedSignedData {
30
    /// The signed data. This would be `tbsCertificate` in the case of an X.509
31
    /// certificate, `tbsResponseData` in the case of an OCSP response, `tbsCertList`
32
    /// in the case of a CRL, and the data nested in the `digitally-signed` construct for
33
    /// TLS 1.2 signed data.
34
    pub(crate) data: Vec<u8>,
35
36
    /// The value of the `AlgorithmIdentifier`. This would be
37
    /// `signatureAlgorithm` in the case of an X.509 certificate, OCSP
38
    /// response or CRL. This would have to be synthesized in the case of TLS 1.2
39
    /// signed data, since TLS does not identify algorithms by ASN.1 OIDs.
40
    pub(crate) algorithm: Vec<u8>,
41
42
    /// The value of the signature. This would be `signature` in an X.509
43
    /// certificate, OCSP response or CRL. This would be the value of
44
    /// `DigitallySigned.signature` for TLS 1.2 signed data.
45
    pub(crate) signature: Vec<u8>,
46
}
47
48
#[cfg(feature = "alloc")]
49
impl OwnedSignedData {
50
    /// Return a borrowed [`SignedData`] from the owned representation.
51
0
    pub(crate) fn borrow(&self) -> SignedData<'_> {
52
0
        SignedData {
53
0
            data: untrusted::Input::from(&self.data),
54
0
            algorithm: untrusted::Input::from(&self.algorithm),
55
0
            signature: untrusted::Input::from(&self.signature),
56
0
        }
57
0
    }
58
}
59
60
/// X.509 certificates and related items that are signed are almost always
61
/// encoded in the format "tbs||signatureAlgorithm||signature". This structure
62
/// captures this pattern.
63
#[derive(Debug)]
64
pub(crate) struct SignedData<'a> {
65
    /// The signed data. This would be `tbsCertificate` in the case of an X.509
66
    /// certificate, `tbsResponseData` in the case of an OCSP response, `tbsCertList`
67
    /// in the case of a CRL, and the data nested in the `digitally-signed` construct for
68
    /// TLS 1.2 signed data.
69
    pub(crate) data: untrusted::Input<'a>,
70
71
    /// The value of the `AlgorithmIdentifier`. This would be
72
    /// `signatureAlgorithm` in the case of an X.509 certificate, OCSP
73
    /// response or CRL. This would have to be synthesized in the case of TLS 1.2
74
    /// signed data, since TLS does not identify algorithms by ASN.1 OIDs.
75
    pub(crate) algorithm: untrusted::Input<'a>,
76
77
    /// The value of the signature. This would be `signature` in an X.509
78
    /// certificate, OCSP response or CRL. This would be the value of
79
    /// `DigitallySigned.signature` for TLS 1.2 signed data.
80
    pub(crate) signature: untrusted::Input<'a>,
81
}
82
83
impl<'a> SignedData<'a> {
84
    /// Parses the concatenation of "tbs||signatureAlgorithm||signature" that
85
    /// is common in the X.509 certificate and OCSP response syntaxes.
86
    ///
87
    /// X.509 Certificates (RFC 5280) look like this:
88
    ///
89
    /// ```ASN.1
90
    /// Certificate (SEQUENCE) {
91
    ///     tbsCertificate TBSCertificate,
92
    ///     signatureAlgorithm AlgorithmIdentifier,
93
    ///     signatureValue BIT STRING
94
    /// }
95
    /// ```
96
    ///
97
    /// OCSP responses (RFC 6960) look like this:
98
    /// ```ASN.1
99
    /// BasicOCSPResponse {
100
    ///     tbsResponseData ResponseData,
101
    ///     signatureAlgorithm AlgorithmIdentifier,
102
    ///     signature BIT STRING,
103
    ///     certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL
104
    /// }
105
    /// ```
106
    ///
107
    /// Note that this function does NOT parse the outermost `SEQUENCE` or the
108
    /// `certs` value.
109
    ///
110
    /// The return value's first component is the contents of
111
    /// `tbsCertificate`/`tbsResponseData`; the second component is a `SignedData`
112
    /// structure that can be passed to `verify_signed_data`.
113
    ///
114
    /// The provided size_limit will enforce the largest possible outermost `SEQUENCE` this
115
    /// function will read.
116
0
    pub(crate) fn from_der(
117
0
        der: &mut untrusted::Reader<'a>,
118
0
        size_limit: usize,
119
0
    ) -> Result<(untrusted::Input<'a>, Self), Error> {
120
0
        let (data, tbs) = der.read_partial(|input| {
121
0
            der::expect_tag_and_get_value_limited(input, der::Tag::Sequence, size_limit)
122
0
        })?;
123
0
        let algorithm = der::expect_tag(der, der::Tag::Sequence)?;
124
0
        let signature = der::bit_string_with_no_unused_bits(der)?;
125
126
0
        Ok((
127
0
            tbs,
128
0
            SignedData {
129
0
                data,
130
0
                algorithm,
131
0
                signature,
132
0
            },
133
0
        ))
134
0
    }
135
136
    /// Convert the borrowed signed data to an [`OwnedSignedData`].
137
    #[cfg(feature = "alloc")]
138
0
    pub(crate) fn to_owned(&self) -> OwnedSignedData {
139
0
        OwnedSignedData {
140
0
            data: self.data.as_slice_less_safe().to_vec(),
141
0
            algorithm: self.algorithm.as_slice_less_safe().to_vec(),
142
0
            signature: self.signature.as_slice_less_safe().to_vec(),
143
0
        }
144
0
    }
145
}
146
147
/// Verify `signed_data` using the public key in the DER-encoded
148
/// SubjectPublicKeyInfo `spki` using one of the algorithms in
149
/// `supported_algorithms`.
150
///
151
/// The algorithm is chosen based on the algorithm information encoded in the
152
/// algorithm identifiers in `public_key` and `signed_data.algorithm`. The
153
/// ordering of the algorithms in `supported_algorithms` does not really matter,
154
/// but generally more common algorithms should go first, as it is scanned
155
/// linearly for matches.
156
0
pub(crate) fn verify_signed_data(
157
0
    supported_algorithms: &[&dyn SignatureVerificationAlgorithm],
158
0
    spki_value: untrusted::Input<'_>,
159
0
    signed_data: &SignedData<'_>,
160
0
    budget: &mut Budget,
161
0
) -> Result<(), Error> {
162
0
    budget.consume_signature()?;
163
164
    // We need to verify the signature in `signed_data` using the public key
165
    // in `public_key`. In order to know which *ring* signature verification
166
    // algorithm to use, we need to know the public key algorithm (ECDSA,
167
    // RSA PKCS#1, etc.), the curve (if applicable), and the digest algorithm.
168
    // `signed_data` identifies only the public key algorithm and the digest
169
    // algorithm, and `public_key` identifies only the public key algorithm and
170
    // the curve (if any). Thus, we have to combine information from both
171
    // inputs to figure out which `ring::signature::VerificationAlgorithm` to
172
    // use to verify the signature.
173
    //
174
    // This is all further complicated by the fact that we don't have any
175
    // implicit knowledge about any algorithms or identifiers, since all of
176
    // that information is encoded in `supported_algorithms.` In particular, we
177
    // avoid hard-coding any of that information so that (link-time) dead code
178
    // elimination will work effectively in eliminating code for unused
179
    // algorithms.
180
181
    // Parse the signature.
182
    //
183
0
    let mut found_signature_alg_match = false;
184
0
    for supported_alg in supported_algorithms
185
0
        .iter()
186
0
        .filter(|alg| alg.signature_alg_id().as_ref() == signed_data.algorithm.as_slice_less_safe())
187
    {
188
0
        match verify_signature(
189
0
            *supported_alg,
190
0
            spki_value,
191
0
            signed_data.data,
192
0
            signed_data.signature,
193
        ) {
194
            Err(Error::UnsupportedSignatureAlgorithmForPublicKey) => {
195
0
                found_signature_alg_match = true;
196
0
                continue;
197
            }
198
0
            result => {
199
0
                return result;
200
            }
201
        }
202
    }
203
204
0
    if found_signature_alg_match {
205
0
        Err(Error::UnsupportedSignatureAlgorithmForPublicKey)
206
    } else {
207
0
        Err(Error::UnsupportedSignatureAlgorithm)
208
    }
209
0
}
210
211
0
pub(crate) fn verify_signature(
212
0
    signature_alg: &dyn SignatureVerificationAlgorithm,
213
0
    spki_value: untrusted::Input<'_>,
214
0
    msg: untrusted::Input<'_>,
215
0
    signature: untrusted::Input<'_>,
216
0
) -> Result<(), Error> {
217
0
    let spki = der::read_all::<SubjectPublicKeyInfo<'_>>(spki_value)?;
218
0
    if signature_alg.public_key_alg_id().as_ref() != spki.algorithm_id_value.as_slice_less_safe() {
219
0
        return Err(Error::UnsupportedSignatureAlgorithmForPublicKey);
220
0
    }
221
222
0
    signature_alg
223
0
        .verify_signature(
224
0
            spki.key_value.as_slice_less_safe(),
225
0
            msg.as_slice_less_safe(),
226
0
            signature.as_slice_less_safe(),
227
        )
228
0
        .map_err(|_| Error::InvalidSignatureForPublicKey)
229
0
}
230
231
pub(crate) struct SubjectPublicKeyInfo<'a> {
232
    algorithm_id_value: untrusted::Input<'a>,
233
    key_value: untrusted::Input<'a>,
234
}
235
236
impl<'a> FromDer<'a> for SubjectPublicKeyInfo<'a> {
237
    // Parse the public key into an algorithm OID, an optional curve OID, and the
238
    // key value. The caller needs to check whether these match the
239
    // `PublicKeyAlgorithm` for the `SignatureVerificationAlgorithm` that is matched when
240
    // parsing the signature.
241
0
    fn from_der(reader: &mut untrusted::Reader<'a>) -> Result<Self, Error> {
242
0
        let algorithm_id_value = der::expect_tag(reader, der::Tag::Sequence)?;
243
0
        let key_value = der::bit_string_with_no_unused_bits(reader)?;
244
0
        Ok(SubjectPublicKeyInfo {
245
0
            algorithm_id_value,
246
0
            key_value,
247
0
        })
248
0
    }
249
250
    const TYPE_ID: DerTypeId = DerTypeId::SubjectPublicKeyInfo;
251
}
252
253
/// Encodings of the PKIX AlgorithmIdentifier type.
254
///
255
/// This module contains a set of common values, and exists to keep the
256
/// names of these separate from the actual algorithm implementations.
257
pub mod alg_id {
258
    use super::AlgorithmIdentifier;
259
260
    // See src/data/README.md.
261
262
    /// AlgorithmIdentifier for `id-ecPublicKey` with named curve `secp256r1`.
263
    pub const ECDSA_P256: AlgorithmIdentifier =
264
        AlgorithmIdentifier::from_slice(include_bytes!("data/alg-ecdsa-p256.der"));
265
266
    /// AlgorithmIdentifier for `id-ecPublicKey` with named curve `secp384r1`.
267
    pub const ECDSA_P384: AlgorithmIdentifier =
268
        AlgorithmIdentifier::from_slice(include_bytes!("data/alg-ecdsa-p384.der"));
269
270
    /// AlgorithmIdentifier for `id-ecPublicKey` with named curve `secp521r1`.
271
    pub const ECDSA_P521: AlgorithmIdentifier =
272
        AlgorithmIdentifier::from_slice(include_bytes!("data/alg-ecdsa-p521.der"));
273
274
    /// AlgorithmIdentifier for `ecdsa-with-SHA256`.
275
    pub const ECDSA_SHA256: AlgorithmIdentifier =
276
        AlgorithmIdentifier::from_slice(include_bytes!("data/alg-ecdsa-sha256.der"));
277
278
    /// AlgorithmIdentifier for `ecdsa-with-SHA384`.
279
    pub const ECDSA_SHA384: AlgorithmIdentifier =
280
        AlgorithmIdentifier::from_slice(include_bytes!("data/alg-ecdsa-sha384.der"));
281
282
    /// AlgorithmIdentifier for `ecdsa-with-SHA512`.
283
    pub const ECDSA_SHA512: AlgorithmIdentifier =
284
        AlgorithmIdentifier::from_slice(include_bytes!("data/alg-ecdsa-sha512.der"));
285
286
    /// AlgorithmIdentifier for `rsaEncryption`.
287
    pub const RSA_ENCRYPTION: AlgorithmIdentifier =
288
        AlgorithmIdentifier::from_slice(include_bytes!("data/alg-rsa-encryption.der"));
289
290
    /// AlgorithmIdentifier for `sha256WithRSAEncryption`.
291
    pub const RSA_PKCS1_SHA256: AlgorithmIdentifier =
292
        AlgorithmIdentifier::from_slice(include_bytes!("data/alg-rsa-pkcs1-sha256.der"));
293
294
    /// AlgorithmIdentifier for `sha384WithRSAEncryption`.
295
    pub const RSA_PKCS1_SHA384: AlgorithmIdentifier =
296
        AlgorithmIdentifier::from_slice(include_bytes!("data/alg-rsa-pkcs1-sha384.der"));
297
298
    /// AlgorithmIdentifier for `sha512WithRSAEncryption`.
299
    pub const RSA_PKCS1_SHA512: AlgorithmIdentifier =
300
        AlgorithmIdentifier::from_slice(include_bytes!("data/alg-rsa-pkcs1-sha512.der"));
301
302
    /// AlgorithmIdentifier for `rsassaPss` with:
303
    ///
304
    /// - hashAlgorithm: sha256
305
    /// - maskGenAlgorithm: mgf1 with sha256
306
    /// - saltLength: 32
307
    pub const RSA_PSS_SHA256: AlgorithmIdentifier =
308
        AlgorithmIdentifier::from_slice(include_bytes!("data/alg-rsa-pss-sha256.der"));
309
310
    /// AlgorithmIdentifier for `rsassaPss` with:
311
    ///
312
    /// - hashAlgorithm: sha384
313
    /// - maskGenAlgorithm: mgf1 with sha384
314
    /// - saltLength: 48
315
    pub const RSA_PSS_SHA384: AlgorithmIdentifier =
316
        AlgorithmIdentifier::from_slice(include_bytes!("data/alg-rsa-pss-sha384.der"));
317
318
    /// AlgorithmIdentifier for `rsassaPss` with:
319
    ///
320
    /// - hashAlgorithm: sha512
321
    /// - maskGenAlgorithm: mgf1 with sha512
322
    /// - saltLength: 64
323
    pub const RSA_PSS_SHA512: AlgorithmIdentifier =
324
        AlgorithmIdentifier::from_slice(include_bytes!("data/alg-rsa-pss-sha512.der"));
325
326
    /// AlgorithmIdentifier for `ED25519`.
327
    pub const ED25519: AlgorithmIdentifier =
328
        AlgorithmIdentifier::from_slice(include_bytes!("data/alg-ed25519.der"));
329
}