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
15use crate::der::{self, FromDer};
16use crate::error::{DerTypeId, Error};
17use crate::verify_cert::Budget;
18
19use pki_types::{AlgorithmIdentifier, SignatureVerificationAlgorithm};
20
21#[cfg(feature = "alloc")]
22use 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)]
29pub(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")]
49impl OwnedSignedData {
50 /// Return a borrowed [`SignedData`] from the owned representation.
51 pub(crate) fn borrow(&self) -> SignedData<'_> {
52 SignedData {
53 data: untrusted::Input::from(&self.data),
54 algorithm: untrusted::Input::from(&self.algorithm),
55 signature: untrusted::Input::from(&self.signature),
56 }
57 }
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)]
64pub(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
83impl<'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 pub(crate) fn from_der(
117 der: &mut untrusted::Reader<'a>,
118 size_limit: usize,
119 ) -> Result<(untrusted::Input<'a>, Self), Error> {
120 let (data, tbs) = der.read_partial(|input| {
121 der::expect_tag_and_get_value_limited(input, der::Tag::Sequence, size_limit)
122 })?;
123 let algorithm = der::expect_tag(der, der::Tag::Sequence)?;
124 let signature = der::bit_string_with_no_unused_bits(der)?;
125
126 Ok((
127 tbs,
128 SignedData {
129 data,
130 algorithm,
131 signature,
132 },
133 ))
134 }
135
136 /// Convert the borrowed signed data to an [`OwnedSignedData`].
137 #[cfg(feature = "alloc")]
138 pub(crate) fn to_owned(&self) -> OwnedSignedData {
139 OwnedSignedData {
140 data: self.data.as_slice_less_safe().to_vec(),
141 algorithm: self.algorithm.as_slice_less_safe().to_vec(),
142 signature: self.signature.as_slice_less_safe().to_vec(),
143 }
144 }
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.
156pub(crate) fn verify_signed_data(
157 supported_algorithms: &[&dyn SignatureVerificationAlgorithm],
158 spki_value: untrusted::Input,
159 signed_data: &SignedData,
160 budget: &mut Budget,
161) -> Result<(), Error> {
162 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 let mut found_signature_alg_match = false;
184 for supported_alg in supported_algorithms
185 .iter()
186 .filter(|alg| alg.signature_alg_id().as_ref() == signed_data.algorithm.as_slice_less_safe())
187 {
188 match verify_signature(
189 *supported_alg,
190 spki_value,
191 signed_data.data,
192 signed_data.signature,
193 ) {
194 Err(Error::UnsupportedSignatureAlgorithmForPublicKey) => {
195 found_signature_alg_match = true;
196 continue;
197 }
198 result => {
199 return result;
200 }
201 }
202 }
203
204 if found_signature_alg_match {
205 Err(Error::UnsupportedSignatureAlgorithmForPublicKey)
206 } else {
207 Err(Error::UnsupportedSignatureAlgorithm)
208 }
209}
210
211pub(crate) fn verify_signature(
212 signature_alg: &dyn SignatureVerificationAlgorithm,
213 spki_value: untrusted::Input,
214 msg: untrusted::Input,
215 signature: untrusted::Input,
216) -> Result<(), Error> {
217 let spki: SubjectPublicKeyInfo<'_> = der::read_all::<SubjectPublicKeyInfo>(input:spki_value)?;
218 if signature_alg.public_key_alg_id().as_ref() != spki.algorithm_id_value.as_slice_less_safe() {
219 return Err(Error::UnsupportedSignatureAlgorithmForPublicKey);
220 }
221
222 signature_alg
223 .verify_signature(
224 spki.key_value.as_slice_less_safe(),
225 msg.as_slice_less_safe(),
226 signature.as_slice_less_safe(),
227 )
228 .map_err(|_| Error::InvalidSignatureForPublicKey)
229}
230
231struct SubjectPublicKeyInfo<'a> {
232 algorithm_id_value: untrusted::Input<'a>,
233 key_value: untrusted::Input<'a>,
234}
235
236impl<'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 fn from_der(reader: &mut untrusted::Reader<'a>) -> Result<Self, Error> {
242 let algorithm_id_value: Input<'_> = der::expect_tag(input:reader, der::Tag::Sequence)?;
243 let key_value: Input<'_> = der::bit_string_with_no_unused_bits(input:reader)?;
244 Ok(SubjectPublicKeyInfo {
245 algorithm_id_value,
246 key_value,
247 })
248 }
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.
257pub 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}
330