| 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 <stdint.h> | 5 #include <stdint.h> |
| 6 #include <algorithm> | 6 #include <algorithm> |
| 7 | 7 |
| 8 #include "base/base64.h" | 8 #include "base/base64.h" |
| 9 #include "base/sha1.h" | 9 #include "base/sha1.h" |
| 10 #include "base/strings/string_piece.h" | 10 #include "base/strings/string_piece.h" |
| (...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 612 HashValuesEqual(backup_hash)); | 612 HashValuesEqual(backup_hash)); |
| 613 EXPECT_NE(dynamic_domain_state.pkp.spki_hashes.end(), hash); | 613 EXPECT_NE(dynamic_domain_state.pkp.spki_hashes.end(), hash); |
| 614 | 614 |
| 615 // Expect the overall state to reflect the header, too. | 615 // Expect the overall state to reflect the header, too. |
| 616 EXPECT_TRUE(state.HasPublicKeyPins(domain)); | 616 EXPECT_TRUE(state.HasPublicKeyPins(domain)); |
| 617 HashValueVector hashes; | 617 HashValueVector hashes; |
| 618 hashes.push_back(good_hash); | 618 hashes.push_back(good_hash); |
| 619 std::string failure_log; | 619 std::string failure_log; |
| 620 const bool is_issued_by_known_root = true; | 620 const bool is_issued_by_known_root = true; |
| 621 EXPECT_TRUE(state.CheckPublicKeyPins( | 621 EXPECT_TRUE(state.CheckPublicKeyPins( |
| 622 domain, is_issued_by_known_root, hashes, &failure_log)); | 622 domain, is_issued_by_known_root, hashes, 0, nullptr, nullptr, |
| 623 TransportSecurityState::DO_NOT_SEND_PUBLIC_KEY_PIN_REPORT, &failure_log)); |
| 623 | 624 |
| 624 TransportSecurityState::DomainState new_dynamic_domain_state; | 625 TransportSecurityState::DomainState new_dynamic_domain_state; |
| 625 EXPECT_TRUE(state.GetDynamicDomainState(domain, &new_dynamic_domain_state)); | 626 EXPECT_TRUE(state.GetDynamicDomainState(domain, &new_dynamic_domain_state)); |
| 626 EXPECT_EQ(2UL, new_dynamic_domain_state.pkp.spki_hashes.size()); | 627 EXPECT_EQ(2UL, new_dynamic_domain_state.pkp.spki_hashes.size()); |
| 627 EXPECT_EQ(report_uri, dynamic_domain_state.pkp.report_uri); | 628 EXPECT_EQ(report_uri, dynamic_domain_state.pkp.report_uri); |
| 628 | 629 |
| 629 hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(), | 630 hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(), |
| 630 new_dynamic_domain_state.pkp.spki_hashes.end(), | 631 new_dynamic_domain_state.pkp.spki_hashes.end(), |
| 631 HashValuesEqual(good_hash)); | 632 HashValuesEqual(good_hash)); |
| 632 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash); | 633 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 // though dynamic policy has been removed. (This policy may change in the | 703 // though dynamic policy has been removed. (This policy may change in the |
| 703 // future, in which case this test must be updated.) | 704 // future, in which case this test must be updated.) |
| 704 EXPECT_TRUE(state.HasPublicKeyPins(domain)); | 705 EXPECT_TRUE(state.HasPublicKeyPins(domain)); |
| 705 EXPECT_TRUE(state.ShouldSSLErrorsBeFatal(domain)); | 706 EXPECT_TRUE(state.ShouldSSLErrorsBeFatal(domain)); |
| 706 std::string failure_log; | 707 std::string failure_log; |
| 707 // Damage the hashes to cause a pin validation failure. | 708 // Damage the hashes to cause a pin validation failure. |
| 708 new_static_domain_state2.pkp.spki_hashes[0].data()[0] ^= 0x80; | 709 new_static_domain_state2.pkp.spki_hashes[0].data()[0] ^= 0x80; |
| 709 new_static_domain_state2.pkp.spki_hashes[1].data()[0] ^= 0x80; | 710 new_static_domain_state2.pkp.spki_hashes[1].data()[0] ^= 0x80; |
| 710 new_static_domain_state2.pkp.spki_hashes[2].data()[0] ^= 0x80; | 711 new_static_domain_state2.pkp.spki_hashes[2].data()[0] ^= 0x80; |
| 711 const bool is_issued_by_known_root = true; | 712 const bool is_issued_by_known_root = true; |
| 712 EXPECT_FALSE( | 713 EXPECT_FALSE(state.CheckPublicKeyPins( |
| 713 state.CheckPublicKeyPins(domain, | 714 domain, is_issued_by_known_root, new_static_domain_state2.pkp.spki_hashes, |
| 714 is_issued_by_known_root, | 715 0, nullptr, nullptr, |
| 715 new_static_domain_state2.pkp.spki_hashes, | 716 TransportSecurityState::DO_NOT_SEND_PUBLIC_KEY_PIN_REPORT, &failure_log)); |
| 716 &failure_log)); | |
| 717 EXPECT_NE(0UL, failure_log.length()); | 717 EXPECT_NE(0UL, failure_log.length()); |
| 718 } | 718 } |
| 719 | 719 |
| 720 // Tests that when a static HSTS and a static HPKP entry are present, adding a | 720 // Tests that when a static HSTS and a static HPKP entry are present, adding a |
| 721 // dynamic HSTS header does not clobber the static HPKP entry. Further, adding a | 721 // dynamic HSTS header does not clobber the static HPKP entry. Further, adding a |
| 722 // dynamic HPKP entry could not affect the HSTS entry for the site. | 722 // dynamic HPKP entry could not affect the HSTS entry for the site. |
| 723 TEST_F(HttpSecurityHeadersTest, NoClobberPins) { | 723 TEST_F(HttpSecurityHeadersTest, NoClobberPins) { |
| 724 TransportSecurityState state; | 724 TransportSecurityState state; |
| 725 TransportSecurityState::DomainState domain_state; | 725 TransportSecurityState::DomainState domain_state; |
| 726 | 726 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 737 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain)); | 737 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain)); |
| 738 EXPECT_TRUE(state.HasPublicKeyPins(domain)); | 738 EXPECT_TRUE(state.HasPublicKeyPins(domain)); |
| 739 | 739 |
| 740 // Add a dynamic HSTS header. CheckPublicKeyPins should still pass when given | 740 // Add a dynamic HSTS header. CheckPublicKeyPins should still pass when given |
| 741 // the original |saved_hashes|, indicating that the static PKP data is still | 741 // the original |saved_hashes|, indicating that the static PKP data is still |
| 742 // configured for the domain. | 742 // configured for the domain. |
| 743 EXPECT_TRUE(state.AddHSTSHeader(domain, "includesubdomains; max-age=10000")); | 743 EXPECT_TRUE(state.AddHSTSHeader(domain, "includesubdomains; max-age=10000")); |
| 744 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain)); | 744 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain)); |
| 745 std::string failure_log; | 745 std::string failure_log; |
| 746 const bool is_issued_by_known_root = true; | 746 const bool is_issued_by_known_root = true; |
| 747 EXPECT_TRUE(state.CheckPublicKeyPins(domain, | 747 EXPECT_TRUE(state.CheckPublicKeyPins( |
| 748 is_issued_by_known_root, | 748 domain, is_issued_by_known_root, saved_hashes, 0, nullptr, nullptr, |
| 749 saved_hashes, | 749 TransportSecurityState::DO_NOT_SEND_PUBLIC_KEY_PIN_REPORT, &failure_log)); |
| 750 &failure_log)); | |
| 751 | 750 |
| 752 // Add an HPKP header, which should only update the dynamic state. | 751 // Add an HPKP header, which should only update the dynamic state. |
| 753 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1); | 752 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1); |
| 754 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1); | 753 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1); |
| 755 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1); | 754 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1); |
| 756 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin; | 755 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin; |
| 757 | 756 |
| 758 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks. | 757 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks. |
| 759 SSLInfo ssl_info; | 758 SSLInfo ssl_info; |
| 760 ssl_info.public_key_hashes.push_back(good_hash); | 759 ssl_info.public_key_hashes.push_back(good_hash); |
| 761 ssl_info.public_key_hashes.push_back(saved_hashes[0]); | 760 ssl_info.public_key_hashes.push_back(saved_hashes[0]); |
| 762 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); | 761 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); |
| 763 | 762 |
| 764 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); | 763 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); |
| 765 // HSTS should still be configured for this domain. | 764 // HSTS should still be configured for this domain. |
| 766 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL()); | 765 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL()); |
| 767 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain)); | 766 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain)); |
| 768 // The dynamic pins, which do not match |saved_hashes|, should take | 767 // The dynamic pins, which do not match |saved_hashes|, should take |
| 769 // precedence over the static pins and cause the check to fail. | 768 // precedence over the static pins and cause the check to fail. |
| 770 EXPECT_FALSE(state.CheckPublicKeyPins(domain, | 769 EXPECT_FALSE(state.CheckPublicKeyPins( |
| 771 is_issued_by_known_root, | 770 domain, is_issued_by_known_root, saved_hashes, 0, nullptr, nullptr, |
| 772 saved_hashes, | 771 TransportSecurityState::DO_NOT_SEND_PUBLIC_KEY_PIN_REPORT, &failure_log)); |
| 773 &failure_log)); | |
| 774 } | 772 } |
| 775 | 773 |
| 776 // Tests that seeing an invalid HPKP header leaves the existing one alone. | 774 // Tests that seeing an invalid HPKP header leaves the existing one alone. |
| 777 TEST_F(HttpSecurityHeadersTest, IgnoreInvalidHeaders) { | 775 TEST_F(HttpSecurityHeadersTest, IgnoreInvalidHeaders) { |
| 778 TransportSecurityState state; | 776 TransportSecurityState state; |
| 779 | 777 |
| 780 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA256); | 778 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA256); |
| 781 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA256); | 779 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA256); |
| 782 std::string bad_pin = GetTestPin(2, HASH_VALUE_SHA256); | 780 std::string bad_pin = GetTestPin(2, HASH_VALUE_SHA256); |
| 783 std::string backup_pin = GetTestPin(3, HASH_VALUE_SHA256); | 781 std::string backup_pin = GetTestPin(3, HASH_VALUE_SHA256); |
| 784 | 782 |
| 785 SSLInfo ssl_info; | 783 SSLInfo ssl_info; |
| 786 ssl_info.public_key_hashes.push_back(good_hash); | 784 ssl_info.public_key_hashes.push_back(good_hash); |
| 787 | 785 |
| 788 // Add a valid HPKP header. | 786 // Add a valid HPKP header. |
| 789 EXPECT_TRUE(state.AddHPKPHeader( | 787 EXPECT_TRUE(state.AddHPKPHeader( |
| 790 "example.com", "max-age = 10000; " + good_pin + "; " + backup_pin, | 788 "example.com", "max-age = 10000; " + good_pin + "; " + backup_pin, |
| 791 ssl_info)); | 789 ssl_info)); |
| 792 | 790 |
| 793 // Check the insertion was valid. | 791 // Check the insertion was valid. |
| 794 EXPECT_TRUE(state.HasPublicKeyPins("example.com")); | 792 EXPECT_TRUE(state.HasPublicKeyPins("example.com")); |
| 795 std::string failure_log; | 793 std::string failure_log; |
| 796 bool is_issued_by_known_root = true; | 794 bool is_issued_by_known_root = true; |
| 797 EXPECT_TRUE(state.CheckPublicKeyPins("example.com", is_issued_by_known_root, | 795 EXPECT_TRUE(state.CheckPublicKeyPins( |
| 798 ssl_info.public_key_hashes, | 796 "example.com", is_issued_by_known_root, ssl_info.public_key_hashes, 0, |
| 799 &failure_log)); | 797 nullptr, nullptr, |
| 798 TransportSecurityState::DO_NOT_SEND_PUBLIC_KEY_PIN_REPORT, &failure_log)); |
| 800 | 799 |
| 801 // Now assert an invalid one. This should fail. | 800 // Now assert an invalid one. This should fail. |
| 802 EXPECT_FALSE(state.AddHPKPHeader( | 801 EXPECT_FALSE(state.AddHPKPHeader( |
| 803 "example.com", "max-age = 10000; " + bad_pin + "; " + backup_pin, | 802 "example.com", "max-age = 10000; " + bad_pin + "; " + backup_pin, |
| 804 ssl_info)); | 803 ssl_info)); |
| 805 | 804 |
| 806 // The old pins must still exist. | 805 // The old pins must still exist. |
| 807 EXPECT_TRUE(state.HasPublicKeyPins("example.com")); | 806 EXPECT_TRUE(state.HasPublicKeyPins("example.com")); |
| 808 EXPECT_TRUE(state.CheckPublicKeyPins("example.com", is_issued_by_known_root, | 807 EXPECT_TRUE(state.CheckPublicKeyPins( |
| 809 ssl_info.public_key_hashes, | 808 "example.com", is_issued_by_known_root, ssl_info.public_key_hashes, 0, |
| 810 &failure_log)); | 809 nullptr, nullptr, |
| 810 TransportSecurityState::DO_NOT_SEND_PUBLIC_KEY_PIN_REPORT, &failure_log)); |
| 811 } | 811 } |
| 812 | 812 |
| 813 }; // namespace net | 813 }; // namespace net |
| OLD | NEW |