/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 | | } |