webpki/
signed_data.rs

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, Error};
16use ring::signature;
17
18/// X.509 certificates and related items that are signed are almost always
19/// encoded in the format "tbs||signatureAlgorithm||signature". This structure
20/// captures this pattern.
21pub struct SignedData<'a> {
22    /// The signed data. This would be `tbsCertificate` in the case of an X.509
23    /// certificate, `tbsResponseData` in the case of an OCSP response, and the
24    /// data nested in the `digitally-signed` construct for TLS 1.2 signed
25    /// data.
26    data: untrusted::Input<'a>,
27
28    /// The value of the `AlgorithmIdentifier`. This would be
29    /// `signatureAlgorithm` in the case of an X.509 certificate or OCSP
30    /// response. This would have to be synthesized in the case of TLS 1.2
31    /// signed data, since TLS does not identify algorithms by ASN.1 OIDs.
32    pub(crate) algorithm: untrusted::Input<'a>,
33
34    /// The value of the signature. This would be `signature` in an X.509
35    /// certificate or OCSP response. This would be the value of
36    /// `DigitallySigned.signature` for TLS 1.2 signed data.
37    signature: untrusted::Input<'a>,
38}
39
40/// Parses the concatenation of "tbs||signatureAlgorithm||signature" that
41/// is common in the X.509 certificate and OCSP response syntaxes.
42///
43/// X.509 Certificates (RFC 5280) look like this:
44///
45/// ```ASN.1
46/// Certificate (SEQUENCE) {
47///     tbsCertificate TBSCertificate,
48///     signatureAlgorithm AlgorithmIdentifier,
49///     signatureValue BIT STRING
50/// }
51///
52/// OCSP responses (RFC 6960) look like this:
53/// ```ASN.1
54/// BasicOCSPResponse {
55///     tbsResponseData ResponseData,
56///     signatureAlgorithm AlgorithmIdentifier,
57///     signature BIT STRING,
58///     certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL
59/// }
60/// ```
61/// 
62/// Note that this function does NOT parse the outermost `SEQUENCE` or the
63/// `certs` value.
64///
65/// The return value's first component is the contents of
66/// `tbsCertificate`/`tbsResponseData`; the second component is a `SignedData`
67/// structure that can be passed to `verify_signed_data`.
68pub(crate) fn parse_signed_data<'a>(
69    der: &mut untrusted::Reader<'a>,
70) -> Result<(untrusted::Input<'a>, SignedData<'a>), Error> {
71    let (data, tbs) =
72        der.read_partial(|input| der::expect_tag_and_get_value(input, der::Tag::Sequence))?;
73    let algorithm = der::expect_tag_and_get_value(der, der::Tag::Sequence)?;
74    let signature = der::bit_string_with_no_unused_bits(der)?;
75
76    Ok((
77        tbs,
78        SignedData {
79            data,
80            algorithm,
81            signature,
82        },
83    ))
84}
85
86/// Verify `signed_data` using the public key in the DER-encoded
87/// SubjectPublicKeyInfo `spki` using one of the algorithms in
88/// `supported_algorithms`.
89///
90/// The algorithm is chosen based on the algorithm information encoded in the
91/// algorithm identifiers in `public_key` and `signed_data.algorithm`. The
92/// ordering of the algorithms in `supported_algorithms` does not really matter,
93/// but generally more common algorithms should go first, as it is scanned
94/// linearly for matches.
95pub(crate) fn verify_signed_data(
96    supported_algorithms: &[&SignatureAlgorithm], spki_value: untrusted::Input,
97    signed_data: &SignedData,
98) -> Result<(), Error> {
99    // We need to verify the signature in `signed_data` using the public key
100    // in `public_key`. In order to know which *ring* signature verification
101    // algorithm to use, we need to know the public key algorithm (ECDSA,
102    // RSA PKCS#1, etc.), the curve (if applicable), and the digest algorithm.
103    // `signed_data` identifies only the public key algorithm and the digest
104    // algorithm, and `public_key` identifies only the public key algorithm and
105    // the curve (if any). Thus, we have to combine information from both
106    // inputs to figure out which `ring::signature::VerificationAlgorithm` to
107    // use to verify the signature.
108    //
109    // This is all further complicated by the fact that we don't have any
110    // implicit knowledge about any algorithms or identifiers, since all of
111    // that information is encoded in `supported_algorithms.` In particular, we
112    // avoid hard-coding any of that information so that (link-time) dead code
113    // elimination will work effectively in eliminating code for unused
114    // algorithms.
115
116    // Parse the signature.
117    //
118    let mut found_signature_alg_match = false;
119    for supported_alg in supported_algorithms.iter().filter(|alg| {
120        alg.signature_alg_id
121            .matches_algorithm_id_value(signed_data.algorithm)
122    }) {
123        match verify_signature(
124            supported_alg,
125            spki_value,
126            signed_data.data,
127            signed_data.signature,
128        ) {
129            Err(Error::UnsupportedSignatureAlgorithmForPublicKey) => {
130                found_signature_alg_match = true;
131                continue;
132            },
133            result => {
134                return result;
135            },
136        }
137    }
138
139    if found_signature_alg_match {
140        Err(Error::UnsupportedSignatureAlgorithmForPublicKey)
141    } else {
142        Err(Error::UnsupportedSignatureAlgorithm)
143    }
144}
145
146pub(crate) fn verify_signature(
147    signature_alg: &SignatureAlgorithm, spki_value: untrusted::Input, msg: untrusted::Input,
148    signature: untrusted::Input,
149) -> Result<(), Error> {
150    let spki = parse_spki_value(spki_value)?;
151    if !signature_alg
152        .public_key_alg_id
153        .matches_algorithm_id_value(spki.algorithm_id_value)
154    {
155        return Err(Error::UnsupportedSignatureAlgorithmForPublicKey);
156    }
157    signature::UnparsedPublicKey::new(
158        signature_alg.verification_alg,
159        spki.key_value.as_slice_less_safe(),
160    )
161    .verify(msg.as_slice_less_safe(), signature.as_slice_less_safe())
162    .map_err(|_| Error::InvalidSignatureForPublicKey)
163}
164
165struct SubjectPublicKeyInfo<'a> {
166    algorithm_id_value: untrusted::Input<'a>,
167    key_value: untrusted::Input<'a>,
168}
169
170// Parse the public key into an algorithm OID, an optional curve OID, and the
171// key value. The caller needs to check whether these match the
172// `PublicKeyAlgorithm` for the `SignatureAlgorithm` that is matched when
173// parsing the signature.
174fn parse_spki_value(input: untrusted::Input) -> Result<SubjectPublicKeyInfo, Error> {
175    input.read_all(Error::BadDER, |input| {
176        let algorithm_id_value = der::expect_tag_and_get_value(input, der::Tag::Sequence)?;
177        let key_value = der::bit_string_with_no_unused_bits(input)?;
178        Ok(SubjectPublicKeyInfo {
179            algorithm_id_value,
180            key_value,
181        })
182    })
183}
184
185/// A signature algorithm.
186pub struct SignatureAlgorithm {
187    public_key_alg_id: AlgorithmIdentifier,
188    signature_alg_id: AlgorithmIdentifier,
189    verification_alg: &'static dyn signature::VerificationAlgorithm,
190}
191
192/// ECDSA signatures using the P-256 curve and SHA-256.
193pub static ECDSA_P256_SHA256: SignatureAlgorithm = SignatureAlgorithm {
194    public_key_alg_id: ECDSA_P256,
195    signature_alg_id: ECDSA_SHA256,
196    verification_alg: &signature::ECDSA_P256_SHA256_ASN1,
197};
198
199/// ECDSA signatures using the P-256 curve and SHA-384. Deprecated.
200pub static ECDSA_P256_SHA384: SignatureAlgorithm = SignatureAlgorithm {
201    public_key_alg_id: ECDSA_P256,
202    signature_alg_id: ECDSA_SHA384,
203    verification_alg: &signature::ECDSA_P256_SHA384_ASN1,
204};
205
206/// ECDSA signatures using the P-384 curve and SHA-256. Deprecated.
207pub static ECDSA_P384_SHA256: SignatureAlgorithm = SignatureAlgorithm {
208    public_key_alg_id: ECDSA_P384,
209    signature_alg_id: ECDSA_SHA256,
210    verification_alg: &signature::ECDSA_P384_SHA256_ASN1,
211};
212
213/// ECDSA signatures using the P-384 curve and SHA-384.
214pub static ECDSA_P384_SHA384: SignatureAlgorithm = SignatureAlgorithm {
215    public_key_alg_id: ECDSA_P384,
216    signature_alg_id: ECDSA_SHA384,
217    verification_alg: &signature::ECDSA_P384_SHA384_ASN1,
218};
219
220/// RSA PKCS#1 1.5 signatures using SHA-256 for keys of 2048-8192 bits.
221pub static RSA_PKCS1_2048_8192_SHA256: SignatureAlgorithm = SignatureAlgorithm {
222    public_key_alg_id: RSA_ENCRYPTION,
223    signature_alg_id: RSA_PKCS1_SHA256,
224    verification_alg: &signature::RSA_PKCS1_2048_8192_SHA256,
225};
226
227/// RSA PKCS#1 1.5 signatures using SHA-384 for keys of 2048-8192 bits.
228pub static RSA_PKCS1_2048_8192_SHA384: SignatureAlgorithm = SignatureAlgorithm {
229    public_key_alg_id: RSA_ENCRYPTION,
230    signature_alg_id: RSA_PKCS1_SHA384,
231    verification_alg: &signature::RSA_PKCS1_2048_8192_SHA384,
232};
233
234/// RSA PKCS#1 1.5 signatures using SHA-512 for keys of 2048-8192 bits.
235pub static RSA_PKCS1_2048_8192_SHA512: SignatureAlgorithm = SignatureAlgorithm {
236    public_key_alg_id: RSA_ENCRYPTION,
237    signature_alg_id: RSA_PKCS1_SHA512,
238    verification_alg: &signature::RSA_PKCS1_2048_8192_SHA512,
239};
240
241/// RSA PKCS#1 1.5 signatures using SHA-384 for keys of 3072-8192 bits.
242pub static RSA_PKCS1_3072_8192_SHA384: SignatureAlgorithm = SignatureAlgorithm {
243    public_key_alg_id: RSA_ENCRYPTION,
244    signature_alg_id: RSA_PKCS1_SHA384,
245    verification_alg: &signature::RSA_PKCS1_3072_8192_SHA384,
246};
247
248/// RSA PSS signatures using SHA-256 for keys of 2048-8192 bits and of
249/// type rsaEncryption; see [RFC 4055 Section 1.2].
250///
251/// [RFC 4055 Section 1.2]: https://tools.ietf.org/html/rfc4055#section-1.2
252pub static RSA_PSS_2048_8192_SHA256_LEGACY_KEY: SignatureAlgorithm = SignatureAlgorithm {
253    public_key_alg_id: RSA_ENCRYPTION,
254    signature_alg_id: RSA_PSS_SHA256,
255    verification_alg: &signature::RSA_PSS_2048_8192_SHA256,
256};
257
258/// RSA PSS signatures using SHA-384 for keys of 2048-8192 bits and of
259/// type rsaEncryption; see [RFC 4055 Section 1.2].
260///
261/// [RFC 4055 Section 1.2]: https://tools.ietf.org/html/rfc4055#section-1.2
262pub static RSA_PSS_2048_8192_SHA384_LEGACY_KEY: SignatureAlgorithm = SignatureAlgorithm {
263    public_key_alg_id: RSA_ENCRYPTION,
264    signature_alg_id: RSA_PSS_SHA384,
265    verification_alg: &signature::RSA_PSS_2048_8192_SHA384,
266};
267
268/// RSA PSS signatures using SHA-512 for keys of 2048-8192 bits and of
269/// type rsaEncryption; see [RFC 4055 Section 1.2].
270///
271/// [RFC 4055 Section 1.2]: https://tools.ietf.org/html/rfc4055#section-1.2
272pub static RSA_PSS_2048_8192_SHA512_LEGACY_KEY: SignatureAlgorithm = SignatureAlgorithm {
273    public_key_alg_id: RSA_ENCRYPTION,
274    signature_alg_id: RSA_PSS_SHA512,
275    verification_alg: &signature::RSA_PSS_2048_8192_SHA512,
276};
277
278/// ED25519 signatures according to RFC 8410
279pub static ED25519: SignatureAlgorithm = SignatureAlgorithm {
280    public_key_alg_id: ED_25519,
281    signature_alg_id: ED_25519,
282    verification_alg: &signature::ED25519,
283};
284
285struct AlgorithmIdentifier {
286    asn1_id_value: untrusted::Input<'static>,
287}
288
289impl AlgorithmIdentifier {
290    fn matches_algorithm_id_value(&self, encoded: untrusted::Input) -> bool {
291        encoded == self.asn1_id_value
292    }
293}
294
295// See src/data/README.md.
296
297const ECDSA_P256: AlgorithmIdentifier = AlgorithmIdentifier {
298    asn1_id_value: untrusted::Input::from(include_bytes!("data/alg-ecdsa-p256.der")),
299};
300
301const ECDSA_P384: AlgorithmIdentifier = AlgorithmIdentifier {
302    asn1_id_value: untrusted::Input::from(include_bytes!("data/alg-ecdsa-p384.der")),
303};
304
305const ECDSA_SHA256: AlgorithmIdentifier = AlgorithmIdentifier {
306    asn1_id_value: untrusted::Input::from(include_bytes!("data/alg-ecdsa-sha256.der")),
307};
308
309const ECDSA_SHA384: AlgorithmIdentifier = AlgorithmIdentifier {
310    asn1_id_value: untrusted::Input::from(include_bytes!("data/alg-ecdsa-sha384.der")),
311};
312
313const RSA_ENCRYPTION: AlgorithmIdentifier = AlgorithmIdentifier {
314    asn1_id_value: untrusted::Input::from(include_bytes!("data/alg-rsa-encryption.der")),
315};
316
317const RSA_PKCS1_SHA256: AlgorithmIdentifier = AlgorithmIdentifier {
318    asn1_id_value: untrusted::Input::from(include_bytes!("data/alg-rsa-pkcs1-sha256.der")),
319};
320
321const RSA_PKCS1_SHA384: AlgorithmIdentifier = AlgorithmIdentifier {
322    asn1_id_value: untrusted::Input::from(include_bytes!("data/alg-rsa-pkcs1-sha384.der")),
323};
324
325const RSA_PKCS1_SHA512: AlgorithmIdentifier = AlgorithmIdentifier {
326    asn1_id_value: untrusted::Input::from(include_bytes!("data/alg-rsa-pkcs1-sha512.der")),
327};
328
329const RSA_PSS_SHA256: AlgorithmIdentifier = AlgorithmIdentifier {
330    asn1_id_value: untrusted::Input::from(include_bytes!("data/alg-rsa-pss-sha256.der")),
331};
332
333const RSA_PSS_SHA384: AlgorithmIdentifier = AlgorithmIdentifier {
334    asn1_id_value: untrusted::Input::from(include_bytes!("data/alg-rsa-pss-sha384.der")),
335};
336
337const RSA_PSS_SHA512: AlgorithmIdentifier = AlgorithmIdentifier {
338    asn1_id_value: untrusted::Input::from(include_bytes!("data/alg-rsa-pss-sha512.der")),
339};
340
341const ED_25519: AlgorithmIdentifier = AlgorithmIdentifier {
342    asn1_id_value: untrusted::Input::from(include_bytes!("data/alg-ed25519.der")),
343};
344
345#[cfg(test)]
346mod tests {
347    use crate::{der, signed_data, Error};
348    use base64;
349
350    use std::{self, io::BufRead, string::String, vec::Vec};
351
352    // TODO: The expected results need to be modified for SHA-1 deprecation.
353
354    macro_rules! test_verify_signed_data {
355        ($fn_name:ident, $file_name:expr, $expected_result:expr) => {
356            #[test]
357            fn $fn_name() { test_verify_signed_data($file_name, $expected_result); }
358        };
359    }
360
361    fn test_verify_signed_data(file_name: &str, expected_result: Result<(), Error>) {
362        let tsd = parse_test_signed_data(file_name);
363        let spki_value = untrusted::Input::from(&tsd.spki);
364        let spki_value = spki_value
365            .read_all(Error::BadDER, |input| {
366                der::expect_tag_and_get_value(input, der::Tag::Sequence)
367            })
368            .unwrap();
369
370        // we can't use `parse_signed_data` because it requires `data`
371        // to be an ASN.1 SEQUENCE, and that isn't the case with
372        // Chromium's test data. TODO: The test data set should be
373        // expanded with SEQUENCE-wrapped data so that we can actually
374        // test `parse_signed_data`.
375
376        let algorithm = untrusted::Input::from(&tsd.algorithm);
377        let algorithm = algorithm
378            .read_all(Error::BadDER, |input| {
379                der::expect_tag_and_get_value(input, der::Tag::Sequence)
380            })
381            .unwrap();
382
383        let signature = untrusted::Input::from(&tsd.signature);
384        let signature = signature
385            .read_all(Error::BadDER, |input| {
386                der::bit_string_with_no_unused_bits(input)
387            })
388            .unwrap();
389
390        let signed_data = signed_data::SignedData {
391            data: untrusted::Input::from(&tsd.data),
392            algorithm,
393            signature,
394        };
395
396        assert_eq!(
397            expected_result,
398            signed_data::verify_signed_data(
399                SUPPORTED_ALGORITHMS_IN_TESTS,
400                spki_value,
401                &signed_data
402            )
403        );
404    }
405
406    // XXX: This is testing code that isn't even in this module.
407    macro_rules! test_verify_signed_data_signature_outer {
408        ($fn_name:ident, $file_name:expr, $expected_result:expr) => {
409            #[test]
410            fn $fn_name() { test_verify_signed_data_signature_outer($file_name, $expected_result); }
411        };
412    }
413
414    fn test_verify_signed_data_signature_outer(file_name: &str, expected_error: Error) {
415        let tsd = parse_test_signed_data(file_name);
416        let signature = untrusted::Input::from(&tsd.signature);
417        assert_eq!(
418            Err(expected_error),
419            signature.read_all(Error::BadDER, |input| {
420                der::bit_string_with_no_unused_bits(input)
421            })
422        );
423    }
424
425    // XXX: This is testing code that is not even in this module.
426    macro_rules! test_parse_spki_bad_outer {
427        ($fn_name:ident, $file_name:expr, $error:expr) => {
428            #[test]
429            fn $fn_name() { test_parse_spki_bad_outer($file_name, $error) }
430        };
431    }
432
433    fn test_parse_spki_bad_outer(file_name: &str, expected_error: Error) {
434        let tsd = parse_test_signed_data(file_name);
435        let spki = untrusted::Input::from(&tsd.spki);
436        assert_eq!(
437            Err(expected_error),
438            spki.read_all(Error::BadDER, |input| {
439                der::expect_tag_and_get_value(input, der::Tag::Sequence)
440            })
441        );
442    }
443
444    // XXX: Some of the BadDER tests should have better error codes, maybe?
445
446    // XXX: We should have a variant of this test with a SHA-256 digest that gives
447    // `Error::UnsupportedSignatureAlgorithmForPublicKey`.
448    test_verify_signed_data!(
449        test_ecdsa_prime256v1_sha512_spki_params_null,
450        "ecdsa-prime256v1-sha512-spki-params-null.pem",
451        Err(Error::UnsupportedSignatureAlgorithm)
452    );
453    test_verify_signed_data_signature_outer!(
454        test_ecdsa_prime256v1_sha512_unused_bits_signature,
455        "ecdsa-prime256v1-sha512-unused-bits-signature.pem",
456        Error::BadDER
457    );
458    // XXX: We should have a variant of this test with a SHA-256 digest that gives
459    // `Error::UnsupportedSignatureAlgorithmForPublicKey`.
460    test_verify_signed_data!(
461        test_ecdsa_prime256v1_sha512_using_ecdh_key,
462        "ecdsa-prime256v1-sha512-using-ecdh-key.pem",
463        Err(Error::UnsupportedSignatureAlgorithm)
464    );
465    // XXX: We should have a variant of this test with a SHA-256 digest that gives
466    // `Error::UnsupportedSignatureAlgorithmForPublicKey`.
467    test_verify_signed_data!(
468        test_ecdsa_prime256v1_sha512_using_ecmqv_key,
469        "ecdsa-prime256v1-sha512-using-ecmqv-key.pem",
470        Err(Error::UnsupportedSignatureAlgorithm)
471    );
472    test_verify_signed_data!(
473        test_ecdsa_prime256v1_sha512_using_rsa_algorithm,
474        "ecdsa-prime256v1-sha512-using-rsa-algorithm.pem",
475        Err(Error::UnsupportedSignatureAlgorithmForPublicKey)
476    );
477    // XXX: We should have a variant of this test with a SHA-256 digest that gives
478    // `Error::InvalidSignatureForPublicKey`.
479    test_verify_signed_data!(
480        test_ecdsa_prime256v1_sha512_wrong_signature_format,
481        "ecdsa-prime256v1-sha512-wrong-signature-format.pem",
482        Err(Error::UnsupportedSignatureAlgorithm)
483    );
484    // Differs from Chromium because we don't support P-256 with SHA-512.
485    test_verify_signed_data!(
486        test_ecdsa_prime256v1_sha512,
487        "ecdsa-prime256v1-sha512.pem",
488        Err(Error::UnsupportedSignatureAlgorithm)
489    );
490    test_verify_signed_data!(
491        test_ecdsa_secp384r1_sha256_corrupted_data,
492        "ecdsa-secp384r1-sha256-corrupted-data.pem",
493        Err(Error::InvalidSignatureForPublicKey)
494    );
495    test_verify_signed_data!(
496        test_ecdsa_secp384r1_sha256,
497        "ecdsa-secp384r1-sha256.pem",
498        Ok(())
499    );
500    test_verify_signed_data!(
501        test_ecdsa_using_rsa_key,
502        "ecdsa-using-rsa-key.pem",
503        Err(Error::UnsupportedSignatureAlgorithmForPublicKey)
504    );
505
506    test_parse_spki_bad_outer!(
507        test_rsa_pkcs1_sha1_bad_key_der_length,
508        "rsa-pkcs1-sha1-bad-key-der-length.pem",
509        Error::BadDER
510    );
511    test_parse_spki_bad_outer!(
512        test_rsa_pkcs1_sha1_bad_key_der_null,
513        "rsa-pkcs1-sha1-bad-key-der-null.pem",
514        Error::BadDER
515    );
516    test_verify_signed_data!(
517        test_rsa_pkcs1_sha1_key_params_absent,
518        "rsa-pkcs1-sha1-key-params-absent.pem",
519        Err(Error::UnsupportedSignatureAlgorithm)
520    );
521    test_verify_signed_data!(
522        test_rsa_pkcs1_sha1_using_pss_key_no_params,
523        "rsa-pkcs1-sha1-using-pss-key-no-params.pem",
524        Err(Error::UnsupportedSignatureAlgorithm)
525    );
526    test_verify_signed_data!(
527        test_rsa_pkcs1_sha1_wrong_algorithm,
528        "rsa-pkcs1-sha1-wrong-algorithm.pem",
529        Err(Error::InvalidSignatureForPublicKey)
530    );
531    test_verify_signed_data!(
532        test_rsa_pkcs1_sha1,
533        "rsa-pkcs1-sha1.pem",
534        Err(Error::UnsupportedSignatureAlgorithm)
535    );
536    // XXX: RSA PKCS#1 with SHA-1 is a supported algorithm, but we only accept
537    // 2048-8192 bit keys, and this test file is using a 1024 bit key. Thus,
538    // our results differ from Chromium's. TODO: this means we need a 2048+ bit
539    // version of this test.
540    test_verify_signed_data!(
541        test_rsa_pkcs1_sha256,
542        "rsa-pkcs1-sha256.pem",
543        Err(Error::InvalidSignatureForPublicKey)
544    );
545    test_parse_spki_bad_outer!(
546        test_rsa_pkcs1_sha256_key_encoded_ber,
547        "rsa-pkcs1-sha256-key-encoded-ber.pem",
548        Error::BadDER
549    );
550    test_verify_signed_data!(
551        test_rsa_pkcs1_sha256_spki_non_null_params,
552        "rsa-pkcs1-sha256-spki-non-null-params.pem",
553        Err(Error::UnsupportedSignatureAlgorithmForPublicKey)
554    );
555    test_verify_signed_data!(
556        test_rsa_pkcs1_sha256_using_ecdsa_algorithm,
557        "rsa-pkcs1-sha256-using-ecdsa-algorithm.pem",
558        Err(Error::UnsupportedSignatureAlgorithmForPublicKey)
559    );
560    test_verify_signed_data!(
561        test_rsa_pkcs1_sha256_using_id_ea_rsa,
562        "rsa-pkcs1-sha256-using-id-ea-rsa.pem",
563        Err(Error::UnsupportedSignatureAlgorithmForPublicKey)
564    );
565
566    // Chromium's PSS test are for parameter combinations we don't support.
567    test_verify_signed_data!(
568        test_rsa_pss_sha1_salt20_using_pss_key_no_params,
569        "rsa-pss-sha1-salt20-using-pss-key-no-params.pem",
570        Err(Error::UnsupportedSignatureAlgorithm)
571    );
572    test_verify_signed_data!(
573        test_rsa_pss_sha1_salt20_using_pss_key_with_null_params,
574        "rsa-pss-sha1-salt20-using-pss-key-with-null-params.pem",
575        Err(Error::UnsupportedSignatureAlgorithm)
576    );
577    test_verify_signed_data!(
578        test_rsa_pss_sha1_salt20,
579        "rsa-pss-sha1-salt20.pem",
580        Err(Error::UnsupportedSignatureAlgorithm)
581    );
582    test_verify_signed_data!(
583        test_rsa_pss_sha1_wrong_salt,
584        "rsa-pss-sha1-wrong-salt.pem",
585        Err(Error::UnsupportedSignatureAlgorithm)
586    );
587    test_verify_signed_data!(
588        test_rsa_pss_sha256_mgf1_sha512_salt33,
589        "rsa-pss-sha256-mgf1-sha512-salt33.pem",
590        Err(Error::UnsupportedSignatureAlgorithm)
591    );
592    test_verify_signed_data!(
593        test_rsa_pss_sha256_salt10_using_pss_key_with_params,
594        "rsa-pss-sha256-salt10-using-pss-key-with-params.pem",
595        Err(Error::UnsupportedSignatureAlgorithm)
596    );
597    test_verify_signed_data!(
598        test_rsa_pss_sha256_salt10_using_pss_key_with_wrong_params,
599        "rsa-pss-sha256-salt10-using-pss-key-with-wrong-params.pem",
600        Err(Error::UnsupportedSignatureAlgorithm)
601    );
602    test_verify_signed_data!(
603        test_rsa_pss_sha256_salt10,
604        "rsa-pss-sha256-salt10.pem",
605        Err(Error::UnsupportedSignatureAlgorithm)
606    );
607
608    // Our PSS tests that should work.
609    test_verify_signed_data!(
610        test_rsa_pss_sha256_salt32,
611        "ours/rsa-pss-sha256-salt32.pem",
612        Ok(())
613    );
614    test_verify_signed_data!(
615        test_rsa_pss_sha384_salt48,
616        "ours/rsa-pss-sha384-salt48.pem",
617        Ok(())
618    );
619    test_verify_signed_data!(
620        test_rsa_pss_sha512_salt64,
621        "ours/rsa-pss-sha512-salt64.pem",
622        Ok(())
623    );
624    test_verify_signed_data!(
625        test_rsa_pss_sha256_salt32_corrupted_data,
626        "ours/rsa-pss-sha256-salt32-corrupted-data.pem",
627        Err(Error::InvalidSignatureForPublicKey)
628    );
629    test_verify_signed_data!(
630        test_rsa_pss_sha384_salt48_corrupted_data,
631        "ours/rsa-pss-sha384-salt48-corrupted-data.pem",
632        Err(Error::InvalidSignatureForPublicKey)
633    );
634    test_verify_signed_data!(
635        test_rsa_pss_sha512_salt64_corrupted_data,
636        "ours/rsa-pss-sha512-salt64-corrupted-data.pem",
637        Err(Error::InvalidSignatureForPublicKey)
638    );
639
640    test_verify_signed_data!(
641        test_rsa_using_ec_key,
642        "rsa-using-ec-key.pem",
643        Err(Error::UnsupportedSignatureAlgorithmForPublicKey)
644    );
645    test_verify_signed_data!(
646        test_rsa2048_pkcs1_sha512,
647        "rsa2048-pkcs1-sha512.pem",
648        Ok(())
649    );
650
651    struct TestSignedData {
652        spki: Vec<u8>,
653        data: Vec<u8>,
654        algorithm: Vec<u8>,
655        signature: Vec<u8>,
656    }
657
658    fn parse_test_signed_data(file_name: &str) -> TestSignedData {
659        let path = std::path::PathBuf::from("third-party/chromium/data/verify_signed_data")
660            .join(file_name);
661        let file = std::fs::File::open(path).unwrap();
662        let mut lines = std::io::BufReader::new(&file).lines();
663
664        let spki = read_pem_section(&mut lines, "PUBLIC KEY");
665        let algorithm = read_pem_section(&mut lines, "ALGORITHM");
666        let data = read_pem_section(&mut lines, "DATA");
667        let signature = read_pem_section(&mut lines, "SIGNATURE");
668
669        TestSignedData {
670            spki,
671            data,
672            algorithm,
673            signature,
674        }
675    }
676
677    type FileLines<'a> = std::io::Lines<std::io::BufReader<&'a std::fs::File>>;
678
679    fn read_pem_section(lines: &mut FileLines, section_name: &str) -> Vec<u8> {
680        // Skip comments and header
681        let begin_section = format!("-----BEGIN {}-----", section_name);
682        loop {
683            let line = lines.next().unwrap().unwrap();
684            if line == begin_section {
685                break;
686            }
687        }
688
689        let mut base64 = String::new();
690
691        let end_section = format!("-----END {}-----", section_name);
692        loop {
693            let line = lines.next().unwrap().unwrap();
694            if line == end_section {
695                break;
696            }
697            base64.push_str(&line);
698        }
699
700        base64::decode(&base64).unwrap()
701    }
702
703    static SUPPORTED_ALGORITHMS_IN_TESTS: &[&signed_data::SignatureAlgorithm] = &[
704        // Reasonable algorithms.
705        &signed_data::RSA_PKCS1_2048_8192_SHA256,
706        &signed_data::ECDSA_P256_SHA256,
707        &signed_data::ECDSA_P384_SHA384,
708        &signed_data::RSA_PKCS1_2048_8192_SHA384,
709        &signed_data::RSA_PKCS1_2048_8192_SHA512,
710        &signed_data::RSA_PKCS1_3072_8192_SHA384,
711        &signed_data::RSA_PSS_2048_8192_SHA256_LEGACY_KEY,
712        &signed_data::RSA_PSS_2048_8192_SHA384_LEGACY_KEY,
713        &signed_data::RSA_PSS_2048_8192_SHA512_LEGACY_KEY,
714        &signed_data::ED25519,
715        // Algorithms deprecated because they are annoying (P-521) or because
716        // they are nonsensical combinations.
717        &signed_data::ECDSA_P256_SHA384, // Truncates digest.
718        &signed_data::ECDSA_P384_SHA256, // Digest is unnecessarily short.
719    ];
720}