| Index: net/cert/internal/path_builder_unittest.cc
|
| diff --git a/net/cert/internal/path_builder_unittest.cc b/net/cert/internal/path_builder_unittest.cc
|
| index 24d58e1cc2544bfdc241c5ce0f6098479f146450..fd284db4da0e608f37aa18eeab63af77d85247f5 100644
|
| --- a/net/cert/internal/path_builder_unittest.cc
|
| +++ b/net/cert/internal/path_builder_unittest.cc
|
| @@ -4,21 +4,16 @@
|
|
|
| #include "net/cert/internal/path_builder.h"
|
|
|
| -#include "base/base_paths.h"
|
| -#include "base/cancelable_callback.h"
|
| -#include "base/files/file_util.h"
|
| -#include "base/location.h"
|
| -#include "base/path_service.h"
|
| -#include "base/threading/thread_task_runner_handle.h"
|
| #include "net/base/net_errors.h"
|
| #include "net/base/test_completion_callback.h"
|
| #include "net/cert/internal/cert_issuer_source_static.h"
|
| +#include "net/cert/internal/cert_issuer_source_test_helpers.h"
|
| #include "net/cert/internal/parsed_certificate.h"
|
| #include "net/cert/internal/signature_policy.h"
|
| #include "net/cert/internal/test_helpers.h"
|
| -#include "net/cert/internal/trust_store.h"
|
| +#include "net/cert/internal/trust_store_static.h"
|
| +#include "net/cert/internal/trust_store_test_helpers.h"
|
| #include "net/cert/internal/verify_certificate_chain.h"
|
| -#include "net/cert/pem_tokenizer.h"
|
| #include "net/der/input.h"
|
| #include "net/test/cert_test_util.h"
|
| #include "net/test/test_certificate_data.h"
|
| @@ -36,131 +31,6 @@ using ::testing::StrictMock;
|
| using ::testing::SetArgPointee;
|
| using ::testing::Return;
|
|
|
| -// AsyncCertIssuerSourceStatic always returns its certs asynchronously.
|
| -class AsyncCertIssuerSourceStatic : public CertIssuerSource {
|
| - public:
|
| - class StaticAsyncRequest : public Request {
|
| - public:
|
| - StaticAsyncRequest(const IssuerCallback& issuers_callback,
|
| - ParsedCertificateList&& issuers)
|
| - : cancelable_closure_(base::Bind(&StaticAsyncRequest::RunCallback,
|
| - base::Unretained(this))),
|
| - issuers_callback_(issuers_callback) {
|
| - issuers_.swap(issuers);
|
| - issuers_iter_ = issuers_.begin();
|
| - }
|
| - ~StaticAsyncRequest() override {}
|
| -
|
| - CompletionStatus GetNext(
|
| - scoped_refptr<ParsedCertificate>* out_cert) override {
|
| - if (issuers_iter_ == issuers_.end())
|
| - *out_cert = nullptr;
|
| - else
|
| - *out_cert = std::move(*issuers_iter_++);
|
| - return CompletionStatus::SYNC;
|
| - }
|
| -
|
| - base::Closure callback() { return cancelable_closure_.callback(); }
|
| -
|
| - private:
|
| - void RunCallback() { issuers_callback_.Run(this); }
|
| -
|
| - base::CancelableClosure cancelable_closure_;
|
| - IssuerCallback issuers_callback_;
|
| - ParsedCertificateList issuers_;
|
| - ParsedCertificateList::iterator issuers_iter_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(StaticAsyncRequest);
|
| - };
|
| -
|
| - ~AsyncCertIssuerSourceStatic() override {}
|
| -
|
| - void AddCert(scoped_refptr<ParsedCertificate> cert) {
|
| - static_cert_issuer_source_.AddCert(std::move(cert));
|
| - }
|
| -
|
| - void SyncGetIssuersOf(const ParsedCertificate* cert,
|
| - ParsedCertificateList* issuers) override {}
|
| - void AsyncGetIssuersOf(const ParsedCertificate* cert,
|
| - const IssuerCallback& issuers_callback,
|
| - std::unique_ptr<Request>* out_req) override {
|
| - num_async_gets_++;
|
| - ParsedCertificateList issuers;
|
| - static_cert_issuer_source_.SyncGetIssuersOf(cert, &issuers);
|
| - std::unique_ptr<StaticAsyncRequest> req(
|
| - new StaticAsyncRequest(issuers_callback, std::move(issuers)));
|
| - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, req->callback());
|
| - *out_req = std::move(req);
|
| - }
|
| - int num_async_gets() const { return num_async_gets_; }
|
| -
|
| - private:
|
| - CertIssuerSourceStatic static_cert_issuer_source_;
|
| -
|
| - int num_async_gets_ = 0;
|
| -};
|
| -
|
| -// Reads a data file from the unit-test data.
|
| -std::string ReadTestFileToString(const std::string& file_name) {
|
| - // Compute the full path, relative to the src/ directory.
|
| - base::FilePath src_root;
|
| - PathService::Get(base::DIR_SOURCE_ROOT, &src_root);
|
| - base::FilePath filepath = src_root.AppendASCII(file_name);
|
| -
|
| - // Read the full contents of the file.
|
| - std::string file_data;
|
| - if (!base::ReadFileToString(filepath, &file_data)) {
|
| - ADD_FAILURE() << "Couldn't read file: " << filepath.value();
|
| - return std::string();
|
| - }
|
| -
|
| - return file_data;
|
| -}
|
| -
|
| -// Reads a verify_certificate_chain_unittest-style test case from |file_name|.
|
| -// Test cases are comprised of a certificate chain, trust store, a timestamp to
|
| -// validate at, and the expected result of verification (though the expected
|
| -// result is ignored here).
|
| -void ReadVerifyCertChainTestFromFile(const std::string& file_name,
|
| - std::vector<std::string>* chain,
|
| - scoped_refptr<ParsedCertificate>* root,
|
| - der::GeneralizedTime* time) {
|
| - chain->clear();
|
| -
|
| - std::string file_data = ReadTestFileToString(file_name);
|
| -
|
| - std::vector<std::string> pem_headers;
|
| -
|
| - const char kCertificateHeader[] = "CERTIFICATE";
|
| - const char kTrustedCertificateHeader[] = "TRUSTED_CERTIFICATE";
|
| - const char kTimeHeader[] = "TIME";
|
| -
|
| - pem_headers.push_back(kCertificateHeader);
|
| - pem_headers.push_back(kTrustedCertificateHeader);
|
| - pem_headers.push_back(kTimeHeader);
|
| -
|
| - bool has_time = false;
|
| -
|
| - PEMTokenizer pem_tokenizer(file_data, pem_headers);
|
| - while (pem_tokenizer.GetNext()) {
|
| - const std::string& block_type = pem_tokenizer.block_type();
|
| - const std::string& block_data = pem_tokenizer.data();
|
| -
|
| - if (block_type == kCertificateHeader) {
|
| - chain->push_back(block_data);
|
| - } else if (block_type == kTrustedCertificateHeader) {
|
| - *root = ParsedCertificate::CreateFromCertificateCopy(block_data, {});
|
| - ASSERT_TRUE(*root);
|
| - } else if (block_type == kTimeHeader) {
|
| - ASSERT_FALSE(has_time) << "Duplicate " << kTimeHeader;
|
| - has_time = true;
|
| - ASSERT_TRUE(der::ParseUTCTime(der::Input(&block_data), time));
|
| - }
|
| - }
|
| -
|
| - ASSERT_TRUE(has_time);
|
| -}
|
| -
|
| ::testing::AssertionResult ReadTestPem(const std::string& file_name,
|
| const std::string& block_name,
|
| std::string* result) {
|
| @@ -226,35 +96,37 @@ class PathBuilderMultiRootTest : public ::testing::Test {
|
| // If the target cert is a trust anchor, it should verify and should not include
|
| // anything else in the path.
|
| TEST_F(PathBuilderMultiRootTest, TargetIsTrustAnchor) {
|
| - TrustStore trust_store;
|
| + TrustStoreStatic trust_store;
|
| trust_store.AddTrustedCertificate(a_by_b_);
|
| trust_store.AddTrustedCertificate(b_by_f_);
|
|
|
| CertPathBuilder::Result result;
|
| - CertPathBuilder path_builder(a_by_b_, &trust_store, &signature_policy_, time_,
|
| - &result);
|
| + CertPathBuilder path_builder(a_by_b_, &signature_policy_, time_, &result);
|
| + path_builder.AddTrustStore(&trust_store);
|
|
|
| EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
|
|
|
| EXPECT_EQ(OK, result.error());
|
| - EXPECT_EQ(1U, result.paths[result.best_result_index]->path.size());
|
| + ASSERT_FALSE(result.paths.empty());
|
| + ASSERT_EQ(1U, result.paths[result.best_result_index]->path.size());
|
| EXPECT_EQ(a_by_b_, result.paths[result.best_result_index]->path[0]);
|
| }
|
|
|
| // If the target cert is directly issued by a trust anchor, it should verify
|
| // without any intermediate certs being provided.
|
| TEST_F(PathBuilderMultiRootTest, TargetDirectlySignedByTrustAnchor) {
|
| - TrustStore trust_store;
|
| + TrustStoreStatic trust_store;
|
| trust_store.AddTrustedCertificate(b_by_f_);
|
|
|
| CertPathBuilder::Result result;
|
| - CertPathBuilder path_builder(a_by_b_, &trust_store, &signature_policy_, time_,
|
| - &result);
|
| + CertPathBuilder path_builder(a_by_b_, &signature_policy_, time_, &result);
|
| + path_builder.AddTrustStore(&trust_store);
|
|
|
| EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
|
|
|
| EXPECT_EQ(OK, result.error());
|
| - EXPECT_EQ(2U, result.paths[result.best_result_index]->path.size());
|
| + ASSERT_FALSE(result.paths.empty());
|
| + ASSERT_EQ(2U, result.paths[result.best_result_index]->path.size());
|
| EXPECT_EQ(a_by_b_, result.paths[result.best_result_index]->path[0]);
|
| EXPECT_EQ(b_by_f_, result.paths[result.best_result_index]->path[1]);
|
| }
|
| @@ -262,7 +134,7 @@ TEST_F(PathBuilderMultiRootTest, TargetDirectlySignedByTrustAnchor) {
|
| // Test that async cert queries are not made if the path can be successfully
|
| // built with synchronously available certs.
|
| TEST_F(PathBuilderMultiRootTest, TriesSyncFirst) {
|
| - TrustStore trust_store;
|
| + TrustStoreStatic trust_store;
|
| trust_store.AddTrustedCertificate(e_by_e_);
|
|
|
| CertIssuerSourceStatic sync_certs;
|
| @@ -274,8 +146,8 @@ TEST_F(PathBuilderMultiRootTest, TriesSyncFirst) {
|
| async_certs.AddCert(c_by_e_);
|
|
|
| CertPathBuilder::Result result;
|
| - CertPathBuilder path_builder(a_by_b_, &trust_store, &signature_policy_, time_,
|
| - &result);
|
| + CertPathBuilder path_builder(a_by_b_, &signature_policy_, time_, &result);
|
| + path_builder.AddTrustStore(&trust_store);
|
| path_builder.AddCertIssuerSource(&async_certs);
|
| path_builder.AddCertIssuerSource(&sync_certs);
|
|
|
| @@ -287,7 +159,7 @@ TEST_F(PathBuilderMultiRootTest, TriesSyncFirst) {
|
|
|
| // Test that async cert queries are not made if no callback is provided.
|
| TEST_F(PathBuilderMultiRootTest, SychronousOnlyMode) {
|
| - TrustStore trust_store;
|
| + TrustStoreStatic trust_store;
|
| trust_store.AddTrustedCertificate(e_by_e_);
|
|
|
| CertIssuerSourceStatic sync_certs;
|
| @@ -297,8 +169,8 @@ TEST_F(PathBuilderMultiRootTest, SychronousOnlyMode) {
|
| async_certs.AddCert(b_by_f_);
|
|
|
| CertPathBuilder::Result result;
|
| - CertPathBuilder path_builder(a_by_b_, &trust_store, &signature_policy_, time_,
|
| - &result);
|
| + CertPathBuilder path_builder(a_by_b_, &signature_policy_, time_, &result);
|
| + path_builder.AddTrustStore(&trust_store);
|
| path_builder.AddCertIssuerSource(&async_certs);
|
| path_builder.AddCertIssuerSource(&sync_certs);
|
|
|
| @@ -311,7 +183,7 @@ TEST_F(PathBuilderMultiRootTest, SychronousOnlyMode) {
|
| // If async queries are needed, all async sources will be queried
|
| // simultaneously.
|
| TEST_F(PathBuilderMultiRootTest, TestAsyncSimultaneous) {
|
| - TrustStore trust_store;
|
| + TrustStoreStatic trust_store;
|
| trust_store.AddTrustedCertificate(e_by_e_);
|
|
|
| CertIssuerSourceStatic sync_certs;
|
| @@ -325,8 +197,8 @@ TEST_F(PathBuilderMultiRootTest, TestAsyncSimultaneous) {
|
| async_certs2.AddCert(f_by_e_);
|
|
|
| CertPathBuilder::Result result;
|
| - CertPathBuilder path_builder(a_by_b_, &trust_store, &signature_policy_, time_,
|
| - &result);
|
| + CertPathBuilder path_builder(a_by_b_, &signature_policy_, time_, &result);
|
| + path_builder.AddTrustStore(&trust_store);
|
| path_builder.AddCertIssuerSource(&async_certs1);
|
| path_builder.AddCertIssuerSource(&async_certs2);
|
| path_builder.AddCertIssuerSource(&sync_certs);
|
| @@ -342,7 +214,7 @@ TEST_F(PathBuilderMultiRootTest, TestAsyncSimultaneous) {
|
| // the supplied certs is itself a trust anchor.
|
| TEST_F(PathBuilderMultiRootTest, TestLongChain) {
|
| // Both D(D) and C(D) are trusted roots.
|
| - TrustStore trust_store;
|
| + TrustStoreStatic trust_store;
|
| trust_store.AddTrustedCertificate(d_by_d_);
|
| trust_store.AddTrustedCertificate(c_by_d_);
|
|
|
| @@ -352,8 +224,8 @@ TEST_F(PathBuilderMultiRootTest, TestLongChain) {
|
| sync_certs.AddCert(c_by_d_);
|
|
|
| CertPathBuilder::Result result;
|
| - CertPathBuilder path_builder(a_by_b_, &trust_store, &signature_policy_, time_,
|
| - &result);
|
| + CertPathBuilder path_builder(a_by_b_, &signature_policy_, time_, &result);
|
| + path_builder.AddTrustStore(&trust_store);
|
| path_builder.AddCertIssuerSource(&sync_certs);
|
|
|
| EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
|
| @@ -362,6 +234,36 @@ TEST_F(PathBuilderMultiRootTest, TestLongChain) {
|
|
|
| // The result path should be A(B) <- B(C) <- C(D)
|
| // not the longer but also valid A(B) <- B(C) <- C(D) <- D(D)
|
| + ASSERT_FALSE(result.paths.empty());
|
| + EXPECT_EQ(3U, result.paths[result.best_result_index]->path.size());
|
| +}
|
| +
|
| +// Test that PathBuilder does not generate longer paths than necessary if one of
|
| +// the supplied certs is itself a trust anchor.
|
| +TEST_F(PathBuilderMultiRootTest, TestLongChainAsyncTrust) {
|
| + // Both D(D) and C(D) are trusted roots.
|
| + AsyncTrustStoreStatic trust_store;
|
| + trust_store.AddTrustedCertificate(d_by_d_);
|
| + trust_store.AddTrustedCertificate(c_by_d_);
|
| +
|
| + // Certs A(B), B(C), and C(D) are all supplied.
|
| + CertIssuerSourceStatic sync_certs;
|
| + sync_certs.AddCert(a_by_b_);
|
| + sync_certs.AddCert(b_by_c_);
|
| + sync_certs.AddCert(c_by_d_);
|
| +
|
| + CertPathBuilder::Result result;
|
| + CertPathBuilder path_builder(a_by_b_, &signature_policy_, time_, &result);
|
| + path_builder.AddTrustStore(&trust_store);
|
| + path_builder.AddCertIssuerSource(&sync_certs);
|
| +
|
| + EXPECT_EQ(CompletionStatus::ASYNC, RunPathBuilder(&path_builder));
|
| +
|
| + EXPECT_EQ(OK, result.error());
|
| +
|
| + // The result path should be A(B) <- B(C) <- C(D)
|
| + // not the longer but also valid A(B) <- B(C) <- C(D) <- D(D)
|
| + ASSERT_FALSE(result.paths.empty());
|
| EXPECT_EQ(3U, result.paths[result.best_result_index]->path.size());
|
| }
|
|
|
| @@ -369,7 +271,7 @@ TEST_F(PathBuilderMultiRootTest, TestLongChain) {
|
| // one doesn't work out.
|
| TEST_F(PathBuilderMultiRootTest, TestBacktracking) {
|
| // Only D(D) is a trusted root.
|
| - TrustStore trust_store;
|
| + TrustStoreStatic trust_store;
|
| trust_store.AddTrustedCertificate(d_by_d_);
|
|
|
| // Certs B(F) and F(E) are supplied synchronously, thus the path
|
| @@ -385,8 +287,8 @@ TEST_F(PathBuilderMultiRootTest, TestBacktracking) {
|
| async_certs.AddCert(c_by_d_);
|
|
|
| CertPathBuilder::Result result;
|
| - CertPathBuilder path_builder(a_by_b_, &trust_store, &signature_policy_, time_,
|
| - &result);
|
| + CertPathBuilder path_builder(a_by_b_, &signature_policy_, time_, &result);
|
| + path_builder.AddTrustStore(&trust_store);
|
| path_builder.AddCertIssuerSource(&sync_certs);
|
| path_builder.AddCertIssuerSource(&async_certs);
|
|
|
| @@ -395,6 +297,7 @@ TEST_F(PathBuilderMultiRootTest, TestBacktracking) {
|
| EXPECT_EQ(OK, result.error());
|
|
|
| // The result path should be A(B) <- B(C) <- C(D) <- D(D)
|
| + ASSERT_FALSE(result.paths.empty());
|
| ASSERT_EQ(4U, result.paths[result.best_result_index]->path.size());
|
| EXPECT_EQ(a_by_b_, result.paths[result.best_result_index]->path[0]);
|
| EXPECT_EQ(b_by_c_, result.paths[result.best_result_index]->path[1]);
|
| @@ -406,7 +309,7 @@ TEST_F(PathBuilderMultiRootTest, TestBacktracking) {
|
| // building still succeeds.
|
| TEST_F(PathBuilderMultiRootTest, TestCertIssuerOrdering) {
|
| // Only D(D) is a trusted root.
|
| - TrustStore trust_store;
|
| + TrustStoreStatic trust_store;
|
| trust_store.AddTrustedCertificate(d_by_d_);
|
|
|
| for (bool reverse_order : {false, true}) {
|
| @@ -423,8 +326,8 @@ TEST_F(PathBuilderMultiRootTest, TestCertIssuerOrdering) {
|
| }
|
|
|
| CertPathBuilder::Result result;
|
| - CertPathBuilder path_builder(a_by_b_, &trust_store, &signature_policy_,
|
| - time_, &result);
|
| + CertPathBuilder path_builder(a_by_b_, &signature_policy_, time_, &result);
|
| + path_builder.AddTrustStore(&trust_store);
|
| path_builder.AddCertIssuerSource(&sync_certs);
|
|
|
| EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
|
| @@ -445,28 +348,30 @@ class PathBuilderKeyRolloverTest : public ::testing::Test {
|
| PathBuilderKeyRolloverTest() : signature_policy_(1024) {}
|
|
|
| void SetUp() override {
|
| - std::vector<std::string> path;
|
| + ParsedCertificateList chain;
|
| + ParsedCertificateList roots;
|
| + bool unused_verify_result;
|
|
|
| - ReadVerifyCertChainTestFromFile(
|
| + ReadCertChainTestFromFile(
|
| "net/data/verify_certificate_chain_unittest/key-rollover-oldchain.pem",
|
| - &path, &oldroot_, &time_);
|
| - ASSERT_EQ(2U, path.size());
|
| - target_ = ParsedCertificate::CreateFromCertificateCopy(path[0], {});
|
| - oldintermediate_ =
|
| - ParsedCertificate::CreateFromCertificateCopy(path[1], {});
|
| + &chain, &roots, &time_, &unused_verify_result);
|
| + ASSERT_EQ(2U, chain.size());
|
| + ASSERT_EQ(1U, roots.size());
|
| + target_ = chain[0];
|
| + oldintermediate_ = chain[1];
|
| + oldroot_ = roots[0];
|
| ASSERT_TRUE(target_);
|
| ASSERT_TRUE(oldintermediate_);
|
| + ASSERT_TRUE(oldroot_);
|
|
|
| - ReadVerifyCertChainTestFromFile(
|
| + ReadCertChainTestFromFile(
|
| "net/data/verify_certificate_chain_unittest/"
|
| "key-rollover-longrolloverchain.pem",
|
| - &path, &oldroot_, &time_);
|
| - ASSERT_EQ(4U, path.size());
|
| - newintermediate_ =
|
| - ParsedCertificate::CreateFromCertificateCopy(path[1], {});
|
| - newroot_ = ParsedCertificate::CreateFromCertificateCopy(path[2], {});
|
| - newrootrollover_ =
|
| - ParsedCertificate::CreateFromCertificateCopy(path[3], {});
|
| + &chain, &roots, &time_, &unused_verify_result);
|
| + ASSERT_EQ(4U, chain.size());
|
| + newintermediate_ = chain[1];
|
| + newroot_ = chain[2];
|
| + newrootrollover_ = chain[3];
|
| ASSERT_TRUE(newintermediate_);
|
| ASSERT_TRUE(newroot_);
|
| ASSERT_TRUE(newrootrollover_);
|
| @@ -497,7 +402,7 @@ class PathBuilderKeyRolloverTest : public ::testing::Test {
|
| // path through the new intermediate and rollover cert to the old root.
|
| TEST_F(PathBuilderKeyRolloverTest, TestRolloverOnlyOldRootTrusted) {
|
| // Only oldroot is trusted.
|
| - TrustStore trust_store;
|
| + TrustStoreStatic trust_store;
|
| trust_store.AddTrustedCertificate(oldroot_);
|
|
|
| // Old intermediate cert is not provided, so the pathbuilder will need to go
|
| @@ -507,8 +412,8 @@ TEST_F(PathBuilderKeyRolloverTest, TestRolloverOnlyOldRootTrusted) {
|
| sync_certs.AddCert(newrootrollover_);
|
|
|
| CertPathBuilder::Result result;
|
| - CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_,
|
| - &result);
|
| + CertPathBuilder path_builder(target_, &signature_policy_, time_, &result);
|
| + path_builder.AddTrustStore(&trust_store);
|
| path_builder.AddCertIssuerSource(&sync_certs);
|
|
|
| EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
|
| @@ -542,7 +447,7 @@ TEST_F(PathBuilderKeyRolloverTest, TestRolloverOnlyOldRootTrusted) {
|
| // always builds the path through the new intermediate and new root.
|
| TEST_F(PathBuilderKeyRolloverTest, TestRolloverBothRootsTrusted) {
|
| // Both oldroot and newroot are trusted.
|
| - TrustStore trust_store;
|
| + TrustStoreStatic trust_store;
|
| trust_store.AddTrustedCertificate(oldroot_);
|
| trust_store.AddTrustedCertificate(newroot_);
|
|
|
| @@ -553,8 +458,8 @@ TEST_F(PathBuilderKeyRolloverTest, TestRolloverBothRootsTrusted) {
|
| sync_certs.AddCert(newrootrollover_);
|
|
|
| CertPathBuilder::Result result;
|
| - CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_,
|
| - &result);
|
| + CertPathBuilder path_builder(target_, &signature_policy_, time_, &result);
|
| + path_builder.AddTrustStore(&trust_store);
|
| path_builder.AddCertIssuerSource(&sync_certs);
|
|
|
| EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
|
| @@ -585,7 +490,7 @@ TEST_F(PathBuilderKeyRolloverTest, TestRolloverBothRootsTrusted) {
|
| // verify.
|
| TEST_F(PathBuilderKeyRolloverTest, TestMultipleRootMatchesOnlyOneWorks) {
|
| // Both newroot and oldroot are trusted.
|
| - TrustStore trust_store;
|
| + TrustStoreStatic trust_store;
|
| trust_store.AddTrustedCertificate(newroot_);
|
| trust_store.AddTrustedCertificate(oldroot_);
|
|
|
| @@ -595,8 +500,8 @@ TEST_F(PathBuilderKeyRolloverTest, TestMultipleRootMatchesOnlyOneWorks) {
|
| sync_certs.AddCert(oldintermediate_);
|
|
|
| CertPathBuilder::Result result;
|
| - CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_,
|
| - &result);
|
| + CertPathBuilder path_builder(target_, &signature_policy_, time_, &result);
|
| + path_builder.AddTrustStore(&trust_store);
|
| path_builder.AddCertIssuerSource(&sync_certs);
|
|
|
| EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
|
| @@ -632,7 +537,7 @@ TEST_F(PathBuilderKeyRolloverTest, TestMultipleRootMatchesOnlyOneWorks) {
|
| // Tests that the path builder doesn't build longer than necessary paths.
|
| TEST_F(PathBuilderKeyRolloverTest, TestRolloverLongChain) {
|
| // Only oldroot is trusted.
|
| - TrustStore trust_store;
|
| + TrustStoreStatic trust_store;
|
| trust_store.AddTrustedCertificate(oldroot_);
|
|
|
| // New intermediate and new root are provided synchronously.
|
| @@ -646,8 +551,8 @@ TEST_F(PathBuilderKeyRolloverTest, TestRolloverLongChain) {
|
| async_certs.AddCert(newrootrollover_);
|
|
|
| CertPathBuilder::Result result;
|
| - CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_,
|
| - &result);
|
| + CertPathBuilder path_builder(target_, &signature_policy_, time_, &result);
|
| + path_builder.AddTrustStore(&trust_store);
|
| path_builder.AddCertIssuerSource(&sync_certs);
|
| path_builder.AddCertIssuerSource(&async_certs);
|
|
|
| @@ -692,13 +597,14 @@ TEST_F(PathBuilderKeyRolloverTest, TestRolloverLongChain) {
|
| // If the target cert is a trust root, that alone is a valid path.
|
| TEST_F(PathBuilderKeyRolloverTest, TestEndEntityIsTrustRoot) {
|
| // Trust newintermediate.
|
| - TrustStore trust_store;
|
| + TrustStoreStatic trust_store;
|
| trust_store.AddTrustedCertificate(newintermediate_);
|
|
|
| CertPathBuilder::Result result;
|
| // Newintermediate is also the target cert.
|
| - CertPathBuilder path_builder(newintermediate_, &trust_store,
|
| - &signature_policy_, time_, &result);
|
| + CertPathBuilder path_builder(newintermediate_, &signature_policy_, time_,
|
| + &result);
|
| + path_builder.AddTrustStore(&trust_store);
|
|
|
| EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
|
|
|
| @@ -710,6 +616,33 @@ TEST_F(PathBuilderKeyRolloverTest, TestEndEntityIsTrustRoot) {
|
| EXPECT_EQ(newintermediate_, result.paths[0]->path[0]);
|
| }
|
|
|
| +// If the target cert is a trust root, but fails verification for some other
|
| +// reason (eg, bad validity time), path building should fail and no other paths
|
| +// should be attempted.
|
| +TEST_F(PathBuilderKeyRolloverTest, TestEndEntityIsTrustRootButFailsVerification) {
|
| + // Trust newintermediate and newroot.
|
| + TrustStoreStatic trust_store;
|
| + trust_store.AddTrustedCertificate(newintermediate_);
|
| + trust_store.AddTrustedCertificate(newroot_);
|
| +
|
| + CertPathBuilder::Result result;
|
| + // Newintermediate is also the target cert.
|
| +
|
| + der::GeneralizedTime badtime = {2010, 4, 11, 0, 0, 0};
|
| + CertPathBuilder path_builder(newintermediate_, &signature_policy_, badtime,
|
| + &result);
|
| + path_builder.AddTrustStore(&trust_store);
|
| +
|
| + EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
|
| +
|
| + EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.error());
|
| +
|
| + ASSERT_EQ(1U, result.paths.size());
|
| + EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.paths[0]->error);
|
| + ASSERT_EQ(1U, result.paths[0]->path.size());
|
| + EXPECT_EQ(newintermediate_, result.paths[0]->path[0]);
|
| +}
|
| +
|
| // If target has same Name+SAN+SPKI as a necessary intermediate, test if a path
|
| // can still be built.
|
| // Since LoopChecker will prevent the intermediate from being included, this
|
| @@ -717,7 +650,7 @@ TEST_F(PathBuilderKeyRolloverTest, TestEndEntityIsTrustRoot) {
|
| TEST_F(PathBuilderKeyRolloverTest,
|
| TestEndEntityHasSameNameAndSpkiAsIntermediate) {
|
| // Trust oldroot.
|
| - TrustStore trust_store;
|
| + TrustStoreStatic trust_store;
|
| trust_store.AddTrustedCertificate(oldroot_);
|
|
|
| // New root rollover is provided synchronously.
|
| @@ -726,8 +659,8 @@ TEST_F(PathBuilderKeyRolloverTest,
|
|
|
| CertPathBuilder::Result result;
|
| // Newroot is the target cert.
|
| - CertPathBuilder path_builder(newroot_, &trust_store, &signature_policy_,
|
| - time_, &result);
|
| + CertPathBuilder path_builder(newroot_, &signature_policy_, time_, &result);
|
| + path_builder.AddTrustStore(&trust_store);
|
| path_builder.AddCertIssuerSource(&sync_certs);
|
|
|
| EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
|
| @@ -742,13 +675,13 @@ TEST_F(PathBuilderKeyRolloverTest,
|
| TEST_F(PathBuilderKeyRolloverTest,
|
| TestEndEntityHasSameNameAndSpkiAsTrustAnchor) {
|
| // Trust newrootrollover.
|
| - TrustStore trust_store;
|
| + TrustStoreStatic trust_store;
|
| trust_store.AddTrustedCertificate(newrootrollover_);
|
|
|
| CertPathBuilder::Result result;
|
| // Newroot is the target cert.
|
| - CertPathBuilder path_builder(newroot_, &trust_store, &signature_policy_,
|
| - time_, &result);
|
| + CertPathBuilder path_builder(newroot_, &signature_policy_, time_, &result);
|
| + path_builder.AddTrustStore(&trust_store);
|
|
|
| EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
|
|
|
| @@ -774,7 +707,7 @@ TEST_F(PathBuilderKeyRolloverTest, TestDuplicateIntermediates) {
|
| oldintermediate_->der_cert().AsStringPiece(), {}));
|
|
|
| // Only newroot is a trusted root.
|
| - TrustStore trust_store;
|
| + TrustStoreStatic trust_store;
|
| trust_store.AddTrustedCertificate(newroot_);
|
|
|
| // The oldintermediate is supplied synchronously by |sync_certs1| and
|
| @@ -793,8 +726,8 @@ TEST_F(PathBuilderKeyRolloverTest, TestDuplicateIntermediates) {
|
| async_certs.AddCert(newintermediate_);
|
|
|
| CertPathBuilder::Result result;
|
| - CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_,
|
| - &result);
|
| + CertPathBuilder path_builder(target_, &signature_policy_, time_, &result);
|
| + path_builder.AddTrustStore(&trust_store);
|
| path_builder.AddCertIssuerSource(&sync_certs1);
|
| path_builder.AddCertIssuerSource(&sync_certs2);
|
| path_builder.AddCertIssuerSource(&async_certs);
|
| @@ -833,7 +766,7 @@ TEST_F(PathBuilderKeyRolloverTest, TestDuplicateIntermediateAndRoot) {
|
| newroot_->der_cert().AsStringPiece(), {}));
|
|
|
| // Only newroot is a trusted root.
|
| - TrustStore trust_store;
|
| + TrustStoreStatic trust_store;
|
| trust_store.AddTrustedCertificate(newroot_);
|
|
|
| // The oldintermediate and newroot are supplied synchronously by |sync_certs|.
|
| @@ -842,8 +775,8 @@ TEST_F(PathBuilderKeyRolloverTest, TestDuplicateIntermediateAndRoot) {
|
| sync_certs.AddCert(newroot_dupe);
|
|
|
| CertPathBuilder::Result result;
|
| - CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_,
|
| - &result);
|
| + CertPathBuilder path_builder(target_, &signature_policy_, time_, &result);
|
| + path_builder.AddTrustStore(&trust_store);
|
| path_builder.AddCertIssuerSource(&sync_certs);
|
|
|
| EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
|
| @@ -862,38 +795,6 @@ TEST_F(PathBuilderKeyRolloverTest, TestDuplicateIntermediateAndRoot) {
|
| EXPECT_EQ(newroot_->der_cert(), result.paths[0]->path[2]->der_cert());
|
| }
|
|
|
| -class MockCertIssuerSourceRequest : public CertIssuerSource::Request {
|
| - public:
|
| - MOCK_METHOD1(GetNext, CompletionStatus(scoped_refptr<ParsedCertificate>*));
|
| -};
|
| -
|
| -class MockCertIssuerSource : public CertIssuerSource {
|
| - public:
|
| - MOCK_METHOD2(SyncGetIssuersOf,
|
| - void(const ParsedCertificate*, ParsedCertificateList*));
|
| - MOCK_METHOD3(AsyncGetIssuersOf,
|
| - void(const ParsedCertificate*,
|
| - const IssuerCallback&,
|
| - std::unique_ptr<Request>*));
|
| -};
|
| -
|
| -// Helper class to pass the Request to the PathBuilder when it calls
|
| -// AsyncGetIssuersOf. (GoogleMock has a ByMove helper, but it apparently can
|
| -// only be used with Return, not SetArgPointee.)
|
| -class CertIssuerSourceRequestMover {
|
| - public:
|
| - CertIssuerSourceRequestMover(std::unique_ptr<CertIssuerSource::Request> req)
|
| - : request_(std::move(req)) {}
|
| - void MoveIt(const ParsedCertificate* cert,
|
| - const CertIssuerSource::IssuerCallback& issuers_callback,
|
| - std::unique_ptr<CertIssuerSource::Request>* out_req) {
|
| - *out_req = std::move(request_);
|
| - }
|
| -
|
| - private:
|
| - std::unique_ptr<CertIssuerSource::Request> request_;
|
| -};
|
| -
|
| // Test that a single CertIssuerSource returning multiple async batches of
|
| // issuers is handled correctly. Due to the StrictMocks, it also tests that path
|
| // builder does not request issuers of certs that it shouldn't.
|
| @@ -901,12 +802,12 @@ TEST_F(PathBuilderKeyRolloverTest, TestMultipleAsyncCallbacksFromSingleSource) {
|
| StrictMock<MockCertIssuerSource> cert_issuer_source;
|
|
|
| // Only newroot is a trusted root.
|
| - TrustStore trust_store;
|
| + TrustStoreStatic trust_store;
|
| trust_store.AddTrustedCertificate(newroot_);
|
|
|
| CertPathBuilder::Result result;
|
| - CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_,
|
| - &result);
|
| + CertPathBuilder path_builder(target_, &signature_policy_, time_, &result);
|
| + path_builder.AddTrustStore(&trust_store);
|
| path_builder.AddCertIssuerSource(&cert_issuer_source);
|
|
|
| CertIssuerSource::IssuerCallback target_issuers_callback;
|
| @@ -922,7 +823,7 @@ TEST_F(PathBuilderKeyRolloverTest, TestMultipleAsyncCallbacksFromSingleSource) {
|
| {
|
| ::testing::InSequence s;
|
| EXPECT_CALL(cert_issuer_source, SyncGetIssuersOf(target_.get(), _));
|
| - EXPECT_CALL(cert_issuer_source, AsyncGetIssuersOf(target_.get(), _, _))
|
| + EXPECT_CALL(cert_issuer_source, AsyncGetIssuersOf(target_, _, _))
|
| .WillOnce(
|
| DoAll(SaveArg<1>(&target_issuers_callback),
|
| Invoke(&req_mover, &CertIssuerSourceRequestMover::MoveIt)));
|
| @@ -948,8 +849,7 @@ TEST_F(PathBuilderKeyRolloverTest, TestMultipleAsyncCallbacksFromSingleSource) {
|
| // lookups are expected.
|
| EXPECT_CALL(cert_issuer_source,
|
| SyncGetIssuersOf(oldintermediate_.get(), _));
|
| - EXPECT_CALL(cert_issuer_source,
|
| - AsyncGetIssuersOf(oldintermediate_.get(), _, _));
|
| + EXPECT_CALL(cert_issuer_source, AsyncGetIssuersOf(oldintermediate_, _, _));
|
| }
|
| target_issuers_callback.Run(target_issuers_req);
|
| ::testing::Mock::VerifyAndClearExpectations(target_issuers_req);
|
| @@ -999,12 +899,12 @@ TEST_F(PathBuilderKeyRolloverTest, TestDuplicateAsyncIntermediates) {
|
| StrictMock<MockCertIssuerSource> cert_issuer_source;
|
|
|
| // Only newroot is a trusted root.
|
| - TrustStore trust_store;
|
| + TrustStoreStatic trust_store;
|
| trust_store.AddTrustedCertificate(newroot_);
|
|
|
| CertPathBuilder::Result result;
|
| - CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_,
|
| - &result);
|
| + CertPathBuilder path_builder(target_, &signature_policy_, time_, &result);
|
| + path_builder.AddTrustStore(&trust_store);
|
| path_builder.AddCertIssuerSource(&cert_issuer_source);
|
|
|
| CertIssuerSource::IssuerCallback target_issuers_callback;
|
| @@ -1020,7 +920,7 @@ TEST_F(PathBuilderKeyRolloverTest, TestDuplicateAsyncIntermediates) {
|
| {
|
| ::testing::InSequence s;
|
| EXPECT_CALL(cert_issuer_source, SyncGetIssuersOf(target_.get(), _));
|
| - EXPECT_CALL(cert_issuer_source, AsyncGetIssuersOf(target_.get(), _, _))
|
| + EXPECT_CALL(cert_issuer_source, AsyncGetIssuersOf(target_, _, _))
|
| .WillOnce(
|
| DoAll(SaveArg<1>(&target_issuers_callback),
|
| Invoke(&req_mover, &CertIssuerSourceRequestMover::MoveIt)));
|
| @@ -1046,8 +946,7 @@ TEST_F(PathBuilderKeyRolloverTest, TestDuplicateAsyncIntermediates) {
|
| // lookups are expected.
|
| EXPECT_CALL(cert_issuer_source,
|
| SyncGetIssuersOf(oldintermediate_.get(), _));
|
| - EXPECT_CALL(cert_issuer_source,
|
| - AsyncGetIssuersOf(oldintermediate_.get(), _, _));
|
| + EXPECT_CALL(cert_issuer_source, AsyncGetIssuersOf(oldintermediate_, _, _));
|
| }
|
| target_issuers_callback.Run(target_issuers_req);
|
| ::testing::Mock::VerifyAndClearExpectations(target_issuers_req);
|
| @@ -1108,6 +1007,9 @@ TEST_F(PathBuilderKeyRolloverTest, TestDuplicateAsyncIntermediates) {
|
| EXPECT_EQ(newroot_, result.paths[1]->path[2]);
|
| }
|
|
|
| +// XXX Is it worth it to do parametirizenized tests so everything can be tested
|
| +// with async trust store?
|
| +
|
| } // namespace
|
|
|
| } // namespace net
|
|
|