OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/cert/internal/path_builder.h" | 5 #include "net/cert/internal/path_builder.h" |
6 | 6 |
7 #include "base/base_paths.h" | 7 #include "base/base_paths.h" |
8 #include "base/cancelable_callback.h" | 8 #include "base/cancelable_callback.h" |
9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
10 #include "base/location.h" | 10 #include "base/location.h" |
11 #include "base/path_service.h" | 11 #include "base/path_service.h" |
12 #include "base/threading/thread_task_runner_handle.h" | 12 #include "base/threading/thread_task_runner_handle.h" |
13 #include "net/base/net_errors.h" | 13 #include "net/base/net_errors.h" |
14 #include "net/base/test_completion_callback.h" | 14 #include "net/base/test_completion_callback.h" |
15 #include "net/cert/internal/cert_issuer_source_static.h" | 15 #include "net/cert/internal/cert_issuer_source_static.h" |
16 #include "net/cert/internal/parsed_certificate.h" | 16 #include "net/cert/internal/parsed_certificate.h" |
17 #include "net/cert/internal/signature_policy.h" | 17 #include "net/cert/internal/signature_policy.h" |
18 #include "net/cert/internal/test_helpers.h" | 18 #include "net/cert/internal/test_helpers.h" |
19 #include "net/cert/internal/trust_store_in_memory.h" | 19 #include "net/cert/internal/trust_store_in_memory.h" |
| 20 #include "net/cert/internal/trust_store_test_helpers.h" |
20 #include "net/cert/internal/verify_certificate_chain.h" | 21 #include "net/cert/internal/verify_certificate_chain.h" |
21 #include "net/cert/pem_tokenizer.h" | 22 #include "net/cert/pem_tokenizer.h" |
22 #include "net/der/input.h" | 23 #include "net/der/input.h" |
23 #include "net/test/cert_test_util.h" | 24 #include "net/test/cert_test_util.h" |
24 #include "net/test/test_certificate_data.h" | 25 #include "net/test/test_certificate_data.h" |
25 #include "testing/gmock/include/gmock/gmock.h" | 26 #include "testing/gmock/include/gmock/gmock.h" |
26 #include "testing/gtest/include/gtest/gtest.h" | 27 #include "testing/gtest/include/gtest/gtest.h" |
27 | 28 |
28 namespace net { | 29 namespace net { |
29 | 30 |
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
620 DVLOG(1) << "USED OLD"; | 621 DVLOG(1) << "USED OLD"; |
621 EXPECT_EQ(oldintermediate_, path.certs[1]); | 622 EXPECT_EQ(oldintermediate_, path.certs[1]); |
622 EXPECT_EQ(oldroot_, path.trust_anchor); | 623 EXPECT_EQ(oldroot_, path.trust_anchor); |
623 } else { | 624 } else { |
624 DVLOG(1) << "USED NEW"; | 625 DVLOG(1) << "USED NEW"; |
625 EXPECT_EQ(newintermediate_, path.certs[1]); | 626 EXPECT_EQ(newintermediate_, path.certs[1]); |
626 EXPECT_EQ(newroot_, path.trust_anchor->cert()); | 627 EXPECT_EQ(newroot_, path.trust_anchor->cert()); |
627 } | 628 } |
628 } | 629 } |
629 | 630 |
630 class MockTrustStore : public TrustStore { | 631 // If trust anchors are provided both synchronously and asynchronously for the |
631 public: | 632 // same cert, the synchronously provided ones should be tried first, and |
632 MOCK_CONST_METHOD2(FindTrustAnchorsByNormalizedName, | 633 // pathbuilder should finish synchronously. |
633 void(const der::Input& normalized_name, | 634 TEST_F(PathBuilderKeyRolloverTest, TestSyncAnchorsPreferred) { |
634 TrustAnchors* matches)); | 635 TrustStoreInMemoryAsync trust_store; |
635 }; | 636 // Both oldintermediate and newintermediate are trusted, but oldintermediate |
| 637 // is returned synchronously and newintermediate asynchronously. |
| 638 trust_store.AddSyncTrustAnchor( |
| 639 TrustAnchor::CreateFromCertificateNoConstraints(oldintermediate_)); |
| 640 trust_store.AddAsyncTrustAnchor( |
| 641 TrustAnchor::CreateFromCertificateNoConstraints(newintermediate_)); |
| 642 |
| 643 CertPathBuilder::Result result; |
| 644 CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_, |
| 645 &result); |
| 646 |
| 647 EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder)); |
| 648 |
| 649 EXPECT_EQ(OK, result.error()); |
| 650 |
| 651 ASSERT_EQ(1U, result.paths.size()); |
| 652 const auto& path = result.paths[0]->path; |
| 653 EXPECT_EQ(OK, result.paths[0]->error); |
| 654 ASSERT_EQ(1U, path.certs.size()); |
| 655 EXPECT_EQ(target_, path.certs[0]); |
| 656 EXPECT_EQ(oldintermediate_, path.trust_anchor->cert()); |
| 657 } |
| 658 |
| 659 // Async trust anchor checks should be done before synchronous issuer checks are |
| 660 // considered. (Avoiding creating unnecessarily long paths.) |
| 661 // |
| 662 // Two valid paths could be built: |
| 663 // newintermediate <- newrootrollover <- oldroot |
| 664 // newintermediate <- newroot |
| 665 // One invalid path could be built: |
| 666 // newintermediate <- oldroot |
| 667 // |
| 668 // First: newintermediate <- oldroot will be tried, since oldroot is |
| 669 // available synchronously, but this path will not verify. |
| 670 // Second: newintermediate <- newroot should be built, even though |
| 671 // newrootrollover issuer is available synchronously and newroot is async. This |
| 672 // path should verify and pathbuilder will stop. |
| 673 TEST_F(PathBuilderKeyRolloverTest, TestAsyncAnchorsBeforeSyncIssuers) { |
| 674 TrustStoreInMemoryAsync trust_store; |
| 675 trust_store.AddSyncTrustAnchor(oldroot_); |
| 676 trust_store.AddAsyncTrustAnchor( |
| 677 TrustAnchor::CreateFromCertificateNoConstraints(newroot_)); |
| 678 |
| 679 CertIssuerSourceStatic sync_certs; |
| 680 sync_certs.AddCert(newrootrollover_); |
| 681 |
| 682 CertPathBuilder::Result result; |
| 683 CertPathBuilder path_builder(newintermediate_, &trust_store, |
| 684 &signature_policy_, time_, &result); |
| 685 path_builder.AddCertIssuerSource(&sync_certs); |
| 686 |
| 687 EXPECT_EQ(CompletionStatus::ASYNC, RunPathBuilder(&path_builder)); |
| 688 |
| 689 EXPECT_EQ(OK, result.error()); |
| 690 |
| 691 ASSERT_EQ(2U, result.paths.size()); |
| 692 { |
| 693 const auto& path = result.paths[0]->path; |
| 694 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.paths[0]->error); |
| 695 ASSERT_EQ(1U, path.certs.size()); |
| 696 EXPECT_EQ(newintermediate_, path.certs[0]); |
| 697 EXPECT_EQ(oldroot_, path.trust_anchor); |
| 698 } |
| 699 { |
| 700 const auto& path = result.paths[1]->path; |
| 701 EXPECT_EQ(OK, result.paths[1]->error); |
| 702 ASSERT_EQ(1U, path.certs.size()); |
| 703 EXPECT_EQ(newintermediate_, path.certs[0]); |
| 704 EXPECT_EQ(newroot_, path.trust_anchor->cert()); |
| 705 } |
| 706 } |
| 707 |
| 708 // If async trust anchor query returned no results, and there are no issuer |
| 709 // sources, path building should fail at that point. |
| 710 TEST_F(PathBuilderKeyRolloverTest, TestAsyncAnchorsNoMatchAndNoIssuerSources) { |
| 711 TrustStoreInMemoryAsync trust_store; |
| 712 trust_store.AddAsyncTrustAnchor( |
| 713 TrustAnchor::CreateFromCertificateNoConstraints(newroot_)); |
| 714 |
| 715 CertPathBuilder::Result result; |
| 716 CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_, |
| 717 &result); |
| 718 |
| 719 EXPECT_EQ(CompletionStatus::ASYNC, RunPathBuilder(&path_builder)); |
| 720 |
| 721 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.error()); |
| 722 |
| 723 ASSERT_EQ(0U, result.paths.size()); |
| 724 } |
| 725 |
| 726 // Both trust store and issuer source are async. Should successfully build a |
| 727 // path. |
| 728 TEST_F(PathBuilderKeyRolloverTest, TestAsyncAnchorsAndAsyncIssuers) { |
| 729 TrustStoreInMemoryAsync trust_store; |
| 730 trust_store.AddAsyncTrustAnchor( |
| 731 TrustAnchor::CreateFromCertificateNoConstraints(newroot_)); |
| 732 |
| 733 AsyncCertIssuerSourceStatic async_certs; |
| 734 async_certs.AddCert(newintermediate_); |
| 735 |
| 736 CertPathBuilder::Result result; |
| 737 CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_, |
| 738 &result); |
| 739 path_builder.AddCertIssuerSource(&async_certs); |
| 740 |
| 741 EXPECT_EQ(CompletionStatus::ASYNC, RunPathBuilder(&path_builder)); |
| 742 |
| 743 EXPECT_EQ(OK, result.error()); |
| 744 |
| 745 ASSERT_EQ(1U, result.paths.size()); |
| 746 const auto& path = result.paths[0]->path; |
| 747 EXPECT_EQ(OK, result.paths[0]->error); |
| 748 ASSERT_EQ(2U, path.certs.size()); |
| 749 EXPECT_EQ(target_, path.certs[0]); |
| 750 EXPECT_EQ(newintermediate_, path.certs[1]); |
| 751 EXPECT_EQ(newroot_, path.trust_anchor->cert()); |
| 752 } |
636 | 753 |
637 // Tests that multiple trust root matches on a single path will be considered. | 754 // Tests that multiple trust root matches on a single path will be considered. |
638 // Both roots have the same subject but different keys. Only one of them will | 755 // Both roots have the same subject but different keys. Only one of them will |
639 // verify. | 756 // verify. |
640 TEST_F(PathBuilderKeyRolloverTest, TestMultipleRootMatchesOnlyOneWorks) { | 757 TEST_F(PathBuilderKeyRolloverTest, TestMultipleRootMatchesOnlyOneWorks) { |
641 NiceMock<MockTrustStore> trust_store; | 758 TrustStoreInMemoryAsync trust_store; |
642 // Default handler for any other TrustStore requests. | 759 // Since FindTrustAnchorsByNormalizedName returns newroot synchronously, it |
643 EXPECT_CALL(trust_store, FindTrustAnchorsByNormalizedName(_, _)) | 760 // should be tried first. |
644 .WillRepeatedly(Return()); | 761 trust_store.AddSyncTrustAnchor( |
645 // Both newroot and oldroot are trusted, and newroot is returned first in the | 762 TrustAnchor::CreateFromCertificateNoConstraints(newroot_)); |
646 // matches vector. | 763 // oldroot is returned asynchronously, so it should only be tried after the |
647 EXPECT_CALL(trust_store, FindTrustAnchorsByNormalizedName( | 764 // path built with newroot fails. |
648 newroot_->normalized_subject(), _)) | 765 trust_store.AddAsyncTrustAnchor(oldroot_); |
649 .WillRepeatedly(Invoke( | |
650 [this](const der::Input& normalized_name, TrustAnchors* matches) { | |
651 matches->push_back( | |
652 TrustAnchor::CreateFromCertificateNoConstraints(newroot_)); | |
653 matches->push_back(oldroot_); | |
654 })); | |
655 | 766 |
656 // Only oldintermediate is supplied, so the path with newroot should fail, | 767 // Only oldintermediate is supplied, so the path with newroot should fail, |
657 // oldroot should succeed. | 768 // oldroot should succeed. |
658 CertIssuerSourceStatic sync_certs; | 769 CertIssuerSourceStatic sync_certs; |
659 sync_certs.AddCert(oldintermediate_); | 770 sync_certs.AddCert(oldintermediate_); |
660 | 771 |
661 CertPathBuilder::Result result; | 772 CertPathBuilder::Result result; |
662 CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_, | 773 CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_, |
663 &result); | 774 &result); |
664 path_builder.AddCertIssuerSource(&sync_certs); | 775 path_builder.AddCertIssuerSource(&sync_certs); |
665 | 776 |
666 EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder)); | 777 EXPECT_EQ(CompletionStatus::ASYNC, RunPathBuilder(&path_builder)); |
667 | 778 |
668 EXPECT_EQ(OK, result.error()); | 779 EXPECT_EQ(OK, result.error()); |
669 // Since FindTrustAnchorsByNormalizedName returns newroot first, it should be | |
670 // tried first. (Note: this may change if PathBuilder starts prioritizing the | |
671 // path building order.) | |
672 ASSERT_EQ(2U, result.paths.size()); | 780 ASSERT_EQ(2U, result.paths.size()); |
673 | 781 |
674 { | 782 { |
675 // Path builder may first attempt: target <- oldintermediate <- newroot | 783 // Path builder may first attempt: target <- oldintermediate <- newroot |
676 // but it will fail since oldintermediate is signed by oldroot. | 784 // but it will fail since oldintermediate is signed by oldroot. |
677 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.paths[0]->error); | 785 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.paths[0]->error); |
678 const auto& path = result.paths[0]->path; | 786 const auto& path = result.paths[0]->path; |
679 ASSERT_EQ(2U, path.certs.size()); | 787 ASSERT_EQ(2U, path.certs.size()); |
680 EXPECT_EQ(target_, path.certs[0]); | 788 EXPECT_EQ(target_, path.certs[0]); |
681 EXPECT_EQ(oldintermediate_, path.certs[1]); | 789 EXPECT_EQ(oldintermediate_, path.certs[1]); |
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1181 const auto& path1 = result.paths[1]->path; | 1289 const auto& path1 = result.paths[1]->path; |
1182 ASSERT_EQ(2U, path1.certs.size()); | 1290 ASSERT_EQ(2U, path1.certs.size()); |
1183 EXPECT_EQ(target_, path1.certs[0]); | 1291 EXPECT_EQ(target_, path1.certs[0]); |
1184 EXPECT_EQ(newintermediate_, path1.certs[1]); | 1292 EXPECT_EQ(newintermediate_, path1.certs[1]); |
1185 EXPECT_EQ(newroot_, path1.trust_anchor->cert()); | 1293 EXPECT_EQ(newroot_, path1.trust_anchor->cert()); |
1186 } | 1294 } |
1187 | 1295 |
1188 } // namespace | 1296 } // namespace |
1189 | 1297 |
1190 } // namespace net | 1298 } // namespace net |
OLD | NEW |