| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/ct_policy_enforcer.h" | 5 #include "net/cert/ct_policy_enforcer.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 ct::SCTList* verified_scts) { | 74 ct::SCTList* verified_scts) { |
| 75 for (size_t i = 0; i < num_scts; ++i) { | 75 for (size_t i = 0; i < num_scts; ++i) { |
| 76 scoped_refptr<ct::SignedCertificateTimestamp> sct( | 76 scoped_refptr<ct::SignedCertificateTimestamp> sct( |
| 77 new ct::SignedCertificateTimestamp()); | 77 new ct::SignedCertificateTimestamp()); |
| 78 sct->origin = desired_origin; | 78 sct->origin = desired_origin; |
| 79 if (i < desired_log_keys.size()) | 79 if (i < desired_log_keys.size()) |
| 80 sct->log_id = desired_log_keys[i]; | 80 sct->log_id = desired_log_keys[i]; |
| 81 else | 81 else |
| 82 sct->log_id = std::string(crypto::kSHA256Length, static_cast<char>(i)); | 82 sct->log_id = std::string(crypto::kSHA256Length, static_cast<char>(i)); |
| 83 | 83 |
| 84 if (timestamp_past_enforcement_date) { | 84 if (timestamp_past_enforcement_date) |
| 85 sct->timestamp = | 85 sct->timestamp = |
| 86 base::Time::FromUTCExploded({2015, 8, 0, 15, 0, 0, 0, 0}); | 86 base::Time::FromUTCExploded({2015, 8, 0, 15, 0, 0, 0, 0}); |
| 87 } else { | 87 else |
| 88 sct->timestamp = | 88 sct->timestamp = |
| 89 base::Time::FromUTCExploded({2015, 6, 0, 15, 0, 0, 0, 0}); | 89 base::Time::FromUTCExploded({2015, 6, 0, 15, 0, 0, 0, 0}); |
| 90 } | |
| 91 | 90 |
| 92 verified_scts->push_back(sct); | 91 verified_scts->push_back(sct); |
| 93 } | 92 } |
| 94 } | 93 } |
| 95 | 94 |
| 96 void AddDisqualifiedLogSCT( | |
| 97 ct::SignedCertificateTimestamp::Origin desired_origin, | |
| 98 bool timestamp_after_disqualification_date, | |
| 99 ct::SCTList* verified_scts) { | |
| 100 static const char kCertlyLogID[] = | |
| 101 "\xcd\xb5\x17\x9b\x7f\xc1\xc0\x46\xfe\xea\x31\x13\x6a\x3f\x8f\x00\x2e" | |
| 102 "\x61\x82\xfa\xf8\x89\x6f\xec\xc8\xb2\xf5\xb5\xab\x60\x49\x00"; | |
| 103 static_assert(arraysize(kCertlyLogID) - 1 == crypto::kSHA256Length, | |
| 104 "Incorrect log ID length."); | |
| 105 | |
| 106 scoped_refptr<ct::SignedCertificateTimestamp> sct( | |
| 107 new ct::SignedCertificateTimestamp()); | |
| 108 sct->origin = desired_origin; | |
| 109 sct->log_id = std::string(kCertlyLogID, crypto::kSHA256Length); | |
| 110 if (timestamp_after_disqualification_date) { | |
| 111 sct->timestamp = | |
| 112 base::Time::FromUTCExploded({2016, 4, 0, 16, 0, 0, 0, 0}); | |
| 113 } else { | |
| 114 sct->timestamp = base::Time::FromUTCExploded({2016, 4, 0, 1, 0, 0, 0, 0}); | |
| 115 } | |
| 116 | |
| 117 verified_scts->push_back(sct); | |
| 118 } | |
| 119 | |
| 120 void FillListWithSCTsOfOrigin( | 95 void FillListWithSCTsOfOrigin( |
| 121 ct::SignedCertificateTimestamp::Origin desired_origin, | 96 ct::SignedCertificateTimestamp::Origin desired_origin, |
| 122 size_t num_scts, | 97 size_t num_scts, |
| 123 ct::SCTList* verified_scts) { | 98 ct::SCTList* verified_scts) { |
| 124 std::vector<std::string> desired_log_ids; | 99 std::vector<std::string> desired_log_ids; |
| 125 desired_log_ids.push_back(google_log_id_); | 100 desired_log_ids.push_back(google_log_id_); |
| 126 FillListWithSCTsOfOrigin(desired_origin, num_scts, desired_log_ids, true, | 101 FillListWithSCTsOfOrigin(desired_origin, num_scts, desired_log_ids, true, |
| 127 verified_scts); | 102 verified_scts); |
| 128 } | 103 } |
| 129 | 104 |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 chain_.get(), non_including_whitelist.get(), scts, BoundNetLog())); | 290 chain_.get(), non_including_whitelist.get(), scts, BoundNetLog())); |
| 316 | 291 |
| 317 // ... but should be OK if whitelisted. | 292 // ... but should be OK if whitelisted. |
| 318 scoped_refptr<ct::EVCertsWhitelist> whitelist( | 293 scoped_refptr<ct::EVCertsWhitelist> whitelist( |
| 319 new DummyEVCertsWhitelist(true, true)); | 294 new DummyEVCertsWhitelist(true, true)); |
| 320 EXPECT_EQ(ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_WHITELIST, | 295 EXPECT_EQ(ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_WHITELIST, |
| 321 policy_enforcer_->DoesConformToCTEVPolicy( | 296 policy_enforcer_->DoesConformToCTEVPolicy( |
| 322 chain_.get(), whitelist.get(), scts, BoundNetLog())); | 297 chain_.get(), whitelist.get(), scts, BoundNetLog())); |
| 323 } | 298 } |
| 324 | 299 |
| 325 TEST_F(CTPolicyEnforcerTest, DoesNotConformToCTEVPolicyNotEnoughFreshSCTs) { | |
| 326 ct::SCTList scts; | |
| 327 | |
| 328 // The results should be the same before and after disqualification, | |
| 329 // regardless of the delivery method. | |
| 330 | |
| 331 // SCT from before disqualification. | |
| 332 scts.clear(); | |
| 333 FillListWithSCTsOfOrigin( | |
| 334 ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION, 1, &scts); | |
| 335 AddDisqualifiedLogSCT(ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION, | |
| 336 false, &scts); | |
| 337 EXPECT_EQ(ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS, | |
| 338 policy_enforcer_->DoesConformToCertPolicy(chain_.get(), scts, | |
| 339 BoundNetLog())); | |
| 340 EXPECT_EQ(ct::EVPolicyCompliance::EV_POLICY_NOT_DIVERSE_SCTS, | |
| 341 policy_enforcer_->DoesConformToCTEVPolicy(chain_.get(), nullptr, | |
| 342 scts, BoundNetLog())); | |
| 343 | |
| 344 // SCT from after disqualification. | |
| 345 scts.clear(); | |
| 346 FillListWithSCTsOfOrigin( | |
| 347 ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION, 1, &scts); | |
| 348 AddDisqualifiedLogSCT(ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION, | |
| 349 true, &scts); | |
| 350 EXPECT_EQ(ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS, | |
| 351 policy_enforcer_->DoesConformToCertPolicy(chain_.get(), scts, | |
| 352 BoundNetLog())); | |
| 353 EXPECT_EQ(ct::EVPolicyCompliance::EV_POLICY_NOT_DIVERSE_SCTS, | |
| 354 policy_enforcer_->DoesConformToCTEVPolicy(chain_.get(), nullptr, | |
| 355 scts, BoundNetLog())); | |
| 356 | |
| 357 // Embedded SCT from before disqualification. | |
| 358 scts.clear(); | |
| 359 FillListWithSCTsOfOrigin( | |
| 360 ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION, 1, &scts); | |
| 361 AddDisqualifiedLogSCT(ct::SignedCertificateTimestamp::SCT_EMBEDDED, false, | |
| 362 &scts); | |
| 363 EXPECT_EQ(ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS, | |
| 364 policy_enforcer_->DoesConformToCertPolicy(chain_.get(), scts, | |
| 365 BoundNetLog())); | |
| 366 EXPECT_EQ(ct::EVPolicyCompliance::EV_POLICY_NOT_DIVERSE_SCTS, | |
| 367 policy_enforcer_->DoesConformToCTEVPolicy(chain_.get(), nullptr, | |
| 368 scts, BoundNetLog())); | |
| 369 | |
| 370 // Embedded SCT from after disqualification. | |
| 371 scts.clear(); | |
| 372 FillListWithSCTsOfOrigin( | |
| 373 ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION, 1, &scts); | |
| 374 AddDisqualifiedLogSCT(ct::SignedCertificateTimestamp::SCT_EMBEDDED, true, | |
| 375 &scts); | |
| 376 EXPECT_EQ(ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS, | |
| 377 policy_enforcer_->DoesConformToCertPolicy(chain_.get(), scts, | |
| 378 BoundNetLog())); | |
| 379 EXPECT_EQ(ct::EVPolicyCompliance::EV_POLICY_NOT_DIVERSE_SCTS, | |
| 380 policy_enforcer_->DoesConformToCTEVPolicy(chain_.get(), nullptr, | |
| 381 scts, BoundNetLog())); | |
| 382 } | |
| 383 | |
| 384 TEST_F(CTPolicyEnforcerTest, | |
| 385 ConformsWithDisqualifiedLogBeforeDisqualificationDate) { | |
| 386 ct::SCTList scts; | |
| 387 FillListWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED, 4, | |
| 388 &scts); | |
| 389 AddDisqualifiedLogSCT(ct::SignedCertificateTimestamp::SCT_EMBEDDED, false, | |
| 390 &scts); | |
| 391 | |
| 392 // |chain_| is valid for 10 years - over 121 months - so requires 5 SCTs. | |
| 393 EXPECT_EQ(ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS, | |
| 394 policy_enforcer_->DoesConformToCertPolicy(chain_.get(), scts, | |
| 395 BoundNetLog())); | |
| 396 EXPECT_EQ(ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS, | |
| 397 policy_enforcer_->DoesConformToCTEVPolicy(chain_.get(), nullptr, | |
| 398 scts, BoundNetLog())); | |
| 399 } | |
| 400 | |
| 401 TEST_F(CTPolicyEnforcerTest, | |
| 402 DoesNotConformWithDisqualifiedLogAfterDisqualificationDate) { | |
| 403 ct::SCTList scts; | |
| 404 FillListWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED, 4, | |
| 405 &scts); | |
| 406 AddDisqualifiedLogSCT(ct::SignedCertificateTimestamp::SCT_EMBEDDED, true, | |
| 407 &scts); | |
| 408 | |
| 409 // |chain_| is valid for 10 years - over 121 months - so requires 5 SCTs. | |
| 410 EXPECT_EQ(ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS, | |
| 411 policy_enforcer_->DoesConformToCertPolicy(chain_.get(), scts, | |
| 412 BoundNetLog())); | |
| 413 EXPECT_EQ(ct::EVPolicyCompliance::EV_POLICY_NOT_ENOUGH_SCTS, | |
| 414 policy_enforcer_->DoesConformToCTEVPolicy(chain_.get(), nullptr, | |
| 415 scts, BoundNetLog())); | |
| 416 } | |
| 417 | |
| 418 TEST_F(CTPolicyEnforcerTest, | |
| 419 DoesNotConformWithIssuanceDateAfterDisqualificationDate) { | |
| 420 ct::SCTList scts; | |
| 421 AddDisqualifiedLogSCT(ct::SignedCertificateTimestamp::SCT_EMBEDDED, true, | |
| 422 &scts); | |
| 423 FillListWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED, 4, | |
| 424 &scts); | |
| 425 // Make sure all SCTs are after the disqualification date. | |
| 426 for (size_t i = 1; i < scts.size(); ++i) | |
| 427 scts[i]->timestamp = scts[0]->timestamp; | |
| 428 | |
| 429 // |chain_| is valid for 10 years - over 121 months - so requires 5 SCTs. | |
| 430 EXPECT_EQ(ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS, | |
| 431 policy_enforcer_->DoesConformToCertPolicy(chain_.get(), scts, | |
| 432 BoundNetLog())); | |
| 433 EXPECT_EQ(ct::EVPolicyCompliance::EV_POLICY_NOT_ENOUGH_SCTS, | |
| 434 policy_enforcer_->DoesConformToCTEVPolicy(chain_.get(), nullptr, | |
| 435 scts, BoundNetLog())); | |
| 436 } | |
| 437 | |
| 438 TEST_F(CTPolicyEnforcerTest, | 300 TEST_F(CTPolicyEnforcerTest, |
| 439 DoesNotConformToCTEVPolicyNotEnoughUniqueEmbeddedLogs) { | 301 DoesNotConformToCTEVPolicyNotEnoughUniqueEmbeddedLogs) { |
| 440 ct::SCTList scts; | 302 ct::SCTList scts; |
| 441 std::vector<std::string> desired_logs; | 303 std::vector<std::string> desired_logs; |
| 442 | 304 |
| 443 // One Google Log. | 305 // One Google Log. |
| 444 desired_logs.clear(); | 306 desired_logs.clear(); |
| 445 desired_logs.push_back(google_log_id_); | 307 desired_logs.push_back(google_log_id_); |
| 446 FillListWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED, | 308 FillListWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED, |
| 447 desired_logs.size(), desired_logs, true, &scts); | 309 desired_logs.size(), desired_logs, true, &scts); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 571 FillListWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED, 2, | 433 FillListWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED, 2, |
| 572 &scts); | 434 &scts); |
| 573 EXPECT_EQ(ct::EVPolicyCompliance::EV_POLICY_NOT_ENOUGH_SCTS, | 435 EXPECT_EQ(ct::EVPolicyCompliance::EV_POLICY_NOT_ENOUGH_SCTS, |
| 574 policy_enforcer_->DoesConformToCTEVPolicy(chain_.get(), nullptr, | 436 policy_enforcer_->DoesConformToCTEVPolicy(chain_.get(), nullptr, |
| 575 scts, BoundNetLog())); | 437 scts, BoundNetLog())); |
| 576 } | 438 } |
| 577 | 439 |
| 578 } // namespace | 440 } // namespace |
| 579 | 441 |
| 580 } // namespace net | 442 } // namespace net |
| OLD | NEW |