| 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 26 matching lines...) Expand all Loading... |
| 37 | 37 |
| 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 verifier_->SetEnforceCTEVPolicy(true); |
| 47 std::string der_test_cert(ct::GetDerEncodedX509Cert()); | 48 std::string der_test_cert(ct::GetDerEncodedX509Cert()); |
| 48 chain_ = X509Certificate::CreateFromBytes( | 49 chain_ = X509Certificate::CreateFromBytes( |
| 49 der_test_cert.data(), | 50 der_test_cert.data(), |
| 50 der_test_cert.length()); | 51 der_test_cert.length()); |
| 51 ASSERT_TRUE(chain_); | 52 ASSERT_TRUE(chain_); |
| 52 | 53 |
| 53 embedded_sct_chain_ = | 54 embedded_sct_chain_ = |
| 54 CreateCertificateChainFromFile(GetTestCertsDirectory(), | 55 CreateCertificateChainFromFile(GetTestCertsDirectory(), |
| 55 "ct-test-embedded-cert.pem", | 56 "ct-test-embedded-cert.pem", |
| 56 X509Certificate::FORMAT_AUTO); | 57 X509Certificate::FORMAT_AUTO); |
| 57 ASSERT_TRUE(embedded_sct_chain_); | 58 ASSERT_TRUE(embedded_sct_chain_); |
| 58 } | 59 } |
| 59 | 60 |
| 60 bool CheckForSingleVerifiedSCTInResult(const ct::CTVerifyResult& result) { | 61 bool CheckForSingleVerifiedSCTInResult(const ct::CTVerifyResult& result) { |
| 61 return (result.verified_scts.size() == 1U) && | 62 return (result.verified_scts.size() == 1U) && |
| 62 result.invalid_scts.empty() && | 63 result.invalid_scts.empty() && |
| 63 result.unknown_logs_scts.empty() && | 64 result.unknown_logs_scts.empty() && |
| 64 result.verified_scts[0]->log_description == kLogDescription; | 65 result.verified_scts[0]->log_description == kLogDescription; |
| 65 } | 66 } |
| 66 | 67 |
| 67 bool CheckForSCTOrigin( | 68 bool CheckForSCTOrigin( |
| 68 const ct::CTVerifyResult& result, | 69 const ct::CTVerifyResult& result, |
| 69 ct::SignedCertificateTimestamp::Origin origin) { | 70 ct::SignedCertificateTimestamp::Origin origin) { |
| 70 return (result.verified_scts.size() > 0) && | 71 return (result.verified_scts.size() > 0) && |
| 71 (result.verified_scts[0]->origin == origin); | 72 (result.verified_scts[0]->origin == origin); |
| 72 } | 73 } |
| 73 | 74 |
| 74 bool CheckForEmbeddedSCTInNetLog(CapturingNetLog& net_log) { | 75 bool CheckForEmbeddedSCTInNetLog(const CapturingNetLog& net_log) { |
| 75 CapturingNetLog::CapturedEntryList entries; | 76 CapturingNetLog::CapturedEntryList entries; |
| 76 net_log.GetEntries(&entries); | 77 net_log.GetEntries(&entries); |
| 77 if (entries.size() != 2) | 78 if (entries.size() != 2) |
| 78 return false; | 79 return false; |
| 79 | 80 |
| 80 const CapturingNetLog::CapturedEntry& received = entries[0]; | 81 const CapturingNetLog::CapturedEntry& received = entries[0]; |
| 81 std::string embedded_scts; | 82 std::string embedded_scts; |
| 82 if (!received.GetStringValue("embedded_scts", &embedded_scts)) | 83 if (!received.GetStringValue("embedded_scts", &embedded_scts)) |
| 83 return false; | 84 return false; |
| 84 if (embedded_scts.empty()) | 85 if (embedded_scts.empty()) |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 int NumEmbeddedSCTsInHistogram() { | 178 int NumEmbeddedSCTsInHistogram() { |
| 178 return GetValueFromHistogram("Net.CertificateTransparency.SCTOrigin", | 179 return GetValueFromHistogram("Net.CertificateTransparency.SCTOrigin", |
| 179 ct::SignedCertificateTimestamp::SCT_EMBEDDED); | 180 ct::SignedCertificateTimestamp::SCT_EMBEDDED); |
| 180 } | 181 } |
| 181 | 182 |
| 182 int NumValidSCTsInStatusHistogram() { | 183 int NumValidSCTsInStatusHistogram() { |
| 183 return GetValueFromHistogram("Net.CertificateTransparency.SCTStatus", | 184 return GetValueFromHistogram("Net.CertificateTransparency.SCTStatus", |
| 184 ct::SCT_STATUS_OK); | 185 ct::SCT_STATUS_OK); |
| 185 } | 186 } |
| 186 | 187 |
| 188 void FillResultWithSCTsOfOrigin( |
| 189 ct::SignedCertificateTimestamp::Origin desired_origin, |
| 190 int num_scts, |
| 191 ct::CTVerifyResult* result) { |
| 192 for (int i = 0; i < num_scts; ++i) { |
| 193 scoped_refptr<ct::SignedCertificateTimestamp> sct( |
| 194 new ct::SignedCertificateTimestamp()); |
| 195 sct->origin = desired_origin; |
| 196 result->verified_scts.push_back(sct); |
| 197 } |
| 198 } |
| 199 |
| 187 protected: | 200 protected: |
| 188 scoped_ptr<MultiLogCTVerifier> verifier_; | 201 scoped_ptr<MultiLogCTVerifier> verifier_; |
| 189 scoped_refptr<X509Certificate> chain_; | 202 scoped_refptr<X509Certificate> chain_; |
| 190 scoped_refptr<X509Certificate> embedded_sct_chain_; | 203 scoped_refptr<X509Certificate> embedded_sct_chain_; |
| 191 }; | 204 }; |
| 192 | 205 |
| 193 TEST_F(MultiLogCTVerifierTest, VerifiesEmbeddedSCT) { | 206 TEST_F(MultiLogCTVerifierTest, VerifiesEmbeddedSCT) { |
| 194 ASSERT_TRUE(CheckPrecertificateVerification(embedded_sct_chain_)); | 207 ASSERT_TRUE(CheckPrecertificateVerification(embedded_sct_chain_)); |
| 195 } | 208 } |
| 196 | 209 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 EXPECT_EQ(old_embedded_count + 1, NumEmbeddedSCTsInHistogram()); | 300 EXPECT_EQ(old_embedded_count + 1, NumEmbeddedSCTsInHistogram()); |
| 288 } | 301 } |
| 289 | 302 |
| 290 TEST_F(MultiLogCTVerifierTest, CountsZeroSCTsCorrectly) { | 303 TEST_F(MultiLogCTVerifierTest, CountsZeroSCTsCorrectly) { |
| 291 int connections_without_scts = GetValueFromHistogram(kSCTCountHistogram, 0); | 304 int connections_without_scts = GetValueFromHistogram(kSCTCountHistogram, 0); |
| 292 EXPECT_FALSE(VerifySinglePrecertificateChain(chain_)); | 305 EXPECT_FALSE(VerifySinglePrecertificateChain(chain_)); |
| 293 ASSERT_EQ(connections_without_scts + 1, | 306 ASSERT_EQ(connections_without_scts + 1, |
| 294 GetValueFromHistogram(kSCTCountHistogram, 0)); | 307 GetValueFromHistogram(kSCTCountHistogram, 0)); |
| 295 } | 308 } |
| 296 | 309 |
| 310 TEST_F(MultiLogCTVerifierTest, ConformsToCTEVPolicyWithNonEmbeddedSCTs) { |
| 311 ct::CTVerifyResult result; |
| 312 FillResultWithSCTsOfOrigin( |
| 313 ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION, |
| 314 2, |
| 315 &result); |
| 316 |
| 317 ASSERT_TRUE(verifier_->DoesConformToCTEVPolicy(chain_, result)); |
| 318 } |
| 319 |
| 320 TEST_F(MultiLogCTVerifierTest, ConformsToCTEVPolicyWithEmbeddedSCTs) { |
| 321 // We know that the chain_ is valid for 10 years - over 121 months - so |
| 322 // requires 5 SCTs. |
| 323 ct::CTVerifyResult result; |
| 324 FillResultWithSCTsOfOrigin( |
| 325 ct::SignedCertificateTimestamp::SCT_EMBEDDED, |
| 326 5, |
| 327 &result); |
| 328 |
| 329 ASSERT_TRUE(verifier_->DoesConformToCTEVPolicy(chain_, result)); |
| 330 } |
| 331 |
| 332 TEST_F(MultiLogCTVerifierTest, ConformsToCTEVPolicyMixedOriginSCTs) { |
| 333 ct::CTVerifyResult result; |
| 334 FillResultWithSCTsOfOrigin( |
| 335 ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION, |
| 336 2, |
| 337 &result); |
| 338 result.verified_scts[1]->origin = |
| 339 ct::SignedCertificateTimestamp::SCT_EMBEDDED; |
| 340 ASSERT_TRUE(verifier_->DoesConformToCTEVPolicy(chain_, result)); |
| 341 } |
| 342 |
| 343 TEST_F(MultiLogCTVerifierTest, DoesNotConformToCTEVPolicyNotEnoughSCTs) { |
| 344 // We know that the chain_ is valid for 10 years - over 121 months - so |
| 345 // 5 SCTs are required. However, as there are only two logs, two SCTs |
| 346 // will be required - so provide one to guarantee the test fails. |
| 347 ct::CTVerifyResult result; |
| 348 FillResultWithSCTsOfOrigin( |
| 349 ct::SignedCertificateTimestamp::SCT_EMBEDDED, |
| 350 1, |
| 351 &result); |
| 352 |
| 353 ASSERT_FALSE(verifier_->DoesConformToCTEVPolicy(chain_, result)); |
| 354 } |
| 355 |
| 356 |
| 297 } // namespace | 357 } // namespace |
| 298 | 358 |
| 299 } // namespace net | 359 } // namespace net |
| OLD | NEW |