| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "net/cert/multi_log_ct_verifier.h" | 5 #include "net/cert/multi_log_ct_verifier.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| 11 #include "base/files/file_util.h" | 11 #include "base/files/file_util.h" |
| 12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 13 #include "base/metrics/histogram_samples.h" | 13 #include "base/metrics/histogram_samples.h" |
| 14 #include "base/metrics/statistics_recorder.h" | 14 #include "base/metrics/statistics_recorder.h" |
| 15 #include "base/values.h" | 15 #include "base/values.h" |
| 16 #include "net/base/net_errors.h" | 16 #include "net/base/net_errors.h" |
| 17 #include "net/cert/ct_log_verifier.h" | 17 #include "net/cert/ct_log_verifier.h" |
| 18 #include "net/cert/ct_serialization.h" | 18 #include "net/cert/ct_serialization.h" |
| 19 #include "net/cert/ct_verify_result.h" | |
| 20 #include "net/cert/pem_tokenizer.h" | 19 #include "net/cert/pem_tokenizer.h" |
| 21 #include "net/cert/sct_status_flags.h" | 20 #include "net/cert/sct_status_flags.h" |
| 22 #include "net/cert/signed_certificate_timestamp.h" | 21 #include "net/cert/signed_certificate_timestamp.h" |
| 22 #include "net/cert/signed_certificate_timestamp_and_status.h" |
| 23 #include "net/cert/x509_certificate.h" | 23 #include "net/cert/x509_certificate.h" |
| 24 #include "net/log/net_log_source_type.h" | 24 #include "net/log/net_log_source_type.h" |
| 25 #include "net/log/net_log_with_source.h" | 25 #include "net/log/net_log_with_source.h" |
| 26 #include "net/log/test_net_log.h" | 26 #include "net/log/test_net_log.h" |
| 27 #include "net/log/test_net_log_entry.h" | 27 #include "net/log/test_net_log_entry.h" |
| 28 #include "net/test/cert_test_util.h" | 28 #include "net/test/cert_test_util.h" |
| 29 #include "net/test/ct_test_util.h" | 29 #include "net/test/ct_test_util.h" |
| 30 #include "net/test/test_data_directory.h" | 30 #include "net/test/test_data_directory.h" |
| 31 #include "testing/gmock/include/gmock/gmock.h" | 31 #include "testing/gmock/include/gmock/gmock.h" |
| 32 #include "testing/gtest/include/gtest/gtest.h" | 32 #include "testing/gtest/include/gtest/gtest.h" |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 104 | 104 |
| 105 std::string verification_status; | 105 std::string verification_status; |
| 106 if (!the_sct->GetString("verification_status", &verification_status)) | 106 if (!the_sct->GetString("verification_status", &verification_status)) |
| 107 return false; | 107 return false; |
| 108 if (verification_status != "Verified") | 108 if (verification_status != "Verified") |
| 109 return false; | 109 return false; |
| 110 | 110 |
| 111 return true; | 111 return true; |
| 112 } | 112 } |
| 113 | 113 |
| 114 bool VerifySinglePrecertificateChain(scoped_refptr<X509Certificate> chain, | 114 bool VerifySinglePrecertificateChain( |
| 115 const NetLogWithSource& net_log, | 115 scoped_refptr<X509Certificate> chain, |
| 116 ct::CTVerifyResult* result) { | 116 const NetLogWithSource& net_log, |
| 117 return verifier_->Verify(chain.get(), std::string(), std::string(), result, | 117 SignedCertificateTimestampAndStatusList* output_scts) { |
| 118 net_log) == OK; | 118 return verifier_->Verify(chain.get(), std::string(), std::string(), |
| 119 output_scts, net_log) == OK; |
| 119 } | 120 } |
| 120 | 121 |
| 121 bool VerifySinglePrecertificateChain(scoped_refptr<X509Certificate> chain) { | 122 bool VerifySinglePrecertificateChain(scoped_refptr<X509Certificate> chain) { |
| 122 ct::CTVerifyResult result; | 123 SignedCertificateTimestampAndStatusList scts; |
| 123 TestNetLog test_net_log; | 124 TestNetLog test_net_log; |
| 124 NetLogWithSource net_log = | 125 NetLogWithSource net_log = |
| 125 NetLogWithSource::Make(&test_net_log, NetLogSourceType::CONNECT_JOB); | 126 NetLogWithSource::Make(&test_net_log, NetLogSourceType::CONNECT_JOB); |
| 126 | 127 |
| 127 return verifier_->Verify(chain.get(), std::string(), std::string(), &result, | 128 return verifier_->Verify(chain.get(), std::string(), std::string(), &scts, |
| 128 net_log) == OK; | 129 net_log) == OK; |
| 129 } | 130 } |
| 130 | 131 |
| 131 bool CheckPrecertificateVerification(scoped_refptr<X509Certificate> chain) { | 132 bool CheckPrecertificateVerification(scoped_refptr<X509Certificate> chain) { |
| 132 ct::CTVerifyResult result; | 133 SignedCertificateTimestampAndStatusList scts; |
| 133 TestNetLog test_net_log; | 134 TestNetLog test_net_log; |
| 134 NetLogWithSource net_log = | 135 NetLogWithSource net_log = |
| 135 NetLogWithSource::Make(&test_net_log, NetLogSourceType::CONNECT_JOB); | 136 NetLogWithSource::Make(&test_net_log, NetLogSourceType::CONNECT_JOB); |
| 136 return (VerifySinglePrecertificateChain(chain, net_log, &result) && | 137 return (VerifySinglePrecertificateChain(chain, net_log, &scts) && |
| 137 ct::CheckForSingleVerifiedSCTInResult(result, kLogDescription) && | 138 ct::CheckForSingleVerifiedSCTInResult(scts, kLogDescription) && |
| 138 ct::CheckForSCTOrigin( | 139 ct::CheckForSCTOrigin( |
| 139 result, ct::SignedCertificateTimestamp::SCT_EMBEDDED) && | 140 scts, ct::SignedCertificateTimestamp::SCT_EMBEDDED) && |
| 140 CheckForEmbeddedSCTInNetLog(test_net_log)); | 141 CheckForEmbeddedSCTInNetLog(test_net_log)); |
| 141 } | 142 } |
| 142 | 143 |
| 143 // Histogram-related helper methods | 144 // Histogram-related helper methods |
| 144 int GetValueFromHistogram(const std::string& histogram_name, | 145 int GetValueFromHistogram(const std::string& histogram_name, |
| 145 int sample_index) { | 146 int sample_index) { |
| 146 base::Histogram* histogram = static_cast<base::Histogram*>( | 147 base::Histogram* histogram = static_cast<base::Histogram*>( |
| 147 base::StatisticsRecorder::FindHistogram(histogram_name)); | 148 base::StatisticsRecorder::FindHistogram(histogram_name)); |
| 148 | 149 |
| 149 if (histogram == NULL) | 150 if (histogram == NULL) |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 GetTestCertsDirectory(), | 204 GetTestCertsDirectory(), |
| 204 "ct-test-embedded-with-intermediate-preca-chain.pem", | 205 "ct-test-embedded-with-intermediate-preca-chain.pem", |
| 205 X509Certificate::FORMAT_AUTO)); | 206 X509Certificate::FORMAT_AUTO)); |
| 206 ASSERT_TRUE(chain.get()); | 207 ASSERT_TRUE(chain.get()); |
| 207 ASSERT_TRUE(CheckPrecertificateVerification(chain)); | 208 ASSERT_TRUE(CheckPrecertificateVerification(chain)); |
| 208 } | 209 } |
| 209 | 210 |
| 210 TEST_F(MultiLogCTVerifierTest, VerifiesSCTOverX509Cert) { | 211 TEST_F(MultiLogCTVerifierTest, VerifiesSCTOverX509Cert) { |
| 211 std::string sct_list = ct::GetSCTListForTesting(); | 212 std::string sct_list = ct::GetSCTListForTesting(); |
| 212 | 213 |
| 213 ct::CTVerifyResult result; | 214 SignedCertificateTimestampAndStatusList scts; |
| 214 EXPECT_EQ(OK, verifier_->Verify(chain_.get(), std::string(), sct_list, | 215 EXPECT_EQ(OK, verifier_->Verify(chain_.get(), std::string(), sct_list, &scts, |
| 215 &result, NetLogWithSource())); | 216 NetLogWithSource())); |
| 216 ASSERT_TRUE(ct::CheckForSingleVerifiedSCTInResult(result, kLogDescription)); | 217 ASSERT_TRUE(ct::CheckForSingleVerifiedSCTInResult(scts, kLogDescription)); |
| 217 ASSERT_TRUE(ct::CheckForSCTOrigin( | 218 ASSERT_TRUE(ct::CheckForSCTOrigin( |
| 218 result, ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION)); | 219 scts, ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION)); |
| 219 } | 220 } |
| 220 | 221 |
| 221 TEST_F(MultiLogCTVerifierTest, IdentifiesSCTFromUnknownLog) { | 222 TEST_F(MultiLogCTVerifierTest, IdentifiesSCTFromUnknownLog) { |
| 222 std::string sct_list = ct::GetSCTListWithInvalidSCT(); | 223 std::string sct_list = ct::GetSCTListWithInvalidSCT(); |
| 223 ct::CTVerifyResult result; | 224 SignedCertificateTimestampAndStatusList scts; |
| 224 | 225 |
| 225 EXPECT_NE(OK, verifier_->Verify(chain_.get(), std::string(), sct_list, | 226 EXPECT_NE(OK, verifier_->Verify(chain_.get(), std::string(), sct_list, &scts, |
| 226 &result, NetLogWithSource())); | 227 NetLogWithSource())); |
| 227 EXPECT_EQ(1U, result.scts.size()); | 228 EXPECT_EQ(1U, scts.size()); |
| 228 EXPECT_EQ("", result.scts[0].sct->log_description); | 229 EXPECT_EQ("", scts[0].sct->log_description); |
| 229 EXPECT_EQ(ct::SCT_STATUS_LOG_UNKNOWN, result.scts[0].status); | 230 EXPECT_EQ(ct::SCT_STATUS_LOG_UNKNOWN, scts[0].status); |
| 230 } | 231 } |
| 231 | 232 |
| 232 TEST_F(MultiLogCTVerifierTest, CountsValidSCTsInStatusHistogram) { | 233 TEST_F(MultiLogCTVerifierTest, CountsValidSCTsInStatusHistogram) { |
| 233 int num_valid_scts = NumValidSCTsInStatusHistogram(); | 234 int num_valid_scts = NumValidSCTsInStatusHistogram(); |
| 234 | 235 |
| 235 ASSERT_TRUE(VerifySinglePrecertificateChain(embedded_sct_chain_)); | 236 ASSERT_TRUE(VerifySinglePrecertificateChain(embedded_sct_chain_)); |
| 236 | 237 |
| 237 EXPECT_EQ(num_valid_scts + 1, NumValidSCTsInStatusHistogram()); | 238 EXPECT_EQ(num_valid_scts + 1, NumValidSCTsInStatusHistogram()); |
| 238 } | 239 } |
| 239 | 240 |
| 240 TEST_F(MultiLogCTVerifierTest, CountsInvalidSCTsInStatusHistogram) { | 241 TEST_F(MultiLogCTVerifierTest, CountsInvalidSCTsInStatusHistogram) { |
| 241 std::string sct_list = ct::GetSCTListWithInvalidSCT(); | 242 std::string sct_list = ct::GetSCTListWithInvalidSCT(); |
| 242 ct::CTVerifyResult result; | 243 SignedCertificateTimestampAndStatusList scts; |
| 244 |
| 243 int num_valid_scts = NumValidSCTsInStatusHistogram(); | 245 int num_valid_scts = NumValidSCTsInStatusHistogram(); |
| 244 int num_invalid_scts = GetValueFromHistogram( | 246 int num_invalid_scts = GetValueFromHistogram( |
| 245 "Net.CertificateTransparency.SCTStatus", ct::SCT_STATUS_LOG_UNKNOWN); | 247 "Net.CertificateTransparency.SCTStatus", ct::SCT_STATUS_LOG_UNKNOWN); |
| 246 | 248 |
| 247 EXPECT_NE(OK, verifier_->Verify(chain_.get(), std::string(), sct_list, | 249 EXPECT_NE(OK, verifier_->Verify(chain_.get(), std::string(), sct_list, &scts, |
| 248 &result, NetLogWithSource())); | 250 NetLogWithSource())); |
| 249 | 251 |
| 250 ASSERT_EQ(num_valid_scts, NumValidSCTsInStatusHistogram()); | 252 ASSERT_EQ(num_valid_scts, NumValidSCTsInStatusHistogram()); |
| 251 ASSERT_EQ(num_invalid_scts + 1, | 253 ASSERT_EQ(num_invalid_scts + 1, |
| 252 GetValueFromHistogram("Net.CertificateTransparency.SCTStatus", | 254 GetValueFromHistogram("Net.CertificateTransparency.SCTStatus", |
| 253 ct::SCT_STATUS_LOG_UNKNOWN)); | 255 ct::SCT_STATUS_LOG_UNKNOWN)); |
| 254 } | 256 } |
| 255 | 257 |
| 256 TEST_F(MultiLogCTVerifierTest, CountsSingleEmbeddedSCTInConnectionsHistogram) { | 258 TEST_F(MultiLogCTVerifierTest, CountsSingleEmbeddedSCTInConnectionsHistogram) { |
| 257 int old_sct_count = NumConnectionsWithSingleSCT(); | 259 int old_sct_count = NumConnectionsWithSingleSCT(); |
| 258 ASSERT_TRUE(CheckPrecertificateVerification(embedded_sct_chain_)); | 260 ASSERT_TRUE(CheckPrecertificateVerification(embedded_sct_chain_)); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 289 Mock::VerifyAndClearExpectations(&observer); | 291 Mock::VerifyAndClearExpectations(&observer); |
| 290 | 292 |
| 291 EXPECT_CALL(observer, OnSCTVerified(embedded_sct_chain_.get(), _)).Times(0); | 293 EXPECT_CALL(observer, OnSCTVerified(embedded_sct_chain_.get(), _)).Times(0); |
| 292 verifier_->SetObserver(nullptr); | 294 verifier_->SetObserver(nullptr); |
| 293 ASSERT_TRUE(VerifySinglePrecertificateChain(embedded_sct_chain_)); | 295 ASSERT_TRUE(VerifySinglePrecertificateChain(embedded_sct_chain_)); |
| 294 } | 296 } |
| 295 | 297 |
| 296 } // namespace | 298 } // namespace |
| 297 | 299 |
| 298 } // namespace net | 300 } // namespace net |
| OLD | NEW |