1use crate::{der, Error};
16use ring::signature;
17
18pub struct SignedData<'a> {
22 data: untrusted::Input<'a>,
27
28 pub(crate) algorithm: untrusted::Input<'a>,
33
34 signature: untrusted::Input<'a>,
38}
39
40pub(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
86pub(crate) fn verify_signed_data(
96 supported_algorithms: &[&SignatureAlgorithm], spki_value: untrusted::Input,
97 signed_data: &SignedData,
98) -> Result<(), Error> {
99 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
170fn 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
185pub struct SignatureAlgorithm {
187 public_key_alg_id: AlgorithmIdentifier,
188 signature_alg_id: AlgorithmIdentifier,
189 verification_alg: &'static dyn signature::VerificationAlgorithm,
190}
191
192pub 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
199pub 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
206pub 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
213pub 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
220pub 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
227pub 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
234pub 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
241pub 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
248pub 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
258pub 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
268pub 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
278pub 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
295const 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 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 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 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 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 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 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 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 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 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 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 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 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 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 &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 &signed_data::ECDSA_P256_SHA384, &signed_data::ECDSA_P384_SHA256, ];
720}