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 |