| Index: net/cert/internal/trust_store_collection_unittest.cc
|
| diff --git a/net/cert/internal/trust_store_collection_unittest.cc b/net/cert/internal/trust_store_collection_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..44787158c686e41ce6bee88f07723b73d8812e5a
|
| --- /dev/null
|
| +++ b/net/cert/internal/trust_store_collection_unittest.cc
|
| @@ -0,0 +1,229 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "net/cert/internal/trust_store_collection.h"
|
| +
|
| +#include "base/bind.h"
|
| +#include "net/cert/internal/test_helpers.h"
|
| +#include "net/cert/internal/trust_store_test_helpers.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace net {
|
| +
|
| +namespace {
|
| +
|
| +using ::testing::_;
|
| +using ::testing::Property;
|
| +using ::testing::StrictMock;
|
| +
|
| +void NotCalled(TrustAnchors anchors) {
|
| + ADD_FAILURE() << "NotCalled was called";
|
| +}
|
| +
|
| +class MockTrustStore : public TrustStore {
|
| + public:
|
| + MOCK_CONST_METHOD4(FindTrustAnchorsForCert,
|
| + void(const scoped_refptr<ParsedCertificate>&,
|
| + const TrustAnchorsCallback&,
|
| + TrustAnchors*,
|
| + std::unique_ptr<Request>*));
|
| +};
|
| +
|
| +class TrustStoreCollectionTest : public testing::Test {
|
| + public:
|
| + void SetUp() override {
|
| + ParsedCertificateList chain;
|
| + bool unused_verify_result;
|
| + der::GeneralizedTime unused_time;
|
| + std::string unused_errors;
|
| +
|
| + ReadVerifyCertChainTestFromFile("key-rollover-oldchain.pem", &chain,
|
| + &oldroot_, &unused_time,
|
| + &unused_verify_result, &unused_errors);
|
| + ASSERT_EQ(2U, chain.size());
|
| + target_ = chain[0];
|
| + oldintermediate_ = chain[1];
|
| + ASSERT_TRUE(target_);
|
| + ASSERT_TRUE(oldintermediate_);
|
| + ASSERT_TRUE(oldroot_);
|
| +
|
| + scoped_refptr<TrustAnchor> unused_root;
|
| + ReadVerifyCertChainTestFromFile("key-rollover-longrolloverchain.pem",
|
| + &chain, &unused_root, &unused_time,
|
| + &unused_verify_result, &unused_errors);
|
| + ASSERT_EQ(4U, chain.size());
|
| + newintermediate_ = chain[1];
|
| + newroot_ = TrustAnchor::CreateFromCertificateNoConstraints(chain[2]);
|
| + newrootrollover_ =
|
| + TrustAnchor::CreateFromCertificateNoConstraints(chain[3]);
|
| + ASSERT_TRUE(newintermediate_);
|
| + ASSERT_TRUE(newroot_);
|
| + ASSERT_TRUE(newrootrollover_);
|
| + }
|
| +
|
| + protected:
|
| + scoped_refptr<TrustAnchor> oldroot_;
|
| + scoped_refptr<TrustAnchor> newroot_;
|
| + scoped_refptr<TrustAnchor> newrootrollover_;
|
| +
|
| + scoped_refptr<ParsedCertificate> target_;
|
| + scoped_refptr<ParsedCertificate> oldintermediate_;
|
| + scoped_refptr<ParsedCertificate> newintermediate_;
|
| +};
|
| +
|
| +// Collection contains no stores, should return no results and complete
|
| +// synchronously.
|
| +TEST_F(TrustStoreCollectionTest, NoStores) {
|
| + std::unique_ptr<TrustStore::Request> req;
|
| + TrustAnchors sync_matches;
|
| +
|
| + TrustStoreCollection collection;
|
| + collection.FindTrustAnchorsForCert(target_, base::Bind(&NotCalled),
|
| + &sync_matches, &req);
|
| +
|
| + EXPECT_FALSE(req);
|
| + EXPECT_TRUE(sync_matches.empty());
|
| +}
|
| +
|
| +// Collection contains only one synchronous store, should complete
|
| +// synchronously.
|
| +TEST_F(TrustStoreCollectionTest, NoPrimaryStoreOneSyncStore) {
|
| + std::unique_ptr<TrustStore::Request> req;
|
| + TrustAnchors sync_matches;
|
| +
|
| + TrustStoreCollection collection;
|
| + TrustStoreInMemory in_memory;
|
| + in_memory.AddTrustAnchor(newroot_);
|
| + collection.AddTrustStoreSynchronousOnly(&in_memory);
|
| + collection.FindTrustAnchorsForCert(newintermediate_, base::Bind(&NotCalled),
|
| + &sync_matches, &req);
|
| +
|
| + EXPECT_FALSE(req);
|
| + ASSERT_EQ(1U, sync_matches.size());
|
| + EXPECT_EQ(newroot_, sync_matches[0]);
|
| +}
|
| +
|
| +// Collection contains two synchronous stores, should complete synchronously.
|
| +TEST_F(TrustStoreCollectionTest, NoPrimaryStoreTwoSyncStores) {
|
| + std::unique_ptr<TrustStore::Request> req;
|
| + TrustAnchors sync_matches;
|
| +
|
| + TrustStoreCollection collection;
|
| + TrustStoreInMemory in_memory1;
|
| + TrustStoreInMemory in_memory2;
|
| + in_memory1.AddTrustAnchor(newroot_);
|
| + in_memory2.AddTrustAnchor(oldroot_);
|
| + collection.AddTrustStoreSynchronousOnly(&in_memory1);
|
| + collection.AddTrustStoreSynchronousOnly(&in_memory2);
|
| + collection.FindTrustAnchorsForCert(newintermediate_, base::Bind(&NotCalled),
|
| + &sync_matches, &req);
|
| +
|
| + EXPECT_FALSE(req);
|
| + ASSERT_EQ(2U, sync_matches.size());
|
| + EXPECT_EQ(newroot_, sync_matches[0]);
|
| + EXPECT_EQ(oldroot_, sync_matches[1]);
|
| +}
|
| +
|
| +// The secondary stores in the collection should not be passed a callback to
|
| +// their FindTrustAnchorsForCert call.
|
| +TEST_F(TrustStoreCollectionTest, SyncStoresAreQueriedSynchronously) {
|
| + std::unique_ptr<TrustStore::Request> req;
|
| + TrustAnchors sync_matches;
|
| +
|
| + TrustStoreCollection collection;
|
| + StrictMock<MockTrustStore> store;
|
| + collection.AddTrustStoreSynchronousOnly(&store);
|
| +
|
| + EXPECT_CALL(
|
| + store,
|
| + FindTrustAnchorsForCert(
|
| + _, Property(&TrustStore::TrustAnchorsCallback::is_null, true), _, _));
|
| +
|
| + collection.FindTrustAnchorsForCert(newintermediate_, base::Bind(&NotCalled),
|
| + &sync_matches, &req);
|
| +
|
| + EXPECT_FALSE(req);
|
| + EXPECT_TRUE(sync_matches.empty());
|
| +}
|
| +
|
| +// If the primary store completes synchronously, TrustStoreCollection should
|
| +// complete synchronously also.
|
| +TEST_F(TrustStoreCollectionTest, AllStoresAreSynchronous) {
|
| + std::unique_ptr<TrustStore::Request> req;
|
| + TrustAnchors sync_matches;
|
| +
|
| + TrustStoreCollection collection;
|
| + TrustStoreInMemory in_memory1;
|
| + TrustStoreInMemory in_memory2;
|
| + in_memory1.AddTrustAnchor(newroot_);
|
| + in_memory2.AddTrustAnchor(oldroot_);
|
| + collection.SetPrimaryTrustStore(&in_memory1);
|
| + collection.AddTrustStoreSynchronousOnly(&in_memory2);
|
| + collection.FindTrustAnchorsForCert(newintermediate_, base::Bind(&NotCalled),
|
| + &sync_matches, &req);
|
| +
|
| + EXPECT_FALSE(req);
|
| + ASSERT_EQ(2U, sync_matches.size());
|
| + EXPECT_EQ(newroot_, sync_matches[0]);
|
| + EXPECT_EQ(oldroot_, sync_matches[1]);
|
| +}
|
| +
|
| +// Primary store returns results asynchronously. No secondary stores registered.
|
| +TEST_F(TrustStoreCollectionTest, AsyncPrimaryStore) {
|
| + std::unique_ptr<TrustStore::Request> req;
|
| + TrustAnchors sync_matches;
|
| +
|
| + TrustStoreInMemoryAsync in_memory_async;
|
| + in_memory_async.AddAsyncTrustAnchor(newroot_);
|
| +
|
| + TrustStoreCollection collection;
|
| + collection.SetPrimaryTrustStore(&in_memory_async);
|
| +
|
| + TrustAnchorResultRecorder anchor_results;
|
| + collection.FindTrustAnchorsForCert(
|
| + newintermediate_, anchor_results.Callback(), &sync_matches, &req);
|
| +
|
| + ASSERT_TRUE(req);
|
| + EXPECT_TRUE(sync_matches.empty());
|
| +
|
| + anchor_results.Run();
|
| + ASSERT_EQ(1U, anchor_results.matches().size());
|
| + EXPECT_EQ(newroot_, anchor_results.matches()[0]);
|
| +}
|
| +
|
| +// Primary store returns results both synchronously and asynchronously, and
|
| +// a secondary store returns results synchronously as well.
|
| +TEST_F(TrustStoreCollectionTest, SyncAndAsyncPrimaryStoreAndSyncStore) {
|
| + std::unique_ptr<TrustStore::Request> req;
|
| + TrustAnchors sync_matches;
|
| +
|
| + TrustStoreInMemoryAsync in_memory_async;
|
| + in_memory_async.AddAsyncTrustAnchor(newroot_);
|
| + in_memory_async.AddSyncTrustAnchor(newrootrollover_);
|
| +
|
| + TrustStoreInMemory in_memory;
|
| + in_memory.AddTrustAnchor(oldroot_);
|
| +
|
| + TrustStoreCollection collection;
|
| + collection.SetPrimaryTrustStore(&in_memory_async);
|
| + collection.AddTrustStoreSynchronousOnly(&in_memory);
|
| +
|
| + TrustAnchorResultRecorder anchor_results;
|
| + collection.FindTrustAnchorsForCert(
|
| + newintermediate_, anchor_results.Callback(), &sync_matches, &req);
|
| +
|
| + ASSERT_TRUE(req);
|
| + ASSERT_EQ(2U, sync_matches.size());
|
| + EXPECT_EQ(newrootrollover_, sync_matches[0]);
|
| + EXPECT_EQ(oldroot_, sync_matches[1]);
|
| +
|
| + anchor_results.Run();
|
| + ASSERT_EQ(1U, anchor_results.matches().size());
|
| + EXPECT_EQ(newroot_, anchor_results.matches()[0]);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +} // namespace net
|
|
|