| // 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 "components/certificate_transparency/tree_state_tracker.h" |
| |
| #include <memory> |
| #include <string> |
| #include <utility> |
| |
| #include "base/run_loop.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/test/scoped_feature_list.h" |
| #include "base/test/scoped_task_environment.h" |
| #include "components/certificate_transparency/features.h" |
| #include "net/base/net_errors.h" |
| #include "net/cert/ct_log_verifier.h" |
| #include "net/cert/ct_serialization.h" |
| #include "net/cert/merkle_tree_leaf.h" |
| #include "net/cert/signed_certificate_timestamp.h" |
| #include "net/cert/signed_tree_head.h" |
| #include "net/cert/x509_certificate.h" |
| #include "net/dns/mock_host_resolver.h" |
| #include "net/log/net_log.h" |
| #include "net/log/test_net_log.h" |
| #include "net/test/ct_test_util.h" |
| #include "net/url_request/url_request_test_util.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| using net::ct::SignedCertificateTimestamp; |
| using net::ct::SignedTreeHead; |
| using net::ct::GetSampleSignedTreeHead; |
| using net::ct::GetTestPublicKeyId; |
| using net::ct::GetTestPublicKey; |
| using net::ct::kSthRootHashLength; |
| using net::ct::GetX509CertSCT; |
| |
| constexpr char kHostname[] = "example.test"; |
| constexpr base::TimeDelta kZeroTTL; |
| |
| namespace certificate_transparency { |
| |
| class TreeStateTrackerTest : public ::testing::Test { |
| void SetUp() override { |
| log_ = net::CTLogVerifier::Create(GetTestPublicKey(), "testlog", |
| "unresolvable.invalid"); |
| |
| ASSERT_TRUE(log_); |
| ASSERT_EQ(log_->key_id(), GetTestPublicKeyId()); |
| |
| const std::string der_test_cert(net::ct::GetDerEncodedX509Cert()); |
| chain_ = net::X509Certificate::CreateFromBytes(der_test_cert.data(), |
| der_test_cert.length()); |
| ASSERT_TRUE(chain_.get()); |
| GetX509CertSCT(&cert_sct_); |
| cert_sct_->origin = SignedCertificateTimestamp::SCT_FROM_OCSP_RESPONSE; |
| } |
| |
| protected: |
| base::test::ScopedTaskEnvironment task_environment_{ |
| base::test::ScopedTaskEnvironment::MainThreadType::IO}; |
| scoped_refptr<const net::CTLogVerifier> log_; |
| net::MockCachingHostResolver host_resolver_; |
| std::unique_ptr<TreeStateTracker> tree_tracker_; |
| scoped_refptr<net::X509Certificate> chain_; |
| scoped_refptr<SignedCertificateTimestamp> cert_sct_; |
| net::TestNetLog net_log_; |
| }; |
| |
| // Test that a new STH & SCT are delegated correctly to a |
| // SingleTreeTracker instance created by the TreeStateTracker. |
| // This is verified by looking for a single event on the net_log_ |
| // passed into the TreeStateTracker c'tor. |
| TEST_F(TreeStateTrackerTest, TestDelegatesCorrectly) { |
| std::vector<scoped_refptr<const net::CTLogVerifier>> verifiers; |
| verifiers.push_back(log_); |
| |
| base::test::ScopedFeatureList feature_list; |
| feature_list.InitAndEnableFeature(kCTLogAuditing); |
| |
| tree_tracker_ = std::make_unique<TreeStateTracker>( |
| verifiers, &host_resolver_, new net::TestURLRequestContext(), &net_log_); |
| |
| // Add a cache entry for kHostname that indicates it was looked up over DNS. |
| // SingleTreeTracker requires this before it will request an inclusion proof, |
| // as otherwise it would reveal to the DNS resolver which server a user |
| // visited. If the server was already looked up via DNS though, that that |
| // information is already known to the DNS resolver so there is then no harm. |
| host_resolver_.GetHostCache()->Set( |
| net::HostCache::Key(kHostname, net::ADDRESS_FAMILY_UNSPECIFIED, 0), |
| net::HostCache::Entry(net::OK, net::AddressList(), |
| net::HostCache::Entry::SOURCE_DNS), |
| base::TimeTicks::Now(), kZeroTTL); |
| |
| SignedTreeHead sth; |
| GetSampleSignedTreeHead(&sth); |
| ASSERT_EQ(log_->key_id(), sth.log_id); |
| tree_tracker_->NewSTHObserved(sth); |
| |
| ASSERT_EQ(log_->key_id(), cert_sct_->log_id); |
| tree_tracker_->OnSCTVerified(kHostname, chain_.get(), cert_sct_.get()); |
| base::RunLoop().RunUntilIdle(); |
| |
| net::ct::MerkleTreeLeaf leaf; |
| ASSERT_TRUE(GetMerkleTreeLeaf(chain_.get(), cert_sct_.get(), &leaf)); |
| |
| std::string leaf_hash; |
| ASSERT_TRUE(HashMerkleTreeLeaf(leaf, &leaf_hash)); |
| // There should be one NetLog event. |
| EXPECT_EQ(1u, net_log_.GetSize()); |
| } |
| |
| } // namespace certificate_transparency |