Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <algorithm> | 5 #include <algorithm> |
| 6 | 6 |
| 7 #include "base/base64.h" | 7 #include "base/base64.h" |
| 8 #include "base/sha1.h" | 8 #include "base/sha1.h" |
| 9 #include "base/strings/string_piece.h" | 9 #include "base/strings/string_piece.h" |
| 10 #include "crypto/sha2.h" | 10 #include "crypto/sha2.h" |
| (...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 443 TEST_F(HttpSecurityHeadersTest, ValidPKPHeadersSHA1) { | 443 TEST_F(HttpSecurityHeadersTest, ValidPKPHeadersSHA1) { |
| 444 TestValidPKPHeaders(HASH_VALUE_SHA1); | 444 TestValidPKPHeaders(HASH_VALUE_SHA1); |
| 445 } | 445 } |
| 446 | 446 |
| 447 TEST_F(HttpSecurityHeadersTest, ValidPKPHeadersSHA256) { | 447 TEST_F(HttpSecurityHeadersTest, ValidPKPHeadersSHA256) { |
| 448 TestValidPKPHeaders(HASH_VALUE_SHA256); | 448 TestValidPKPHeaders(HASH_VALUE_SHA256); |
| 449 } | 449 } |
| 450 | 450 |
| 451 TEST_F(HttpSecurityHeadersTest, UpdateDynamicPKPOnly) { | 451 TEST_F(HttpSecurityHeadersTest, UpdateDynamicPKPOnly) { |
| 452 TransportSecurityState state; | 452 TransportSecurityState state; |
| 453 TransportSecurityState::DomainState domain_state; | 453 TransportSecurityState::DomainState static_domain_state; |
| 454 | 454 |
| 455 // docs.google.com has preloaded pins. | 455 // docs.google.com has preloaded pins. |
| 456 const bool sni_enabled = true; | |
| 456 std::string domain = "docs.google.com"; | 457 std::string domain = "docs.google.com"; |
| 457 EXPECT_TRUE(state.GetDomainState(domain, true, &domain_state)); | 458 EXPECT_TRUE( |
| 458 EXPECT_GT(domain_state.static_spki_hashes.size(), 1UL); | 459 state.GetStaticDomainState(domain, sni_enabled, &static_domain_state)); |
| 459 HashValueVector saved_hashes = domain_state.static_spki_hashes; | 460 EXPECT_GT(static_domain_state.pkp.spki_hashes.size(), 1UL); |
| 461 HashValueVector saved_hashes = static_domain_state.pkp.spki_hashes; | |
| 460 | 462 |
| 461 // Add a header, which should only update the dynamic state. | 463 // Add a header, which should only update the dynamic state. |
| 462 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1); | 464 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1); |
| 463 HashValue backup_hash = GetTestHashValue(2, HASH_VALUE_SHA1); | 465 HashValue backup_hash = GetTestHashValue(2, HASH_VALUE_SHA1); |
| 464 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1); | 466 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1); |
| 465 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1); | 467 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1); |
| 466 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin; | 468 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin; |
| 467 | 469 |
| 468 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks. | 470 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks. |
| 469 SSLInfo ssl_info; | 471 SSLInfo ssl_info; |
| 470 ssl_info.public_key_hashes.push_back(good_hash); | 472 ssl_info.public_key_hashes.push_back(good_hash); |
| 471 ssl_info.public_key_hashes.push_back(saved_hashes[0]); | 473 ssl_info.public_key_hashes.push_back(saved_hashes[0]); |
| 472 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); | 474 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); |
| 473 | 475 |
| 474 // Expect the preloaded state to remain unchanged. | 476 // Expect the static state to remain unchanged. |
| 475 std::string canonicalized_host = TransportSecurityState::CanonicalizeHost( | 477 TransportSecurityState::DomainState new_static_domain_state; |
| 476 domain); | 478 EXPECT_TRUE(state.GetStaticDomainState( |
| 477 TransportSecurityState::DomainState static_domain_state; | 479 domain, sni_enabled, &new_static_domain_state)); |
| 478 EXPECT_TRUE(state.GetStaticDomainState(canonicalized_host, | |
| 479 true, | |
| 480 &static_domain_state)); | |
| 481 for (size_t i = 0; i < saved_hashes.size(); ++i) { | 480 for (size_t i = 0; i < saved_hashes.size(); ++i) { |
| 482 EXPECT_TRUE(HashValuesEqual( | 481 EXPECT_TRUE(HashValuesEqual(saved_hashes[i])( |
| 483 saved_hashes[i])(static_domain_state.static_spki_hashes[i])); | 482 new_static_domain_state.pkp.spki_hashes[i])); |
| 484 } | 483 } |
| 485 | 484 |
| 486 // Expect the dynamic state to reflect the header. | 485 // Expect the dynamic state to reflect the header. |
| 487 TransportSecurityState::DomainState dynamic_domain_state; | 486 TransportSecurityState::DomainState dynamic_domain_state; |
| 488 EXPECT_TRUE(state.GetDynamicDomainState(domain, &dynamic_domain_state)); | 487 EXPECT_TRUE(state.GetDynamicDomainState(domain, &dynamic_domain_state)); |
| 489 EXPECT_EQ(2UL, dynamic_domain_state.dynamic_spki_hashes.size()); | 488 EXPECT_EQ(2UL, dynamic_domain_state.pkp.spki_hashes.size()); |
| 490 | 489 |
| 491 HashValueVector::const_iterator hash = std::find_if( | 490 HashValueVector::const_iterator hash = |
| 492 dynamic_domain_state.dynamic_spki_hashes.begin(), | 491 std::find_if(dynamic_domain_state.pkp.spki_hashes.begin(), |
| 493 dynamic_domain_state.dynamic_spki_hashes.end(), | 492 dynamic_domain_state.pkp.spki_hashes.end(), |
| 494 HashValuesEqual(good_hash)); | 493 HashValuesEqual(good_hash)); |
| 495 EXPECT_NE(dynamic_domain_state.dynamic_spki_hashes.end(), hash); | 494 EXPECT_NE(dynamic_domain_state.pkp.spki_hashes.end(), hash); |
| 496 | 495 |
| 497 hash = std::find_if( | 496 hash = std::find_if(dynamic_domain_state.pkp.spki_hashes.begin(), |
| 498 dynamic_domain_state.dynamic_spki_hashes.begin(), | 497 dynamic_domain_state.pkp.spki_hashes.end(), |
| 499 dynamic_domain_state.dynamic_spki_hashes.end(), | 498 HashValuesEqual(backup_hash)); |
| 500 HashValuesEqual(backup_hash)); | 499 EXPECT_NE(dynamic_domain_state.pkp.spki_hashes.end(), hash); |
| 501 EXPECT_NE(dynamic_domain_state.dynamic_spki_hashes.end(), hash); | |
| 502 | 500 |
| 503 // Expect the overall state to reflect the header, too. | 501 // Expect the overall state to reflect the header, too. |
| 504 EXPECT_TRUE(state.GetDomainState(domain, true, &domain_state)); | 502 EXPECT_TRUE(state.HasPublicKeyPins(domain, sni_enabled)); |
| 505 EXPECT_EQ(2UL, domain_state.dynamic_spki_hashes.size()); | 503 HashValueVector hashes; |
| 504 hashes.push_back(good_hash); | |
| 505 std::string failure_log; | |
| 506 EXPECT_TRUE( | |
| 507 state.CheckPublicKeyPins(domain, sni_enabled, hashes, &failure_log)); | |
| 506 | 508 |
| 507 hash = std::find_if(domain_state.dynamic_spki_hashes.begin(), | 509 TransportSecurityState::DomainState new_dynamic_domain_state; |
| 508 domain_state.dynamic_spki_hashes.end(), | 510 EXPECT_TRUE(state.GetDynamicDomainState(domain, &new_dynamic_domain_state)); |
| 511 EXPECT_EQ(2UL, new_dynamic_domain_state.pkp.spki_hashes.size()); | |
| 512 | |
| 513 hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(), | |
| 514 new_dynamic_domain_state.pkp.spki_hashes.end(), | |
| 509 HashValuesEqual(good_hash)); | 515 HashValuesEqual(good_hash)); |
| 510 EXPECT_NE(domain_state.dynamic_spki_hashes.end(), hash); | 516 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash); |
| 511 | 517 |
| 512 hash = std::find_if( | 518 hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(), |
| 513 domain_state.dynamic_spki_hashes.begin(), | 519 new_dynamic_domain_state.pkp.spki_hashes.end(), |
| 514 domain_state.dynamic_spki_hashes.end(), | 520 HashValuesEqual(backup_hash)); |
| 515 HashValuesEqual(backup_hash)); | 521 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash); |
| 516 EXPECT_NE(domain_state.dynamic_spki_hashes.end(), hash); | 522 } |
| 523 | |
| 524 TEST_F(HttpSecurityHeadersTest, NoClobberPins) { | |
|
Ryan Sleevi
2014/04/24 21:40:21
Document test
// Tests that when a static HSTS an
palmer
2014/04/25 00:59:59
Done.
| |
| 525 TransportSecurityState state; | |
| 526 TransportSecurityState::DomainState domain_state; | |
| 527 | |
| 528 // accounts.google.com has preloaded pins. | |
| 529 std::string domain = "accounts.google.com"; | |
| 530 | |
| 531 // Retrieve the DomainState as it is by default, including its known good | |
| 532 // pins. | |
| 533 const bool sni_enabled = true; | |
| 534 EXPECT_TRUE(state.GetStaticDomainState(domain, sni_enabled, &domain_state)); | |
| 535 HashValueVector saved_hashes = domain_state.pkp.spki_hashes; | |
| 536 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL()); | |
| 537 EXPECT_TRUE(domain_state.HasPublicKeyPins()); | |
| 538 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled)); | |
| 539 EXPECT_TRUE(state.HasPublicKeyPins(domain, sni_enabled)); | |
| 540 | |
| 541 // Add a dynamic HSTS header. CheckPublicKeyPins should still pass when given | |
| 542 // the original |saved_hashes|, indicating that the static PKP data is still | |
| 543 // configured for the domain. | |
| 544 EXPECT_TRUE(state.AddHSTSHeader(domain, "includesubdomains; max-age=10000")); | |
| 545 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled)); | |
| 546 std::string failure_log; | |
| 547 EXPECT_TRUE(state.CheckPublicKeyPins( | |
| 548 domain, sni_enabled, saved_hashes, &failure_log)); | |
| 549 | |
| 550 // Add an HPKP header, which should only update the dynamic state. | |
| 551 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1); | |
| 552 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1); | |
| 553 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1); | |
| 554 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin; | |
| 555 | |
| 556 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks. | |
| 557 SSLInfo ssl_info; | |
| 558 ssl_info.public_key_hashes.push_back(good_hash); | |
| 559 ssl_info.public_key_hashes.push_back(saved_hashes[0]); | |
| 560 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); | |
| 561 | |
| 562 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); | |
| 563 // HSTS should still be configured for this domain. | |
| 564 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL()); | |
| 565 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled)); | |
| 566 // Check that a good pin is still valid. | |
| 567 EXPECT_TRUE(state.CheckPublicKeyPins( | |
| 568 domain, sni_enabled, saved_hashes, &failure_log)); | |
| 517 } | 569 } |
| 518 | 570 |
| 519 }; // namespace net | 571 }; // namespace net |
| OLD | NEW |