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 | 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)] |
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 | 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. |
156 | pub(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 | |
211 | pub(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 | |
231 | 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 | 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. |
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 | } |
330 | |