| 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 <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 class MultiLogCTVerifierTest : public ::testing::Test { | 38 class MultiLogCTVerifierTest : public ::testing::Test { |
| 39 public: | 39 public: |
| 40 virtual void SetUp() OVERRIDE { | 40 virtual void SetUp() OVERRIDE { |
| 41 scoped_ptr<CTLogVerifier> log( | 41 scoped_ptr<CTLogVerifier> log( |
| 42 CTLogVerifier::Create(ct::GetTestPublicKey(), kLogDescription)); | 42 CTLogVerifier::Create(ct::GetTestPublicKey(), kLogDescription)); |
| 43 ASSERT_TRUE(log); | 43 ASSERT_TRUE(log); |
| 44 | 44 |
| 45 verifier_.reset(new MultiLogCTVerifier()); | 45 verifier_.reset(new MultiLogCTVerifier()); |
| 46 verifier_->AddLog(log.Pass()); | 46 verifier_->AddLog(log.Pass()); |
| 47 std::string der_test_cert(ct::GetDerEncodedX509Cert()); | 47 std::string der_test_cert(ct::GetDerEncodedX509Cert()); |
| 48 chain_ = X509Certificate::CreateFromBytes( | 48 chain_ = X509Certificate::CreateFromBytes(der_test_cert.data(), |
| 49 der_test_cert.data(), | 49 der_test_cert.length()); |
| 50 der_test_cert.length()); | |
| 51 ASSERT_TRUE(chain_); | 50 ASSERT_TRUE(chain_); |
| 52 | 51 |
| 53 embedded_sct_chain_ = | 52 embedded_sct_chain_ = |
| 54 CreateCertificateChainFromFile(GetTestCertsDirectory(), | 53 CreateCertificateChainFromFile(GetTestCertsDirectory(), |
| 55 "ct-test-embedded-cert.pem", | 54 "ct-test-embedded-cert.pem", |
| 56 X509Certificate::FORMAT_AUTO); | 55 X509Certificate::FORMAT_AUTO); |
| 57 ASSERT_TRUE(embedded_sct_chain_); | 56 ASSERT_TRUE(embedded_sct_chain_); |
| 58 } | 57 } |
| 59 | 58 |
| 60 bool CheckForSingleVerifiedSCTInResult(const ct::CTVerifyResult& result) { | 59 bool CheckForSingleVerifiedSCTInResult(const ct::CTVerifyResult& result) { |
| 61 return (result.verified_scts.size() == 1U) && | 60 return (result.verified_scts.size() == 1U) && result.invalid_scts.empty() && |
| 62 result.invalid_scts.empty() && | 61 result.unknown_logs_scts.empty() && |
| 63 result.unknown_logs_scts.empty() && | 62 result.verified_scts[0]->log_description == kLogDescription; |
| 64 result.verified_scts[0]->log_description == kLogDescription; | |
| 65 } | 63 } |
| 66 | 64 |
| 67 bool CheckForSCTOrigin( | 65 bool CheckForSCTOrigin(const ct::CTVerifyResult& result, |
| 68 const ct::CTVerifyResult& result, | 66 ct::SignedCertificateTimestamp::Origin origin) { |
| 69 ct::SignedCertificateTimestamp::Origin origin) { | |
| 70 return (result.verified_scts.size() > 0) && | 67 return (result.verified_scts.size() > 0) && |
| 71 (result.verified_scts[0]->origin == origin); | 68 (result.verified_scts[0]->origin == origin); |
| 72 } | 69 } |
| 73 | 70 |
| 74 bool CheckForEmbeddedSCTInNetLog(CapturingNetLog& net_log) { | 71 bool CheckForEmbeddedSCTInNetLog(CapturingNetLog& net_log) { |
| 75 CapturingNetLog::CapturedEntryList entries; | 72 CapturingNetLog::CapturedEntryList entries; |
| 76 net_log.GetEntries(&entries); | 73 net_log.GetEntries(&entries); |
| 77 if (entries.size() != 2) | 74 if (entries.size() != 2) |
| 78 return false; | 75 return false; |
| 79 | 76 |
| 80 const CapturingNetLog::CapturedEntry& received = entries[0]; | 77 const CapturingNetLog::CapturedEntry& received = entries[0]; |
| 81 std::string embedded_scts; | 78 std::string embedded_scts; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 | 140 |
| 144 return verifier_->Verify( | 141 return verifier_->Verify( |
| 145 chain, std::string(), std::string(), &result, bound_net_log) == | 142 chain, std::string(), std::string(), &result, bound_net_log) == |
| 146 OK; | 143 OK; |
| 147 } | 144 } |
| 148 | 145 |
| 149 bool CheckPrecertificateVerification(scoped_refptr<X509Certificate> chain) { | 146 bool CheckPrecertificateVerification(scoped_refptr<X509Certificate> chain) { |
| 150 ct::CTVerifyResult result; | 147 ct::CTVerifyResult result; |
| 151 CapturingNetLog net_log; | 148 CapturingNetLog net_log; |
| 152 BoundNetLog bound_net_log = | 149 BoundNetLog bound_net_log = |
| 153 BoundNetLog::Make(&net_log, NetLog::SOURCE_CONNECT_JOB); | 150 BoundNetLog::Make(&net_log, NetLog::SOURCE_CONNECT_JOB); |
| 154 return (VerifySinglePrecertificateChain(chain, bound_net_log, &result) && | 151 return (VerifySinglePrecertificateChain(chain, bound_net_log, &result) && |
| 155 CheckForSingleVerifiedSCTInResult(result) && | 152 CheckForSingleVerifiedSCTInResult(result) && |
| 156 CheckForSCTOrigin(result, | 153 CheckForSCTOrigin(result, |
| 157 ct::SignedCertificateTimestamp::SCT_EMBEDDED) && | 154 ct::SignedCertificateTimestamp::SCT_EMBEDDED) && |
| 158 CheckForEmbeddedSCTInNetLog(net_log)); | 155 CheckForEmbeddedSCTInNetLog(net_log)); |
| 159 } | 156 } |
| 160 | 157 |
| 161 // Histogram-related helper methods | 158 // Histogram-related helper methods |
| 162 int GetValueFromHistogram(std::string histogram_name, int sample_index) { | 159 int GetValueFromHistogram(std::string histogram_name, int sample_index) { |
| 163 base::Histogram* histogram = static_cast<base::Histogram*>( | 160 base::Histogram* histogram = static_cast<base::Histogram*>( |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 | 202 |
| 206 TEST_F(MultiLogCTVerifierTest, VerifiesEmbeddedSCTWithIntermediate) { | 203 TEST_F(MultiLogCTVerifierTest, VerifiesEmbeddedSCTWithIntermediate) { |
| 207 scoped_refptr<X509Certificate> chain(CreateCertificateChainFromFile( | 204 scoped_refptr<X509Certificate> chain(CreateCertificateChainFromFile( |
| 208 GetTestCertsDirectory(), | 205 GetTestCertsDirectory(), |
| 209 "ct-test-embedded-with-intermediate-chain.pem", | 206 "ct-test-embedded-with-intermediate-chain.pem", |
| 210 X509Certificate::FORMAT_AUTO)); | 207 X509Certificate::FORMAT_AUTO)); |
| 211 ASSERT_TRUE(chain); | 208 ASSERT_TRUE(chain); |
| 212 ASSERT_TRUE(CheckPrecertificateVerification(chain)); | 209 ASSERT_TRUE(CheckPrecertificateVerification(chain)); |
| 213 } | 210 } |
| 214 | 211 |
| 215 TEST_F(MultiLogCTVerifierTest, | 212 TEST_F(MultiLogCTVerifierTest, VerifiesEmbeddedSCTWithIntermediateAndPreCA) { |
| 216 VerifiesEmbeddedSCTWithIntermediateAndPreCA) { | |
| 217 scoped_refptr<X509Certificate> chain(CreateCertificateChainFromFile( | 213 scoped_refptr<X509Certificate> chain(CreateCertificateChainFromFile( |
| 218 GetTestCertsDirectory(), | 214 GetTestCertsDirectory(), |
| 219 "ct-test-embedded-with-intermediate-preca-chain.pem", | 215 "ct-test-embedded-with-intermediate-preca-chain.pem", |
| 220 X509Certificate::FORMAT_AUTO)); | 216 X509Certificate::FORMAT_AUTO)); |
| 221 ASSERT_TRUE(chain); | 217 ASSERT_TRUE(chain); |
| 222 ASSERT_TRUE(CheckPrecertificateVerification(chain)); | 218 ASSERT_TRUE(CheckPrecertificateVerification(chain)); |
| 223 } | 219 } |
| 224 | 220 |
| 225 TEST_F(MultiLogCTVerifierTest, | 221 TEST_F(MultiLogCTVerifierTest, VerifiesSCTOverX509Cert) { |
| 226 VerifiesSCTOverX509Cert) { | |
| 227 std::string sct(ct::GetTestSignedCertificateTimestamp()); | 222 std::string sct(ct::GetTestSignedCertificateTimestamp()); |
| 228 | 223 |
| 229 std::string sct_list; | 224 std::string sct_list; |
| 230 ASSERT_TRUE(ct::EncodeSCTListForTesting(sct, &sct_list)); | 225 ASSERT_TRUE(ct::EncodeSCTListForTesting(sct, &sct_list)); |
| 231 | 226 |
| 232 ct::CTVerifyResult result; | 227 ct::CTVerifyResult result; |
| 233 EXPECT_EQ(OK, | 228 EXPECT_EQ(OK, |
| 234 verifier_->Verify(chain_, std::string(), sct_list, &result, | 229 verifier_->Verify( |
| 235 BoundNetLog())); | 230 chain_, std::string(), sct_list, &result, BoundNetLog())); |
| 236 ASSERT_TRUE(CheckForSingleVerifiedSCTInResult(result)); | 231 ASSERT_TRUE(CheckForSingleVerifiedSCTInResult(result)); |
| 237 ASSERT_TRUE(CheckForSCTOrigin( | 232 ASSERT_TRUE(CheckForSCTOrigin( |
| 238 result, ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION)); | 233 result, ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION)); |
| 239 } | 234 } |
| 240 | 235 |
| 241 TEST_F(MultiLogCTVerifierTest, | 236 TEST_F(MultiLogCTVerifierTest, IdentifiesSCTFromUnknownLog) { |
| 242 IdentifiesSCTFromUnknownLog) { | |
| 243 std::string sct_list = GetSCTListWithInvalidSCT(); | 237 std::string sct_list = GetSCTListWithInvalidSCT(); |
| 244 ct::CTVerifyResult result; | 238 ct::CTVerifyResult result; |
| 245 | 239 |
| 246 EXPECT_NE(OK, | 240 EXPECT_NE(OK, |
| 247 verifier_->Verify( | 241 verifier_->Verify( |
| 248 chain_, std::string(), sct_list, &result, BoundNetLog())); | 242 chain_, std::string(), sct_list, &result, BoundNetLog())); |
| 249 EXPECT_EQ(1U, result.unknown_logs_scts.size()); | 243 EXPECT_EQ(1U, result.unknown_logs_scts.size()); |
| 250 EXPECT_EQ("", result.unknown_logs_scts[0]->log_description); | 244 EXPECT_EQ("", result.unknown_logs_scts[0]->log_description); |
| 251 } | 245 } |
| 252 | 246 |
| 253 TEST_F(MultiLogCTVerifierTest, CountsValidSCTsInStatusHistogram) { | 247 TEST_F(MultiLogCTVerifierTest, CountsValidSCTsInStatusHistogram) { |
| 254 int num_valid_scts = NumValidSCTsInStatusHistogram(); | 248 int num_valid_scts = NumValidSCTsInStatusHistogram(); |
| 255 | 249 |
| 256 ASSERT_TRUE(VerifySinglePrecertificateChain(embedded_sct_chain_)); | 250 ASSERT_TRUE(VerifySinglePrecertificateChain(embedded_sct_chain_)); |
| 257 | 251 |
| 258 EXPECT_EQ(num_valid_scts + 1, NumValidSCTsInStatusHistogram()); | 252 EXPECT_EQ(num_valid_scts + 1, NumValidSCTsInStatusHistogram()); |
| 259 } | 253 } |
| 260 | 254 |
| 261 TEST_F(MultiLogCTVerifierTest, CountsInvalidSCTsInStatusHistogram) { | 255 TEST_F(MultiLogCTVerifierTest, CountsInvalidSCTsInStatusHistogram) { |
| 262 std::string sct_list = GetSCTListWithInvalidSCT(); | 256 std::string sct_list = GetSCTListWithInvalidSCT(); |
| 263 ct::CTVerifyResult result; | 257 ct::CTVerifyResult result; |
| 264 int num_valid_scts = NumValidSCTsInStatusHistogram(); | 258 int num_valid_scts = NumValidSCTsInStatusHistogram(); |
| 265 int num_invalid_scts = GetValueFromHistogram( | 259 int num_invalid_scts = GetValueFromHistogram( |
| 266 "Net.CertificateTransparency.SCTStatus", ct::SCT_STATUS_LOG_UNKNOWN); | 260 "Net.CertificateTransparency.SCTStatus", ct::SCT_STATUS_LOG_UNKNOWN); |
| 267 | 261 |
| 268 EXPECT_NE(OK, | 262 EXPECT_NE(OK, |
| 269 verifier_->Verify(chain_, std::string(), sct_list, &result, | 263 verifier_->Verify( |
| 270 BoundNetLog())); | 264 chain_, std::string(), sct_list, &result, BoundNetLog())); |
| 271 | 265 |
| 272 ASSERT_EQ(num_valid_scts, NumValidSCTsInStatusHistogram()); | 266 ASSERT_EQ(num_valid_scts, NumValidSCTsInStatusHistogram()); |
| 273 ASSERT_EQ(num_invalid_scts + 1, | 267 ASSERT_EQ(num_invalid_scts + 1, |
| 274 GetValueFromHistogram("Net.CertificateTransparency.SCTStatus", | 268 GetValueFromHistogram("Net.CertificateTransparency.SCTStatus", |
| 275 ct::SCT_STATUS_LOG_UNKNOWN)); | 269 ct::SCT_STATUS_LOG_UNKNOWN)); |
| 276 } | 270 } |
| 277 | 271 |
| 278 TEST_F(MultiLogCTVerifierTest, CountsSingleEmbeddedSCTInConnectionsHistogram) { | 272 TEST_F(MultiLogCTVerifierTest, CountsSingleEmbeddedSCTInConnectionsHistogram) { |
| 279 int old_sct_count = NumConnectionsWithSingleSCT(); | 273 int old_sct_count = NumConnectionsWithSingleSCT(); |
| 280 ASSERT_TRUE(CheckPrecertificateVerification(embedded_sct_chain_)); | 274 ASSERT_TRUE(CheckPrecertificateVerification(embedded_sct_chain_)); |
| 281 EXPECT_EQ(old_sct_count + 1, NumConnectionsWithSingleSCT()); | 275 EXPECT_EQ(old_sct_count + 1, NumConnectionsWithSingleSCT()); |
| 282 } | 276 } |
| 283 | 277 |
| 284 TEST_F(MultiLogCTVerifierTest, CountsSingleEmbeddedSCTInOriginsHistogram) { | 278 TEST_F(MultiLogCTVerifierTest, CountsSingleEmbeddedSCTInOriginsHistogram) { |
| 285 int old_embedded_count = NumEmbeddedSCTsInHistogram(); | 279 int old_embedded_count = NumEmbeddedSCTsInHistogram(); |
| 286 ASSERT_TRUE(CheckPrecertificateVerification(embedded_sct_chain_)); | 280 ASSERT_TRUE(CheckPrecertificateVerification(embedded_sct_chain_)); |
| 287 EXPECT_EQ(old_embedded_count + 1, NumEmbeddedSCTsInHistogram()); | 281 EXPECT_EQ(old_embedded_count + 1, NumEmbeddedSCTsInHistogram()); |
| 288 } | 282 } |
| 289 | 283 |
| 290 TEST_F(MultiLogCTVerifierTest, CountsZeroSCTsCorrectly) { | 284 TEST_F(MultiLogCTVerifierTest, CountsZeroSCTsCorrectly) { |
| 291 int connections_without_scts = GetValueFromHistogram(kSCTCountHistogram, 0); | 285 int connections_without_scts = GetValueFromHistogram(kSCTCountHistogram, 0); |
| 292 EXPECT_FALSE(VerifySinglePrecertificateChain(chain_)); | 286 EXPECT_FALSE(VerifySinglePrecertificateChain(chain_)); |
| 293 ASSERT_EQ(connections_without_scts + 1, | 287 ASSERT_EQ(connections_without_scts + 1, |
| 294 GetValueFromHistogram(kSCTCountHistogram, 0)); | 288 GetValueFromHistogram(kSCTCountHistogram, 0)); |
| 295 } | 289 } |
| 296 | 290 |
| 297 } // namespace | 291 } // namespace |
| 298 | 292 |
| 299 } // namespace net | 293 } // namespace net |
| OLD | NEW |