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/strings/string_piece.h" | 10 #include "base/strings/string_piece.h" |
| 11 #include "base/test/histogram_tester.h" | |
| 11 #include "net/cert/ct_log_verifier.h" | 12 #include "net/cert/ct_log_verifier.h" |
| 12 #include "net/cert/ct_serialization.h" | 13 #include "net/cert/ct_serialization.h" |
| 13 #include "net/cert/signed_certificate_timestamp.h" | 14 #include "net/cert/signed_certificate_timestamp.h" |
| 14 #include "net/cert/signed_tree_head.h" | 15 #include "net/cert/signed_tree_head.h" |
| 15 #include "net/cert/x509_certificate.h" | 16 #include "net/cert/x509_certificate.h" |
| 16 #include "net/test/ct_test_util.h" | 17 #include "net/test/ct_test_util.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
| 18 | 19 |
| 19 namespace certificate_transparency { | 20 namespace certificate_transparency { |
| 21 using internal::kCanCheckForInclusionHistogramName; | |
|
Ryan Sleevi
2016/07/20 20:34:00
Newline
Eran Messeri
2016/07/21 17:53:43
Done.
| |
| 20 | 22 |
| 21 namespace { | 23 namespace { |
| 22 | 24 |
| 23 bool GetOldSignedTreeHead(net::ct::SignedTreeHead* sth) { | 25 bool GetOldSignedTreeHead(net::ct::SignedTreeHead* sth) { |
| 24 sth->version = net::ct::SignedTreeHead::V1; | 26 sth->version = net::ct::SignedTreeHead::V1; |
| 25 sth->timestamp = base::Time::UnixEpoch() + | 27 sth->timestamp = base::Time::UnixEpoch() + |
| 26 base::TimeDelta::FromMilliseconds(INT64_C(1348589665525)); | 28 base::TimeDelta::FromMilliseconds(INT64_C(1348589665525)); |
| 27 sth->tree_size = 12u; | 29 sth->tree_size = 12u; |
| 28 | 30 |
| 29 const uint8_t kOldSTHRootHash[] = { | 31 const uint8_t kOldSTHRootHash[] = { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 68 protected: | 70 protected: |
| 69 scoped_refptr<const net::CTLogVerifier> log_; | 71 scoped_refptr<const net::CTLogVerifier> log_; |
| 70 std::unique_ptr<SingleTreeTracker> tree_tracker_; | 72 std::unique_ptr<SingleTreeTracker> tree_tracker_; |
| 71 scoped_refptr<net::X509Certificate> chain_; | 73 scoped_refptr<net::X509Certificate> chain_; |
| 72 scoped_refptr<net::ct::SignedCertificateTimestamp> cert_sct_; | 74 scoped_refptr<net::ct::SignedCertificateTimestamp> cert_sct_; |
| 73 }; | 75 }; |
| 74 | 76 |
| 75 // Test that an SCT is classified as pending for a newer STH if the | 77 // Test that an SCT is classified as pending for a newer STH if the |
| 76 // SingleTreeTracker has not seen any STHs so far. | 78 // SingleTreeTracker has not seen any STHs so far. |
| 77 TEST_F(SingleTreeTrackerTest, CorrectlyClassifiesUnobservedSCTNoSTH) { | 79 TEST_F(SingleTreeTrackerTest, CorrectlyClassifiesUnobservedSCTNoSTH) { |
| 80 base::HistogramTester histograms; | |
| 78 // First make sure the SCT has not been observed at all. | 81 // First make sure the SCT has not been observed at all. |
| 79 EXPECT_EQ( | 82 EXPECT_EQ( |
| 80 SingleTreeTracker::SCT_NOT_OBSERVED, | 83 SingleTreeTracker::SCT_NOT_OBSERVED, |
| 81 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); | 84 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); |
| 82 | 85 |
| 83 tree_tracker_->OnSCTVerified(chain_.get(), cert_sct_.get()); | 86 tree_tracker_->OnSCTVerified(chain_.get(), cert_sct_.get()); |
| 84 | 87 |
| 85 // Since no STH was provided to the tree_tracker_ the status should be that | 88 // Since no STH was provided to the tree_tracker_ the status should be that |
| 86 // the SCT is pending a newer STH. | 89 // the SCT is pending a newer STH. |
| 87 EXPECT_EQ( | 90 EXPECT_EQ( |
| 88 SingleTreeTracker::SCT_PENDING_NEWER_STH, | 91 SingleTreeTracker::SCT_PENDING_NEWER_STH, |
| 89 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); | 92 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); |
| 93 | |
| 94 // Since there's no valid STH expect nothing was logged to UMA. | |
|
Ryan Sleevi
2016/07/20 20:34:00
Grammar: Something feels off on this, most likely
Eran Messeri
2016/07/21 17:53:43
Done.
| |
| 95 histograms.ExpectTotalCount(kCanCheckForInclusionHistogramName, 0); | |
| 90 } | 96 } |
| 91 | 97 |
| 92 // Test that an SCT is classified as pending an inclusion check if the | 98 // Test that an SCT is classified as pending an inclusion check if the |
| 93 // SingleTreeTracker has a fresh-enough STH to check inclusion against. | 99 // SingleTreeTracker has a fresh-enough STH to check inclusion against. |
| 94 TEST_F(SingleTreeTrackerTest, CorrectlyClassifiesUnobservedSCTWithRecentSTH) { | 100 TEST_F(SingleTreeTrackerTest, CorrectlyClassifiesUnobservedSCTWithRecentSTH) { |
| 101 base::HistogramTester histograms; | |
| 95 // Provide an STH to the tree_tracker_. | 102 // Provide an STH to the tree_tracker_. |
| 96 net::ct::SignedTreeHead sth; | 103 net::ct::SignedTreeHead sth; |
| 97 net::ct::GetSampleSignedTreeHead(&sth); | 104 net::ct::GetSampleSignedTreeHead(&sth); |
| 98 tree_tracker_->NewSTHObserved(sth); | 105 tree_tracker_->NewSTHObserved(sth); |
| 99 | 106 |
| 100 // Make sure the SCT status is the same as if there's no STH for | 107 // Make sure the SCT status is the same as if there's no STH for |
| 101 // this log. | 108 // this log. |
| 102 EXPECT_EQ( | 109 EXPECT_EQ( |
| 103 SingleTreeTracker::SCT_NOT_OBSERVED, | 110 SingleTreeTracker::SCT_NOT_OBSERVED, |
| 104 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); | 111 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); |
| 105 | 112 |
| 106 tree_tracker_->OnSCTVerified(chain_.get(), cert_sct_.get()); | 113 tree_tracker_->OnSCTVerified(chain_.get(), cert_sct_.get()); |
| 107 | 114 |
| 108 // The status for this SCT should be 'pending inclusion check' since the STH | 115 // The status for this SCT should be 'pending inclusion check' since the STH |
| 109 // provided at the beginning of the test is newer than the SCT. | 116 // provided at the beginning of the test is newer than the SCT. |
| 110 EXPECT_EQ( | 117 EXPECT_EQ( |
| 111 SingleTreeTracker::SCT_PENDING_INCLUSION_CHECK, | 118 SingleTreeTracker::SCT_PENDING_INCLUSION_CHECK, |
| 112 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); | 119 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); |
| 120 | |
| 121 // Exactly one value should be logged, indicating the SCT | |
| 122 // can be checked for inclusion. | |
|
Ryan Sleevi
2016/07/20 20:34:00
Similarly, this comment doesn't make sense in the
Eran Messeri
2016/07/21 17:53:43
Expanded the comment to document why it's expected
| |
| 123 histograms.ExpectTotalCount(kCanCheckForInclusionHistogramName, 1); | |
| 124 histograms.ExpectBucketCount(kCanCheckForInclusionHistogramName, true, 1); | |
| 113 } | 125 } |
| 114 | 126 |
| 115 // Test that the SingleTreeTracker correctly queues verified SCTs for inclusion | 127 // Test that the SingleTreeTracker correctly queues verified SCTs for inclusion |
| 116 // checking such that, upon receiving a fresh STH, it changes the SCT's status | 128 // checking such that, upon receiving a fresh STH, it changes the SCT's status |
| 117 // from pending newer STH to pending inclusion check. | 129 // from pending newer STH to pending inclusion check. |
| 118 TEST_F(SingleTreeTrackerTest, CorrectlyUpdatesSCTStatusOnNewSTH) { | 130 TEST_F(SingleTreeTrackerTest, CorrectlyUpdatesSCTStatusOnNewSTH) { |
| 131 base::HistogramTester histograms; | |
| 119 // Report an observed SCT and make sure it's in the pending newer STH | 132 // Report an observed SCT and make sure it's in the pending newer STH |
| 120 // state. | 133 // state. |
| 121 tree_tracker_->OnSCTVerified(chain_.get(), cert_sct_.get()); | 134 tree_tracker_->OnSCTVerified(chain_.get(), cert_sct_.get()); |
| 122 EXPECT_EQ( | 135 EXPECT_EQ( |
| 123 SingleTreeTracker::SCT_PENDING_NEWER_STH, | 136 SingleTreeTracker::SCT_PENDING_NEWER_STH, |
| 124 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); | 137 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); |
| 138 histograms.ExpectTotalCount(kCanCheckForInclusionHistogramName, 0); | |
| 125 | 139 |
| 126 // Provide with a fresh STH | 140 // Provide with a fresh STH |
| 127 net::ct::SignedTreeHead sth; | 141 net::ct::SignedTreeHead sth; |
| 128 net::ct::GetSampleSignedTreeHead(&sth); | 142 net::ct::GetSampleSignedTreeHead(&sth); |
| 129 tree_tracker_->NewSTHObserved(sth); | 143 tree_tracker_->NewSTHObserved(sth); |
| 130 | 144 |
| 131 // Test that its status has changed. | 145 // Test that its status has changed. |
| 132 EXPECT_EQ( | 146 EXPECT_EQ( |
| 133 SingleTreeTracker::SCT_PENDING_INCLUSION_CHECK, | 147 SingleTreeTracker::SCT_PENDING_INCLUSION_CHECK, |
| 134 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); | 148 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); |
| 149 // Check that no UMA was logged for this case as the histogram is only | |
| 150 // supposed to measure the state of newly-observed SCTs, not pending ones. | |
| 151 histograms.ExpectTotalCount(kCanCheckForInclusionHistogramName, 0); | |
| 135 } | 152 } |
| 136 | 153 |
| 137 // Test that the SingleTreeTracker does not change an SCT's status if an STH | 154 // Test that the SingleTreeTracker does not change an SCT's status if an STH |
| 138 // from the log it was issued by is observed, but that STH is too old to check | 155 // from the log it was issued by is observed, but that STH is too old to check |
| 139 // inclusion against. | 156 // inclusion against. |
| 140 TEST_F(SingleTreeTrackerTest, DoesNotUpdatesSCTStatusOnOldSTH) { | 157 TEST_F(SingleTreeTrackerTest, DoesNotUpdatesSCTStatusOnOldSTH) { |
| 141 // Notify of an SCT and make sure it's in the 'pending newer STH' state. | 158 // Notify of an SCT and make sure it's in the 'pending newer STH' state. |
| 142 tree_tracker_->OnSCTVerified(chain_.get(), cert_sct_.get()); | 159 tree_tracker_->OnSCTVerified(chain_.get(), cert_sct_.get()); |
| 143 EXPECT_EQ( | 160 EXPECT_EQ( |
| 144 SingleTreeTracker::SCT_PENDING_NEWER_STH, | 161 SingleTreeTracker::SCT_PENDING_NEWER_STH, |
| 145 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); | 162 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); |
| 146 | 163 |
| 147 // Provide an old STH for the same log. | 164 // Provide an old STH for the same log. |
| 148 net::ct::SignedTreeHead sth; | 165 net::ct::SignedTreeHead sth; |
| 149 GetOldSignedTreeHead(&sth); | 166 GetOldSignedTreeHead(&sth); |
| 150 tree_tracker_->NewSTHObserved(sth); | 167 tree_tracker_->NewSTHObserved(sth); |
| 151 | 168 |
| 152 // Make sure the SCT's state hasn't changed. | 169 // Make sure the SCT's state hasn't changed. |
| 153 EXPECT_EQ( | 170 EXPECT_EQ( |
| 154 SingleTreeTracker::SCT_PENDING_NEWER_STH, | 171 SingleTreeTracker::SCT_PENDING_NEWER_STH, |
| 155 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); | 172 tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get())); |
| 156 } | 173 } |
| 157 | 174 |
| 175 // Test that the SingleTreeTracker correctly logs that an SCT is pending a new | |
| 176 // STH when it has STH but the observed SCT is newer than that. | |
|
Ryan Sleevi
2016/07/20 20:34:00
"than that" is ambiguous.
grammatically, this rea
Eran Messeri
2016/07/21 17:53:43
Re-worded the comment a bit, removed 'than that' a
| |
| 177 TEST_F(SingleTreeTrackerTest, LogsUMAForNewSCTAndOldSTH) { | |
| 178 base::HistogramTester histograms; | |
| 179 // Provide an old STH for the same log. | |
| 180 net::ct::SignedTreeHead sth; | |
| 181 GetOldSignedTreeHead(&sth); | |
| 182 tree_tracker_->NewSTHObserved(sth); | |
| 183 | |
| 184 histograms.ExpectTotalCount(kCanCheckForInclusionHistogramName, 0); | |
| 185 // Notify of an SCT and make sure it's in the 'pending newer STH' state. | |
| 186 tree_tracker_->OnSCTVerified(chain_.get(), cert_sct_.get()); | |
|
Ryan Sleevi
2016/07/20 20:34:00
newline between 184-185 and 186-187
Eran Messeri
2016/07/21 17:53:43
Done.
| |
| 187 // Exactly one value should be logged, indicating the SCT cannot be checked | |
| 188 // for inclusion as the STH is too old. | |
| 189 histograms.ExpectTotalCount(kCanCheckForInclusionHistogramName, 1); | |
| 190 histograms.ExpectBucketCount(kCanCheckForInclusionHistogramName, false, 1); | |
| 191 } | |
| 192 | |
| 158 } // namespace certificate_transparency | 193 } // namespace certificate_transparency |
| OLD | NEW |