Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "components/certificate_transparency/single_tree_tracker.h" | 5 #include "components/certificate_transparency/single_tree_tracker.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| 11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
| 12 #include "base/run_loop.h" | 12 #include "base/run_loop.h" |
| 13 #include "base/strings/string_number_conversions.h" | |
| 13 #include "base/strings/string_piece.h" | 14 #include "base/strings/string_piece.h" |
| 14 #include "base/test/histogram_tester.h" | 15 #include "base/test/histogram_tester.h" |
| 15 #include "components/base32/base32.h" | 16 #include "components/base32/base32.h" |
| 16 #include "components/certificate_transparency/log_dns_client.h" | 17 #include "components/certificate_transparency/log_dns_client.h" |
| 17 #include "components/certificate_transparency/mock_log_dns_traffic.h" | 18 #include "components/certificate_transparency/mock_log_dns_traffic.h" |
| 18 #include "crypto/sha2.h" | 19 #include "crypto/sha2.h" |
| 19 #include "net/base/network_change_notifier.h" | 20 #include "net/base/network_change_notifier.h" |
| 20 #include "net/cert/ct_log_verifier.h" | 21 #include "net/cert/ct_log_verifier.h" |
| 21 #include "net/cert/ct_serialization.h" | 22 #include "net/cert/ct_serialization.h" |
| 22 #include "net/cert/merkle_tree_leaf.h" | 23 #include "net/cert/merkle_tree_leaf.h" |
| 23 #include "net/cert/signed_certificate_timestamp.h" | 24 #include "net/cert/signed_certificate_timestamp.h" |
| 24 #include "net/cert/signed_tree_head.h" | 25 #include "net/cert/signed_tree_head.h" |
| 25 #include "net/cert/x509_certificate.h" | 26 #include "net/cert/x509_certificate.h" |
| 26 #include "net/dns/dns_client.h" | 27 #include "net/dns/dns_client.h" |
| 27 #include "net/log/net_log.h" | 28 #include "net/log/net_log.h" |
| 29 #include "net/log/test_net_log.h" | |
| 28 #include "net/test/ct_test_util.h" | 30 #include "net/test/ct_test_util.h" |
| 29 #include "testing/gtest/include/gtest/gtest.h" | 31 #include "testing/gtest/include/gtest/gtest.h" |
| 30 | 32 |
| 31 using net::ct::SignedCertificateTimestamp; | 33 using net::ct::SignedCertificateTimestamp; |
| 32 using net::ct::SignedTreeHead; | 34 using net::ct::SignedTreeHead; |
| 33 using net::ct::GetSampleSignedTreeHead; | 35 using net::ct::GetSampleSignedTreeHead; |
| 34 using net::ct::GetTestPublicKeyId; | 36 using net::ct::GetTestPublicKeyId; |
| 35 using net::ct::GetTestPublicKey; | 37 using net::ct::GetTestPublicKey; |
| 36 using net::ct::kSthRootHashLength; | 38 using net::ct::kSthRootHashLength; |
| 37 using net::ct::GetX509CertSCT; | 39 using net::ct::GetX509CertSCT; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 78 | 80 |
| 79 scoped_refptr<SignedCertificateTimestamp> GetSCT() { | 81 scoped_refptr<SignedCertificateTimestamp> GetSCT() { |
| 80 scoped_refptr<SignedCertificateTimestamp> sct; | 82 scoped_refptr<SignedCertificateTimestamp> sct; |
| 81 | 83 |
| 82 // TODO(eranm): Move setting of the origin field to ct_test_util.cc | 84 // TODO(eranm): Move setting of the origin field to ct_test_util.cc |
| 83 GetX509CertSCT(&sct); | 85 GetX509CertSCT(&sct); |
| 84 sct->origin = SignedCertificateTimestamp::SCT_FROM_OCSP_RESPONSE; | 86 sct->origin = SignedCertificateTimestamp::SCT_FROM_OCSP_RESPONSE; |
| 85 return sct; | 87 return sct; |
| 86 } | 88 } |
| 87 | 89 |
| 88 std::string Base32LeafHash(const net::X509Certificate* cert, | 90 std::string LeafHash(const net::X509Certificate* cert, |
| 89 const SignedCertificateTimestamp* sct) { | 91 const SignedCertificateTimestamp* sct) { |
| 90 net::ct::MerkleTreeLeaf leaf; | 92 net::ct::MerkleTreeLeaf leaf; |
| 91 if (!GetMerkleTreeLeaf(cert, sct, &leaf)) | 93 if (!GetMerkleTreeLeaf(cert, sct, &leaf)) |
| 92 return std::string(); | 94 return std::string(); |
| 93 | 95 |
| 94 std::string leaf_hash; | 96 std::string leaf_hash; |
| 95 if (!HashMerkleTreeLeaf(leaf, &leaf_hash)) | 97 if (!HashMerkleTreeLeaf(leaf, &leaf_hash)) |
| 96 return std::string(); | 98 return std::string(); |
| 97 | 99 |
| 100 return leaf_hash; | |
| 101 } | |
| 102 | |
| 103 std::string Base32LeafHash(const net::X509Certificate* cert, | |
| 104 const SignedCertificateTimestamp* sct) { | |
| 105 std::string leaf_hash = LeafHash(cert, sct); | |
| 106 if (leaf_hash.empty()) | |
| 107 return std::string(); | |
| 108 | |
| 98 return base32::Base32Encode(leaf_hash, | 109 return base32::Base32Encode(leaf_hash, |
| 99 base32::Base32EncodePolicy::OMIT_PADDING); | 110 base32::Base32EncodePolicy::OMIT_PADDING); |
| 100 } | 111 } |
| 101 | 112 |
| 102 // Fills in |sth| for a tree of size 2, where the root hash is a hash of | 113 // Fills in |sth| for a tree of size 2, where the root hash is a hash of |
| 103 // the test SCT (from GetX509CertSCT) and another entry, | 114 // the test SCT (from GetX509CertSCT) and another entry, |
| 104 // whose hash is '0a' 32 times. | 115 // whose hash is '0a' 32 times. |
| 105 bool GetSignedTreeHeadForTreeOfSize2(SignedTreeHead* sth) { | 116 bool GetSignedTreeHeadForTreeOfSize2(SignedTreeHead* sth) { |
| 106 sth->version = SignedTreeHead::V1; | 117 sth->version = SignedTreeHead::V1; |
| 107 // Timestamp is after the timestamp of the test SCT (GetX509CertSCT) | 118 // Timestamp is after the timestamp of the test SCT (GetX509CertSCT) |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 167 cert_sct_->origin = SignedCertificateTimestamp::SCT_FROM_OCSP_RESPONSE; | 178 cert_sct_->origin = SignedCertificateTimestamp::SCT_FROM_OCSP_RESPONSE; |
| 168 | 179 |
| 169 net_change_notifier_ = | 180 net_change_notifier_ = |
| 170 base::WrapUnique(net::NetworkChangeNotifier::CreateMock()); | 181 base::WrapUnique(net::NetworkChangeNotifier::CreateMock()); |
| 171 mock_dns_.InitializeDnsConfig(); | 182 mock_dns_.InitializeDnsConfig(); |
| 172 } | 183 } |
| 173 | 184 |
| 174 protected: | 185 protected: |
| 175 void CreateTreeTracker() { | 186 void CreateTreeTracker() { |
| 176 log_dns_client_ = base::MakeUnique<LogDnsClient>( | 187 log_dns_client_ = base::MakeUnique<LogDnsClient>( |
| 177 mock_dns_.CreateDnsClient(), net_log_, 1); | 188 mock_dns_.CreateDnsClient(), net_log_with_source_, 1); |
| 178 | 189 |
| 179 tree_tracker_ = | 190 tree_tracker_ = base::MakeUnique<SingleTreeTracker>( |
| 180 base::MakeUnique<SingleTreeTracker>(log_, log_dns_client_.get()); | 191 log_, log_dns_client_.get(), &net_log_); |
| 181 } | 192 } |
| 182 | 193 |
| 183 void CreateTreeTrackerWithDefaultDnsExpectation() { | 194 void CreateTreeTrackerWithDefaultDnsExpectation() { |
| 184 // Default to throttling requests as it means observed log entries will | 195 // Default to throttling requests as it means observed log entries will |
| 185 // be frozen in a pending state, simplifying testing of the | 196 // be frozen in a pending state, simplifying testing of the |
| 186 // SingleTreeTracker. | 197 // SingleTreeTracker. |
| 187 ASSERT_TRUE(ExpectLeafIndexRequestAndThrottle(chain_, cert_sct_)); | 198 ASSERT_TRUE(ExpectLeafIndexRequestAndThrottle(chain_, cert_sct_)); |
| 188 CreateTreeTracker(); | 199 CreateTreeTracker(); |
| 189 } | 200 } |
| 190 | 201 |
| 191 // Configured the |mock_dns_| to expect a request for the leaf index | 202 // Configured the |mock_dns_| to expect a request for the leaf index |
| 192 // and have th mock DNS client throttle it. | 203 // and have th mock DNS client throttle it. |
| 193 bool ExpectLeafIndexRequestAndThrottle( | 204 bool ExpectLeafIndexRequestAndThrottle( |
| 194 const scoped_refptr<net::X509Certificate>& chain, | 205 const scoped_refptr<net::X509Certificate>& chain, |
| 195 const scoped_refptr<SignedCertificateTimestamp>& sct) { | 206 const scoped_refptr<SignedCertificateTimestamp>& sct) { |
| 196 return mock_dns_.ExpectRequestAndSocketError( | 207 return mock_dns_.ExpectRequestAndSocketError( |
| 197 Base32LeafHash(chain.get(), sct.get()) + ".hash." + kDNSRequestSuffix, | 208 Base32LeafHash(chain.get(), sct.get()) + ".hash." + kDNSRequestSuffix, |
| 198 net::Error::ERR_TEMPORARILY_THROTTLED); | 209 net::Error::ERR_TEMPORARILY_THROTTLED); |
| 199 } | 210 } |
| 200 | 211 |
| 212 bool MatchAuditingResultInNetLog(net::TestNetLog& net_log, | |
| 213 std::string expected_leaf_hash, | |
| 214 bool expected_success) { | |
| 215 net::TestNetLogEntry::List entries; | |
| 216 | |
| 217 net_log.GetEntries(&entries); | |
| 218 if (entries.size() == 0) | |
| 219 return false; | |
| 220 net::TestNetLogEntry& logged_entry = entries[0]; | |
|
eroman
2017/01/31 19:24:25
const
Eran Messeri
2017/01/31 21:18:25
Done.
| |
| 221 | |
| 222 std::string logged_log_id, logged_leaf_hash; | |
| 223 if (!logged_entry.GetStringValue("log_id", &logged_log_id) || | |
| 224 !logged_entry.GetStringValue("log_entry", &logged_leaf_hash)) | |
| 225 return false; | |
| 226 | |
| 227 if (base::HexEncode(GetTestPublicKeyId().data(), | |
| 228 GetTestPublicKeyId().size()) != logged_log_id) | |
| 229 return false; | |
| 230 | |
| 231 if (base::HexEncode(expected_leaf_hash.data(), expected_leaf_hash.size()) != | |
| 232 logged_leaf_hash) | |
| 233 return false; | |
| 234 | |
| 235 bool logged_success; | |
| 236 if (!logged_entry.GetBooleanValue("success", &logged_success)) | |
| 237 return false; | |
| 238 | |
| 239 return logged_success == expected_success; | |
| 240 } | |
| 241 | |
| 201 base::MessageLoopForIO message_loop_; | 242 base::MessageLoopForIO message_loop_; |
| 202 MockLogDnsTraffic mock_dns_; | 243 MockLogDnsTraffic mock_dns_; |
| 203 scoped_refptr<const net::CTLogVerifier> log_; | 244 scoped_refptr<const net::CTLogVerifier> log_; |
| 204 std::unique_ptr<net::NetworkChangeNotifier> net_change_notifier_; | 245 std::unique_ptr<net::NetworkChangeNotifier> net_change_notifier_; |
| 205 std::unique_ptr<LogDnsClient> log_dns_client_; | 246 std::unique_ptr<LogDnsClient> log_dns_client_; |
| 206 std::unique_ptr<SingleTreeTracker> tree_tracker_; | 247 std::unique_ptr<SingleTreeTracker> tree_tracker_; |
| 207 scoped_refptr<net::X509Certificate> chain_; | 248 scoped_refptr<net::X509Certificate> chain_; |
| 208 scoped_refptr<SignedCertificateTimestamp> cert_sct_; | 249 scoped_refptr<SignedCertificateTimestamp> cert_sct_; |
| 209 net::NetLogWithSource net_log_; | 250 net::TestNetLog net_log_; |
| 251 net::NetLogWithSource net_log_with_source_; | |
| 210 }; | 252 }; |
| 211 | 253 |
| 212 // Test that an SCT is classified as pending for a newer STH if the | 254 // Test that an SCT is classified as pending for a newer STH if the |
| 213 // SingleTreeTracker has not seen any STHs so far. | 255 // SingleTreeTracker has not seen any STHs so far. |
| 214 TEST_F(SingleTreeTrackerTest, CorrectlyClassifiesUnobservedSCTNoSTH) { | 256 TEST_F(SingleTreeTrackerTest, CorrectlyClassifiesUnobservedSCTNoSTH) { |
| 215 CreateTreeTrackerWithDefaultDnsExpectation(); | 257 CreateTreeTrackerWithDefaultDnsExpectation(); |
| 216 | 258 |
| 217 base::HistogramTester histograms; | 259 base::HistogramTester histograms; |
| 218 // First make sure the SCT has not been observed at all. | 260 // First make sure the SCT has not been observed at all. |
| 219 EXPECT_EQ( | 261 EXPECT_EQ( |
| 220 SingleTreeTracker::SCT_NOT_OBSERVED, | 262 SingleTreeTracker::SCT_NOT_OBSERVED, |
| 221 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); | 263 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); |
| 222 | 264 |
| 223 tree_tracker_->OnSCTVerified(chain_.get(), cert_sct_.get()); | 265 tree_tracker_->OnSCTVerified(chain_.get(), cert_sct_.get()); |
| 224 | 266 |
| 225 // Since no STH was provided to the tree_tracker_ the status should be that | 267 // Since no STH was provided to the tree_tracker_ the status should be that |
| 226 // the SCT is pending a newer STH. | 268 // the SCT is pending a newer STH. |
| 227 EXPECT_EQ( | 269 EXPECT_EQ( |
| 228 SingleTreeTracker::SCT_PENDING_NEWER_STH, | 270 SingleTreeTracker::SCT_PENDING_NEWER_STH, |
| 229 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); | 271 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); |
| 230 | 272 |
| 231 // Expect logging of a value indicating a valid STH is required. | 273 // Expect logging of a value indicating a valid STH is required. |
| 232 histograms.ExpectTotalCount(kCanCheckForInclusionHistogramName, 1); | 274 histograms.ExpectTotalCount(kCanCheckForInclusionHistogramName, 1); |
| 233 histograms.ExpectBucketCount(kCanCheckForInclusionHistogramName, 0, 1); | 275 histograms.ExpectBucketCount(kCanCheckForInclusionHistogramName, 0, 1); |
| 276 EXPECT_EQ(0u, net_log_.GetSize()); | |
| 234 } | 277 } |
| 235 | 278 |
| 236 // Test that an SCT is classified as pending an inclusion check if the | 279 // Test that an SCT is classified as pending an inclusion check if the |
| 237 // SingleTreeTracker has a fresh-enough STH to check inclusion against. | 280 // SingleTreeTracker has a fresh-enough STH to check inclusion against. |
| 238 TEST_F(SingleTreeTrackerTest, CorrectlyClassifiesUnobservedSCTWithRecentSTH) { | 281 TEST_F(SingleTreeTrackerTest, CorrectlyClassifiesUnobservedSCTWithRecentSTH) { |
| 239 CreateTreeTrackerWithDefaultDnsExpectation(); | 282 CreateTreeTrackerWithDefaultDnsExpectation(); |
| 240 | 283 |
| 241 base::HistogramTester histograms; | 284 base::HistogramTester histograms; |
| 242 // Provide an STH to the tree_tracker_. | 285 // Provide an STH to the tree_tracker_. |
| 243 SignedTreeHead sth; | 286 SignedTreeHead sth; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 259 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); | 302 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); |
| 260 | 303 |
| 261 // Exactly one value should be logged, indicating the SCT can be checked for | 304 // Exactly one value should be logged, indicating the SCT can be checked for |
| 262 // inclusion, as |tree_tracker_| did have a valid STH when it was notified | 305 // inclusion, as |tree_tracker_| did have a valid STH when it was notified |
| 263 // of a new SCT. | 306 // of a new SCT. |
| 264 histograms.ExpectTotalCount(kCanCheckForInclusionHistogramName, 1); | 307 histograms.ExpectTotalCount(kCanCheckForInclusionHistogramName, 1); |
| 265 histograms.ExpectBucketCount(kCanCheckForInclusionHistogramName, 2, 1); | 308 histograms.ExpectBucketCount(kCanCheckForInclusionHistogramName, 2, 1); |
| 266 // Nothing should be logged in the result histogram since inclusion check | 309 // Nothing should be logged in the result histogram since inclusion check |
| 267 // didn't finish. | 310 // didn't finish. |
| 268 histograms.ExpectTotalCount(kInclusionCheckResultHistogramName, 0); | 311 histograms.ExpectTotalCount(kInclusionCheckResultHistogramName, 0); |
| 312 EXPECT_EQ(0u, net_log_.GetSize()); | |
| 269 } | 313 } |
| 270 | 314 |
| 271 // Test that the SingleTreeTracker correctly queues verified SCTs for inclusion | 315 // Test that the SingleTreeTracker correctly queues verified SCTs for inclusion |
| 272 // checking such that, upon receiving a fresh STH, it changes the SCT's status | 316 // checking such that, upon receiving a fresh STH, it changes the SCT's status |
| 273 // from pending newer STH to pending inclusion check. | 317 // from pending newer STH to pending inclusion check. |
| 274 TEST_F(SingleTreeTrackerTest, CorrectlyUpdatesSCTStatusOnNewSTH) { | 318 TEST_F(SingleTreeTrackerTest, CorrectlyUpdatesSCTStatusOnNewSTH) { |
| 275 CreateTreeTrackerWithDefaultDnsExpectation(); | 319 CreateTreeTrackerWithDefaultDnsExpectation(); |
| 276 | 320 |
| 277 base::HistogramTester histograms; | 321 base::HistogramTester histograms; |
| 278 // Report an observed SCT and make sure it's in the pending newer STH | 322 // Report an observed SCT and make sure it's in the pending newer STH |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 289 tree_tracker_->NewSTHObserved(sth); | 333 tree_tracker_->NewSTHObserved(sth); |
| 290 | 334 |
| 291 // Test that its status has changed. | 335 // Test that its status has changed. |
| 292 EXPECT_EQ( | 336 EXPECT_EQ( |
| 293 SingleTreeTracker::SCT_PENDING_INCLUSION_CHECK, | 337 SingleTreeTracker::SCT_PENDING_INCLUSION_CHECK, |
| 294 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); | 338 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); |
| 295 // Check that no additional UMA was logged for this case as the histogram is | 339 // Check that no additional UMA was logged for this case as the histogram is |
| 296 // only supposed to measure the state of newly-observed SCTs, not pending | 340 // only supposed to measure the state of newly-observed SCTs, not pending |
| 297 // ones. | 341 // ones. |
| 298 histograms.ExpectTotalCount(kCanCheckForInclusionHistogramName, 1); | 342 histograms.ExpectTotalCount(kCanCheckForInclusionHistogramName, 1); |
| 343 EXPECT_EQ(0u, net_log_.GetSize()); | |
| 299 } | 344 } |
| 300 | 345 |
| 301 // Test that the SingleTreeTracker does not change an SCT's status if an STH | 346 // Test that the SingleTreeTracker does not change an SCT's status if an STH |
| 302 // from the log it was issued by is observed, but that STH is too old to check | 347 // from the log it was issued by is observed, but that STH is too old to check |
| 303 // inclusion against. | 348 // inclusion against. |
| 304 TEST_F(SingleTreeTrackerTest, DoesNotUpdatesSCTStatusOnOldSTH) { | 349 TEST_F(SingleTreeTrackerTest, DoesNotUpdatesSCTStatusOnOldSTH) { |
| 305 CreateTreeTrackerWithDefaultDnsExpectation(); | 350 CreateTreeTrackerWithDefaultDnsExpectation(); |
| 306 | 351 |
| 307 // Notify of an SCT and make sure it's in the 'pending newer STH' state. | 352 // Notify of an SCT and make sure it's in the 'pending newer STH' state. |
| 308 tree_tracker_->OnSCTVerified(chain_.get(), cert_sct_.get()); | 353 tree_tracker_->OnSCTVerified(chain_.get(), cert_sct_.get()); |
| 309 EXPECT_EQ( | 354 EXPECT_EQ( |
| 310 SingleTreeTracker::SCT_PENDING_NEWER_STH, | 355 SingleTreeTracker::SCT_PENDING_NEWER_STH, |
| 311 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); | 356 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); |
| 312 | 357 |
| 313 // Provide an old STH for the same log. | 358 // Provide an old STH for the same log. |
| 314 SignedTreeHead sth; | 359 SignedTreeHead sth; |
| 315 GetOldSignedTreeHead(&sth); | 360 GetOldSignedTreeHead(&sth); |
| 316 tree_tracker_->NewSTHObserved(sth); | 361 tree_tracker_->NewSTHObserved(sth); |
| 317 | 362 |
| 318 // Make sure the SCT's state hasn't changed. | 363 // Make sure the SCT's state hasn't changed. |
| 319 EXPECT_EQ( | 364 EXPECT_EQ( |
| 320 SingleTreeTracker::SCT_PENDING_NEWER_STH, | 365 SingleTreeTracker::SCT_PENDING_NEWER_STH, |
| 321 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); | 366 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); |
| 367 EXPECT_EQ(0u, net_log_.GetSize()); | |
| 322 } | 368 } |
| 323 | 369 |
| 324 // Test that the SingleTreeTracker correctly logs that an SCT is pending a new | 370 // Test that the SingleTreeTracker correctly logs that an SCT is pending a new |
| 325 // STH, when it has a valid STH, but the observed SCT is not covered by the | 371 // STH, when it has a valid STH, but the observed SCT is not covered by the |
| 326 // STH. | 372 // STH. |
| 327 TEST_F(SingleTreeTrackerTest, LogsUMAForNewSCTAndOldSTH) { | 373 TEST_F(SingleTreeTrackerTest, LogsUMAForNewSCTAndOldSTH) { |
| 328 CreateTreeTrackerWithDefaultDnsExpectation(); | 374 CreateTreeTrackerWithDefaultDnsExpectation(); |
| 329 | 375 |
| 330 base::HistogramTester histograms; | 376 base::HistogramTester histograms; |
| 331 // Provide an old STH for the same log. | 377 // Provide an old STH for the same log. |
| 332 SignedTreeHead sth; | 378 SignedTreeHead sth; |
| 333 GetOldSignedTreeHead(&sth); | 379 GetOldSignedTreeHead(&sth); |
| 334 tree_tracker_->NewSTHObserved(sth); | 380 tree_tracker_->NewSTHObserved(sth); |
| 335 | 381 |
| 336 histograms.ExpectTotalCount(kCanCheckForInclusionHistogramName, 0); | 382 histograms.ExpectTotalCount(kCanCheckForInclusionHistogramName, 0); |
| 337 | 383 |
| 338 // Notify of an SCT and make sure it's in the 'pending newer STH' state. | 384 // Notify of an SCT and make sure it's in the 'pending newer STH' state. |
| 339 tree_tracker_->OnSCTVerified(chain_.get(), cert_sct_.get()); | 385 tree_tracker_->OnSCTVerified(chain_.get(), cert_sct_.get()); |
| 340 | 386 |
| 341 // Exactly one value should be logged, indicating the SCT cannot be checked | 387 // Exactly one value should be logged, indicating the SCT cannot be checked |
| 342 // for inclusion as the STH is too old. | 388 // for inclusion as the STH is too old. |
| 343 histograms.ExpectTotalCount(kCanCheckForInclusionHistogramName, 1); | 389 histograms.ExpectTotalCount(kCanCheckForInclusionHistogramName, 1); |
| 344 histograms.ExpectBucketCount(kCanCheckForInclusionHistogramName, 1, 1); | 390 histograms.ExpectBucketCount(kCanCheckForInclusionHistogramName, 1, 1); |
| 391 EXPECT_EQ(0u, net_log_.GetSize()); | |
| 345 } | 392 } |
| 346 | 393 |
| 347 // Test that an entry transitions to the "not found" state if the LogDnsClient | 394 // Test that an entry transitions to the "not found" state if the LogDnsClient |
| 348 // fails to get a leaf index. | 395 // fails to get a leaf index. |
| 349 TEST_F(SingleTreeTrackerTest, TestEntryNotPendingAfterLeafIndexFetchFailure) { | 396 TEST_F(SingleTreeTrackerTest, TestEntryNotPendingAfterLeafIndexFetchFailure) { |
| 350 ASSERT_TRUE(mock_dns_.ExpectRequestAndSocketError( | 397 ASSERT_TRUE(mock_dns_.ExpectRequestAndSocketError( |
| 351 Base32LeafHash(chain_.get(), cert_sct_.get()) + ".hash." + | 398 Base32LeafHash(chain_.get(), cert_sct_.get()) + ".hash." + |
| 352 kDNSRequestSuffix, | 399 kDNSRequestSuffix, |
| 353 net::Error::ERR_FAILED)); | 400 net::Error::ERR_FAILED)); |
| 354 | 401 |
| 355 CreateTreeTracker(); | 402 CreateTreeTracker(); |
| 356 | 403 |
| 357 tree_tracker_->OnSCTVerified(chain_.get(), cert_sct_.get()); | 404 tree_tracker_->OnSCTVerified(chain_.get(), cert_sct_.get()); |
| 358 EXPECT_EQ( | 405 EXPECT_EQ( |
| 359 SingleTreeTracker::SCT_PENDING_NEWER_STH, | 406 SingleTreeTracker::SCT_PENDING_NEWER_STH, |
| 360 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); | 407 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); |
| 361 | 408 |
| 362 // Provide with a fresh STH | 409 // Provide with a fresh STH |
| 363 SignedTreeHead sth; | 410 SignedTreeHead sth; |
| 364 GetSampleSignedTreeHead(&sth); | 411 GetSampleSignedTreeHead(&sth); |
| 365 tree_tracker_->NewSTHObserved(sth); | 412 tree_tracker_->NewSTHObserved(sth); |
| 366 base::RunLoop().RunUntilIdle(); | 413 base::RunLoop().RunUntilIdle(); |
| 367 | 414 |
| 368 EXPECT_EQ( | 415 EXPECT_EQ( |
| 369 SingleTreeTracker::SCT_NOT_OBSERVED, | 416 SingleTreeTracker::SCT_NOT_OBSERVED, |
| 370 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); | 417 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); |
| 418 // There should have been one NetLog event, logged with failure. | |
| 419 EXPECT_TRUE(MatchAuditingResultInNetLog( | |
| 420 net_log_, LeafHash(chain_.get(), cert_sct_.get()), false)); | |
| 371 } | 421 } |
| 372 | 422 |
| 373 // Test that an entry transitions to the "not found" state if the LogDnsClient | 423 // Test that an entry transitions to the "not found" state if the LogDnsClient |
| 374 // succeeds to get a leaf index but fails to get an inclusion proof. | 424 // succeeds to get a leaf index but fails to get an inclusion proof. |
| 375 TEST_F(SingleTreeTrackerTest, TestEntryNotPendingAfterInclusionCheckFailure) { | 425 TEST_F(SingleTreeTrackerTest, TestEntryNotPendingAfterInclusionCheckFailure) { |
| 376 // Return 12 as the index of this leaf. | 426 // Return 12 as the index of this leaf. |
| 377 ASSERT_TRUE(mock_dns_.ExpectLeafIndexRequestAndResponse( | 427 ASSERT_TRUE(mock_dns_.ExpectLeafIndexRequestAndResponse( |
| 378 Base32LeafHash(chain_.get(), cert_sct_.get()) + ".hash." + | 428 Base32LeafHash(chain_.get(), cert_sct_.get()) + ".hash." + |
| 379 kDNSRequestSuffix, | 429 kDNSRequestSuffix, |
| 380 12)); | 430 12)); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 394 | 444 |
| 395 // Provide with a fresh STH | 445 // Provide with a fresh STH |
| 396 SignedTreeHead sth; | 446 SignedTreeHead sth; |
| 397 GetSampleSignedTreeHead(&sth); | 447 GetSampleSignedTreeHead(&sth); |
| 398 tree_tracker_->NewSTHObserved(sth); | 448 tree_tracker_->NewSTHObserved(sth); |
| 399 base::RunLoop().RunUntilIdle(); | 449 base::RunLoop().RunUntilIdle(); |
| 400 | 450 |
| 401 EXPECT_EQ( | 451 EXPECT_EQ( |
| 402 SingleTreeTracker::SCT_NOT_OBSERVED, | 452 SingleTreeTracker::SCT_NOT_OBSERVED, |
| 403 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); | 453 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); |
| 454 // There should have been one NetLog event, logged with failure. | |
| 455 EXPECT_TRUE(MatchAuditingResultInNetLog( | |
| 456 net_log_, LeafHash(chain_.get(), cert_sct_.get()), false)); | |
| 404 } | 457 } |
| 405 | 458 |
| 406 // Test that an entry transitions to the "included" state if the LogDnsClient | 459 // Test that an entry transitions to the "included" state if the LogDnsClient |
| 407 // succeeds to get a leaf index and an inclusion proof. | 460 // succeeds to get a leaf index and an inclusion proof. |
| 408 TEST_F(SingleTreeTrackerTest, TestEntryIncludedAfterInclusionCheckSuccess) { | 461 TEST_F(SingleTreeTrackerTest, TestEntryIncludedAfterInclusionCheckSuccess) { |
| 409 std::vector<std::string> audit_proof; | 462 std::vector<std::string> audit_proof; |
| 410 FillVectorWithValidAuditProofForTreeOfSize2(&audit_proof); | 463 FillVectorWithValidAuditProofForTreeOfSize2(&audit_proof); |
| 411 | 464 |
| 412 // Return 0 as the index for this leaf, so the proof provided | 465 // Return 0 as the index for this leaf, so the proof provided |
| 413 // later on would verify. | 466 // later on would verify. |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 433 SignedTreeHead sth; | 486 SignedTreeHead sth; |
| 434 ASSERT_TRUE(GetSignedTreeHeadForTreeOfSize2(&sth)); | 487 ASSERT_TRUE(GetSignedTreeHeadForTreeOfSize2(&sth)); |
| 435 ASSERT_TRUE(log_->VerifySignedTreeHead(sth)); | 488 ASSERT_TRUE(log_->VerifySignedTreeHead(sth)); |
| 436 | 489 |
| 437 tree_tracker_->NewSTHObserved(sth); | 490 tree_tracker_->NewSTHObserved(sth); |
| 438 base::RunLoop().RunUntilIdle(); | 491 base::RunLoop().RunUntilIdle(); |
| 439 | 492 |
| 440 EXPECT_EQ( | 493 EXPECT_EQ( |
| 441 SingleTreeTracker::SCT_INCLUDED_IN_LOG, | 494 SingleTreeTracker::SCT_INCLUDED_IN_LOG, |
| 442 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); | 495 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); |
| 496 // There should have been one NetLog event, with success logged. | |
| 497 EXPECT_TRUE(MatchAuditingResultInNetLog( | |
| 498 net_log_, LeafHash(chain_.get(), cert_sct_.get()), true)); | |
| 443 } | 499 } |
| 444 | 500 |
| 445 // Test that pending entries transition states correctly according to the | 501 // Test that pending entries transition states correctly according to the |
| 446 // STHs provided: | 502 // STHs provided: |
| 447 // * Start without an STH. | 503 // * Start without an STH. |
| 448 // * Add a collection of entries with mixed timestamps (i.e. SCTs not added | 504 // * Add a collection of entries with mixed timestamps (i.e. SCTs not added |
| 449 // in the order of their timestamps). | 505 // in the order of their timestamps). |
| 450 // * Provide an STH that covers some of the entries, test these are audited. | 506 // * Provide an STH that covers some of the entries, test these are audited. |
| 451 // * Provide another STH that covers more of the entries, test that the entries | 507 // * Provide another STH that covers more of the entries, test that the entries |
| 452 // already audited are not audited again and that those that need to be | 508 // already audited are not audited again and that those that need to be |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 652 // inclusion, as |tree_tracker_| did have a valid STH when it was notified | 708 // inclusion, as |tree_tracker_| did have a valid STH when it was notified |
| 653 // of a new SCT. | 709 // of a new SCT. |
| 654 histograms.ExpectTotalCount(kCanCheckForInclusionHistogramName, 1); | 710 histograms.ExpectTotalCount(kCanCheckForInclusionHistogramName, 1); |
| 655 histograms.ExpectBucketCount(kCanCheckForInclusionHistogramName, 2, 1); | 711 histograms.ExpectBucketCount(kCanCheckForInclusionHistogramName, 2, 1); |
| 656 // Failure due to DNS configuration should be logged in the result histogram. | 712 // Failure due to DNS configuration should be logged in the result histogram. |
| 657 histograms.ExpectTotalCount(kInclusionCheckResultHistogramName, 1); | 713 histograms.ExpectTotalCount(kInclusionCheckResultHistogramName, 1); |
| 658 histograms.ExpectBucketCount(kInclusionCheckResultHistogramName, 3, 1); | 714 histograms.ExpectBucketCount(kInclusionCheckResultHistogramName, 3, 1); |
| 659 } | 715 } |
| 660 | 716 |
| 661 } // namespace certificate_transparency | 717 } // namespace certificate_transparency |
| OLD | NEW |