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 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 499 TestValidPKPHeaders(HASH_VALUE_SHA256); | 499 TestValidPKPHeaders(HASH_VALUE_SHA256); |
| 500 } | 500 } |
| 501 | 501 |
| 502 TEST_F(HttpSecurityHeadersTest, UpdateDynamicPKPOnly) { | 502 TEST_F(HttpSecurityHeadersTest, UpdateDynamicPKPOnly) { |
| 503 TransportSecurityState state; | 503 TransportSecurityState state; |
| 504 TransportSecurityState::DomainState static_domain_state; | 504 TransportSecurityState::DomainState static_domain_state; |
| 505 | 505 |
| 506 // docs.google.com has preloaded pins. | 506 // docs.google.com has preloaded pins. |
| 507 const bool sni_enabled = true; | 507 const bool sni_enabled = true; |
| 508 std::string domain = "docs.google.com"; | 508 std::string domain = "docs.google.com"; |
| 509 state.enable_static_pinning_ = true; | |
| 509 EXPECT_TRUE( | 510 EXPECT_TRUE( |
| 510 state.GetStaticDomainState(domain, sni_enabled, &static_domain_state)); | 511 state.GetStaticDomainState(domain, sni_enabled, &static_domain_state)); |
| 511 EXPECT_GT(static_domain_state.pkp.spki_hashes.size(), 1UL); | 512 EXPECT_GT(static_domain_state.pkp.spki_hashes.size(), 1UL); |
| 512 HashValueVector saved_hashes = static_domain_state.pkp.spki_hashes; | 513 HashValueVector saved_hashes = static_domain_state.pkp.spki_hashes; |
| 513 | 514 |
| 514 // Add a header, which should only update the dynamic state. | 515 // Add a header, which should only update the dynamic state. |
| 515 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1); | 516 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1); |
| 516 HashValue backup_hash = GetTestHashValue(2, HASH_VALUE_SHA1); | 517 HashValue backup_hash = GetTestHashValue(2, HASH_VALUE_SHA1); |
| 517 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1); | 518 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1); |
| 518 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1); | 519 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1); |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 547 hash = std::find_if(dynamic_domain_state.pkp.spki_hashes.begin(), | 548 hash = std::find_if(dynamic_domain_state.pkp.spki_hashes.begin(), |
| 548 dynamic_domain_state.pkp.spki_hashes.end(), | 549 dynamic_domain_state.pkp.spki_hashes.end(), |
| 549 HashValuesEqual(backup_hash)); | 550 HashValuesEqual(backup_hash)); |
| 550 EXPECT_NE(dynamic_domain_state.pkp.spki_hashes.end(), hash); | 551 EXPECT_NE(dynamic_domain_state.pkp.spki_hashes.end(), hash); |
| 551 | 552 |
| 552 // Expect the overall state to reflect the header, too. | 553 // Expect the overall state to reflect the header, too. |
| 553 EXPECT_TRUE(state.HasPublicKeyPins(domain, sni_enabled)); | 554 EXPECT_TRUE(state.HasPublicKeyPins(domain, sni_enabled)); |
| 554 HashValueVector hashes; | 555 HashValueVector hashes; |
| 555 hashes.push_back(good_hash); | 556 hashes.push_back(good_hash); |
| 556 std::string failure_log; | 557 std::string failure_log; |
| 558 const bool is_issued_by_known_root = true; | |
| 557 EXPECT_TRUE( | 559 EXPECT_TRUE( |
| 558 state.CheckPublicKeyPins(domain, sni_enabled, hashes, &failure_log)); | 560 state.CheckPublicKeyPins(domain, sni_enabled, is_issued_by_known_root, |
| 561 hashes, &failure_log)); | |
| 559 | 562 |
| 560 TransportSecurityState::DomainState new_dynamic_domain_state; | 563 TransportSecurityState::DomainState new_dynamic_domain_state; |
| 561 EXPECT_TRUE(state.GetDynamicDomainState(domain, &new_dynamic_domain_state)); | 564 EXPECT_TRUE(state.GetDynamicDomainState(domain, &new_dynamic_domain_state)); |
| 562 EXPECT_EQ(2UL, new_dynamic_domain_state.pkp.spki_hashes.size()); | 565 EXPECT_EQ(2UL, new_dynamic_domain_state.pkp.spki_hashes.size()); |
| 563 | 566 |
| 564 hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(), | 567 hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(), |
| 565 new_dynamic_domain_state.pkp.spki_hashes.end(), | 568 new_dynamic_domain_state.pkp.spki_hashes.end(), |
| 566 HashValuesEqual(good_hash)); | 569 HashValuesEqual(good_hash)); |
| 567 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash); | 570 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash); |
| 568 | 571 |
| 569 hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(), | 572 hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(), |
| 570 new_dynamic_domain_state.pkp.spki_hashes.end(), | 573 new_dynamic_domain_state.pkp.spki_hashes.end(), |
| 571 HashValuesEqual(backup_hash)); | 574 HashValuesEqual(backup_hash)); |
| 572 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash); | 575 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash); |
| 573 } | 576 } |
| 574 | 577 |
| 575 // Failing on win_chromium_rel. crbug.com/375538 | 578 // Failing on win_chromium_rel. crbug.com/375538 |
| 576 #if defined(OS_WIN) | 579 #if defined(OS_WIN) |
| 577 #define MAYBE_UpdateDynamicPKPMaxAge0 DISABLED_UpdateDynamicPKPMaxAge0 | 580 #define MAYBE_UpdateDynamicPKPMaxAge0 DISABLED_UpdateDynamicPKPMaxAge0 |
| 578 #else | 581 #else |
| 579 #define MAYBE_UpdateDynamicPKPMaxAge0 UpdateDynamicPKPMaxAge0 | 582 #define MAYBE_UpdateDynamicPKPMaxAge0 UpdateDynamicPKPMaxAge0 |
| 580 #endif | 583 #endif |
| 581 TEST_F(HttpSecurityHeadersTest, MAYBE_UpdateDynamicPKPMaxAge0) { | 584 TEST_F(HttpSecurityHeadersTest, MAYBE_UpdateDynamicPKPMaxAge0) { |
| 582 TransportSecurityState state; | 585 TransportSecurityState state; |
| 583 TransportSecurityState::DomainState static_domain_state; | 586 TransportSecurityState::DomainState static_domain_state; |
| 584 | 587 |
| 585 // docs.google.com has preloaded pins. | 588 // docs.google.com has preloaded pins. |
| 586 const bool sni_enabled = true; | 589 const bool sni_enabled = true; |
| 587 std::string domain = "docs.google.com"; | 590 std::string domain = "docs.google.com"; |
| 591 state.enable_static_pinning_ = true; | |
| 588 ASSERT_TRUE( | 592 ASSERT_TRUE( |
| 589 state.GetStaticDomainState(domain, sni_enabled, &static_domain_state)); | 593 state.GetStaticDomainState(domain, sni_enabled, &static_domain_state)); |
| 590 EXPECT_GT(static_domain_state.pkp.spki_hashes.size(), 1UL); | 594 EXPECT_GT(static_domain_state.pkp.spki_hashes.size(), 1UL); |
| 591 HashValueVector saved_hashes = static_domain_state.pkp.spki_hashes; | 595 HashValueVector saved_hashes = static_domain_state.pkp.spki_hashes; |
| 592 | 596 |
| 593 // Add a header, which should only update the dynamic state. | 597 // Add a header, which should only update the dynamic state. |
| 594 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1); | 598 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1); |
| 595 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1); | 599 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1); |
| 596 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1); | 600 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1); |
| 597 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin; | 601 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 641 | 645 |
| 642 // Expect the exact-matching static policy to continue to apply, even | 646 // Expect the exact-matching static policy to continue to apply, even |
| 643 // though dynamic policy has been removed. (This policy may change in the | 647 // though dynamic policy has been removed. (This policy may change in the |
| 644 // future, in which case this test must be updated.) | 648 // future, in which case this test must be updated.) |
| 645 EXPECT_TRUE(state.HasPublicKeyPins(domain, true)); | 649 EXPECT_TRUE(state.HasPublicKeyPins(domain, true)); |
| 646 EXPECT_TRUE(state.ShouldSSLErrorsBeFatal(domain, true)); | 650 EXPECT_TRUE(state.ShouldSSLErrorsBeFatal(domain, true)); |
| 647 std::string failure_log; | 651 std::string failure_log; |
| 648 // Damage the hashes to cause a pin validation failure. | 652 // Damage the hashes to cause a pin validation failure. |
| 649 new_static_domain_state2.pkp.spki_hashes[0].data()[0] ^= 0x80; | 653 new_static_domain_state2.pkp.spki_hashes[0].data()[0] ^= 0x80; |
| 650 new_static_domain_state2.pkp.spki_hashes[1].data()[0] ^= 0x80; | 654 new_static_domain_state2.pkp.spki_hashes[1].data()[0] ^= 0x80; |
| 655 const bool is_issued_by_known_root = true; | |
| 651 EXPECT_FALSE(state.CheckPublicKeyPins( | 656 EXPECT_FALSE(state.CheckPublicKeyPins( |
| 652 domain, true, new_static_domain_state2.pkp.spki_hashes, &failure_log)); | 657 domain, true, is_issued_by_known_root, |
| 658 new_static_domain_state2.pkp.spki_hashes, &failure_log)); | |
| 653 EXPECT_NE(0UL, failure_log.length()); | 659 EXPECT_NE(0UL, failure_log.length()); |
| 654 } | 660 } |
| 655 #undef MAYBE_UpdateDynamicPKPMaxAge0 | 661 #undef MAYBE_UpdateDynamicPKPMaxAge0 |
| 656 | 662 |
| 657 // Tests that when a static HSTS and a static HPKP entry are present, adding a | 663 // Tests that when a static HSTS and a static HPKP entry are present, adding a |
| 658 // dynamic HSTS header does not clobber the static HPKP entry. Further, adding a | 664 // dynamic HSTS header does not clobber the static HPKP entry. Further, adding a |
| 659 // dynamic HPKP entry could not affect the HSTS entry for the site. | 665 // dynamic HPKP entry could not affect the HSTS entry for the site. |
| 660 TEST_F(HttpSecurityHeadersTest, NoClobberPins) { | 666 TEST_F(HttpSecurityHeadersTest, NoClobberPins) { |
| 661 TransportSecurityState state; | 667 TransportSecurityState state; |
| 662 TransportSecurityState::DomainState domain_state; | 668 TransportSecurityState::DomainState domain_state; |
| 663 | 669 |
| 664 // accounts.google.com has preloaded pins. | 670 // accounts.google.com has preloaded pins. |
| 665 std::string domain = "accounts.google.com"; | 671 std::string domain = "accounts.google.com"; |
| 666 | 672 |
| 667 // Retrieve the DomainState as it is by default, including its known good | 673 // Retrieve the DomainState as it is by default, including its known good |
| 668 // pins. | 674 // pins. |
| 669 const bool sni_enabled = true; | 675 const bool sni_enabled = true; |
| 676 state.enable_static_pinning_ = true; | |
|
wtc
2014/08/07 23:39:12
Move this to line 671 to stay close to the comment
Ryan Hamilton
2014/08/08 00:54:00
Done.
| |
| 670 EXPECT_TRUE(state.GetStaticDomainState(domain, sni_enabled, &domain_state)); | 677 EXPECT_TRUE(state.GetStaticDomainState(domain, sni_enabled, &domain_state)); |
| 671 HashValueVector saved_hashes = domain_state.pkp.spki_hashes; | 678 HashValueVector saved_hashes = domain_state.pkp.spki_hashes; |
| 672 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL()); | 679 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL()); |
| 673 EXPECT_TRUE(domain_state.HasPublicKeyPins()); | 680 EXPECT_TRUE(domain_state.HasPublicKeyPins()); |
| 674 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled)); | 681 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled)); |
| 675 EXPECT_TRUE(state.HasPublicKeyPins(domain, sni_enabled)); | 682 EXPECT_TRUE(state.HasPublicKeyPins(domain, sni_enabled)); |
| 676 | 683 |
| 677 // Add a dynamic HSTS header. CheckPublicKeyPins should still pass when given | 684 // Add a dynamic HSTS header. CheckPublicKeyPins should still pass when given |
| 678 // the original |saved_hashes|, indicating that the static PKP data is still | 685 // the original |saved_hashes|, indicating that the static PKP data is still |
| 679 // configured for the domain. | 686 // configured for the domain. |
| 680 EXPECT_TRUE(state.AddHSTSHeader(domain, "includesubdomains; max-age=10000")); | 687 EXPECT_TRUE(state.AddHSTSHeader(domain, "includesubdomains; max-age=10000")); |
| 681 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled)); | 688 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled)); |
| 682 std::string failure_log; | 689 std::string failure_log; |
| 690 const bool is_issued_by_known_root = true; | |
| 683 EXPECT_TRUE(state.CheckPublicKeyPins( | 691 EXPECT_TRUE(state.CheckPublicKeyPins( |
| 684 domain, sni_enabled, saved_hashes, &failure_log)); | 692 domain, sni_enabled, is_issued_by_known_root, saved_hashes, |
| 693 &failure_log)); | |
| 685 | 694 |
| 686 // Add an HPKP header, which should only update the dynamic state. | 695 // Add an HPKP header, which should only update the dynamic state. |
| 687 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1); | 696 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1); |
| 688 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1); | 697 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1); |
| 689 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1); | 698 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1); |
| 690 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin; | 699 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin; |
| 691 | 700 |
| 692 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks. | 701 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks. |
| 693 SSLInfo ssl_info; | 702 SSLInfo ssl_info; |
| 694 ssl_info.public_key_hashes.push_back(good_hash); | 703 ssl_info.public_key_hashes.push_back(good_hash); |
| 695 ssl_info.public_key_hashes.push_back(saved_hashes[0]); | 704 ssl_info.public_key_hashes.push_back(saved_hashes[0]); |
| 696 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); | 705 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); |
| 697 | 706 |
| 698 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); | 707 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); |
| 699 // HSTS should still be configured for this domain. | 708 // HSTS should still be configured for this domain. |
| 700 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL()); | 709 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL()); |
| 701 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled)); | 710 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled)); |
| 702 // The dynamic pins, which do not match |saved_hashes|, should take | 711 // The dynamic pins, which do not match |saved_hashes|, should take |
| 703 // precedence over the static pins and cause the check to fail. | 712 // precedence over the static pins and cause the check to fail. |
| 704 EXPECT_FALSE(state.CheckPublicKeyPins( | 713 EXPECT_FALSE(state.CheckPublicKeyPins( |
| 705 domain, sni_enabled, saved_hashes, &failure_log)); | 714 domain, sni_enabled, is_issued_by_known_root, saved_hashes, |
| 715 &failure_log)); | |
| 706 } | 716 } |
| 707 | 717 |
| 708 }; // namespace net | 718 }; // namespace net |
| OLD | NEW |