Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(211)

Side by Side Diff: net/cert/internal/path_builder_unittest.cc

Issue 2266333002: Allow TrustStore queries to be asynchronous. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: typo Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/cert/internal/path_builder.cc ('k') | net/cert/internal/trust_store.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « net/cert/internal/path_builder.cc ('k') | net/cert/internal/trust_store.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698