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 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
663 HashValuesEqual(backup_hash)); | 663 HashValuesEqual(backup_hash)); |
664 EXPECT_NE(dynamic_pkp_state.spki_hashes.end(), hash); | 664 EXPECT_NE(dynamic_pkp_state.spki_hashes.end(), hash); |
665 | 665 |
666 // Expect the overall state to reflect the header, too. | 666 // Expect the overall state to reflect the header, too. |
667 EXPECT_TRUE(state.HasPublicKeyPins(domain)); | 667 EXPECT_TRUE(state.HasPublicKeyPins(domain)); |
668 HashValueVector hashes; | 668 HashValueVector hashes; |
669 hashes.push_back(good_hash); | 669 hashes.push_back(good_hash); |
670 std::string failure_log; | 670 std::string failure_log; |
671 const bool is_issued_by_known_root = true; | 671 const bool is_issued_by_known_root = true; |
672 EXPECT_TRUE(state.CheckPublicKeyPins( | 672 EXPECT_TRUE(state.CheckPublicKeyPins( |
673 domain, is_issued_by_known_root, hashes, &failure_log)); | 673 domain, is_issued_by_known_root, hashes, 0, nullptr, nullptr, |
| 674 TransportSecurityState::DO_NOT_SEND_PUBLIC_KEY_PIN_REPORT, &failure_log)); |
674 | 675 |
675 TransportSecurityState::PKPState new_dynamic_pkp_state; | 676 TransportSecurityState::PKPState new_dynamic_pkp_state; |
676 EXPECT_TRUE(state.GetDynamicPKPState(domain, &new_dynamic_pkp_state)); | 677 EXPECT_TRUE(state.GetDynamicPKPState(domain, &new_dynamic_pkp_state)); |
677 EXPECT_EQ(2UL, new_dynamic_pkp_state.spki_hashes.size()); | 678 EXPECT_EQ(2UL, new_dynamic_pkp_state.spki_hashes.size()); |
678 EXPECT_EQ(report_uri, new_dynamic_pkp_state.report_uri); | 679 EXPECT_EQ(report_uri, new_dynamic_pkp_state.report_uri); |
679 | 680 |
680 hash = std::find_if(new_dynamic_pkp_state.spki_hashes.begin(), | 681 hash = std::find_if(new_dynamic_pkp_state.spki_hashes.begin(), |
681 new_dynamic_pkp_state.spki_hashes.end(), | 682 new_dynamic_pkp_state.spki_hashes.end(), |
682 HashValuesEqual(good_hash)); | 683 HashValuesEqual(good_hash)); |
683 EXPECT_NE(new_dynamic_pkp_state.spki_hashes.end(), hash); | 684 EXPECT_NE(new_dynamic_pkp_state.spki_hashes.end(), hash); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
755 EXPECT_TRUE(state.HasPublicKeyPins(domain)); | 756 EXPECT_TRUE(state.HasPublicKeyPins(domain)); |
756 EXPECT_TRUE(state.ShouldSSLErrorsBeFatal(domain)); | 757 EXPECT_TRUE(state.ShouldSSLErrorsBeFatal(domain)); |
757 std::string failure_log; | 758 std::string failure_log; |
758 | 759 |
759 // Damage the hashes to cause a pin validation failure. | 760 // Damage the hashes to cause a pin validation failure. |
760 new_static_pkp_state2.spki_hashes[0].data()[0] ^= 0x80; | 761 new_static_pkp_state2.spki_hashes[0].data()[0] ^= 0x80; |
761 new_static_pkp_state2.spki_hashes[1].data()[0] ^= 0x80; | 762 new_static_pkp_state2.spki_hashes[1].data()[0] ^= 0x80; |
762 new_static_pkp_state2.spki_hashes[2].data()[0] ^= 0x80; | 763 new_static_pkp_state2.spki_hashes[2].data()[0] ^= 0x80; |
763 | 764 |
764 const bool is_issued_by_known_root = true; | 765 const bool is_issued_by_known_root = true; |
765 EXPECT_FALSE(state.CheckPublicKeyPins(domain, is_issued_by_known_root, | 766 EXPECT_FALSE(state.CheckPublicKeyPins( |
766 new_static_pkp_state2.spki_hashes, | 767 domain, is_issued_by_known_root, new_static_pkp_state2.spki_hashes, 0, |
767 &failure_log)); | 768 nullptr, nullptr, |
| 769 TransportSecurityState::DO_NOT_SEND_PUBLIC_KEY_PIN_REPORT, &failure_log)); |
768 EXPECT_NE(0UL, failure_log.length()); | 770 EXPECT_NE(0UL, failure_log.length()); |
769 } | 771 } |
770 | 772 |
771 // Tests that when a static HSTS and a static HPKP entry are present, adding a | 773 // Tests that when a static HSTS and a static HPKP entry are present, adding a |
772 // dynamic HSTS header does not clobber the static HPKP entry. Further, adding a | 774 // dynamic HSTS header does not clobber the static HPKP entry. Further, adding a |
773 // dynamic HPKP entry could not affect the HSTS entry for the site. | 775 // dynamic HPKP entry could not affect the HSTS entry for the site. |
774 TEST_F(HttpSecurityHeadersTest, NoClobberPins) { | 776 TEST_F(HttpSecurityHeadersTest, NoClobberPins) { |
775 TransportSecurityState state; | 777 TransportSecurityState state; |
776 TransportSecurityState::STSState sts_state; | 778 TransportSecurityState::STSState sts_state; |
777 TransportSecurityState::PKPState pkp_state; | 779 TransportSecurityState::PKPState pkp_state; |
(...skipping 11 matching lines...) Expand all Loading... |
789 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain)); | 791 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain)); |
790 EXPECT_TRUE(state.HasPublicKeyPins(domain)); | 792 EXPECT_TRUE(state.HasPublicKeyPins(domain)); |
791 | 793 |
792 // Add a dynamic HSTS header. CheckPublicKeyPins should still pass when given | 794 // Add a dynamic HSTS header. CheckPublicKeyPins should still pass when given |
793 // the original |saved_hashes|, indicating that the static PKP data is still | 795 // the original |saved_hashes|, indicating that the static PKP data is still |
794 // configured for the domain. | 796 // configured for the domain. |
795 EXPECT_TRUE(state.AddHSTSHeader(domain, "includesubdomains; max-age=10000")); | 797 EXPECT_TRUE(state.AddHSTSHeader(domain, "includesubdomains; max-age=10000")); |
796 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain)); | 798 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain)); |
797 std::string failure_log; | 799 std::string failure_log; |
798 const bool is_issued_by_known_root = true; | 800 const bool is_issued_by_known_root = true; |
799 EXPECT_TRUE(state.CheckPublicKeyPins(domain, | 801 EXPECT_TRUE(state.CheckPublicKeyPins( |
800 is_issued_by_known_root, | 802 domain, is_issued_by_known_root, saved_hashes, 0, nullptr, nullptr, |
801 saved_hashes, | 803 TransportSecurityState::DO_NOT_SEND_PUBLIC_KEY_PIN_REPORT, &failure_log)); |
802 &failure_log)); | |
803 | 804 |
804 // Add an HPKP header, which should only update the dynamic state. | 805 // Add an HPKP header, which should only update the dynamic state. |
805 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1); | 806 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1); |
806 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1); | 807 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1); |
807 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1); | 808 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1); |
808 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin; | 809 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin; |
809 | 810 |
810 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks. | 811 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks. |
811 SSLInfo ssl_info; | 812 SSLInfo ssl_info; |
812 ssl_info.public_key_hashes.push_back(good_hash); | 813 ssl_info.public_key_hashes.push_back(good_hash); |
813 ssl_info.public_key_hashes.push_back(saved_hashes[0]); | 814 ssl_info.public_key_hashes.push_back(saved_hashes[0]); |
814 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); | 815 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); |
815 | 816 |
816 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); | 817 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); |
817 // HSTS should still be configured for this domain. | 818 // HSTS should still be configured for this domain. |
818 EXPECT_TRUE(sts_state.ShouldUpgradeToSSL()); | 819 EXPECT_TRUE(sts_state.ShouldUpgradeToSSL()); |
819 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain)); | 820 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain)); |
820 // The dynamic pins, which do not match |saved_hashes|, should take | 821 // The dynamic pins, which do not match |saved_hashes|, should take |
821 // precedence over the static pins and cause the check to fail. | 822 // precedence over the static pins and cause the check to fail. |
822 EXPECT_FALSE(state.CheckPublicKeyPins(domain, | 823 EXPECT_FALSE(state.CheckPublicKeyPins( |
823 is_issued_by_known_root, | 824 domain, is_issued_by_known_root, saved_hashes, 0, nullptr, nullptr, |
824 saved_hashes, | 825 TransportSecurityState::DO_NOT_SEND_PUBLIC_KEY_PIN_REPORT, &failure_log)); |
825 &failure_log)); | |
826 } | 826 } |
827 | 827 |
828 // Tests that seeing an invalid HPKP header leaves the existing one alone. | 828 // Tests that seeing an invalid HPKP header leaves the existing one alone. |
829 TEST_F(HttpSecurityHeadersTest, IgnoreInvalidHeaders) { | 829 TEST_F(HttpSecurityHeadersTest, IgnoreInvalidHeaders) { |
830 TransportSecurityState state; | 830 TransportSecurityState state; |
831 | 831 |
832 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA256); | 832 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA256); |
833 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA256); | 833 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA256); |
834 std::string bad_pin = GetTestPin(2, HASH_VALUE_SHA256); | 834 std::string bad_pin = GetTestPin(2, HASH_VALUE_SHA256); |
835 std::string backup_pin = GetTestPin(3, HASH_VALUE_SHA256); | 835 std::string backup_pin = GetTestPin(3, HASH_VALUE_SHA256); |
836 | 836 |
837 SSLInfo ssl_info; | 837 SSLInfo ssl_info; |
838 ssl_info.public_key_hashes.push_back(good_hash); | 838 ssl_info.public_key_hashes.push_back(good_hash); |
839 | 839 |
840 // Add a valid HPKP header. | 840 // Add a valid HPKP header. |
841 EXPECT_TRUE(state.AddHPKPHeader( | 841 EXPECT_TRUE(state.AddHPKPHeader( |
842 "example.com", "max-age = 10000; " + good_pin + "; " + backup_pin, | 842 "example.com", "max-age = 10000; " + good_pin + "; " + backup_pin, |
843 ssl_info)); | 843 ssl_info)); |
844 | 844 |
845 // Check the insertion was valid. | 845 // Check the insertion was valid. |
846 EXPECT_TRUE(state.HasPublicKeyPins("example.com")); | 846 EXPECT_TRUE(state.HasPublicKeyPins("example.com")); |
847 std::string failure_log; | 847 std::string failure_log; |
848 bool is_issued_by_known_root = true; | 848 bool is_issued_by_known_root = true; |
849 EXPECT_TRUE(state.CheckPublicKeyPins("example.com", is_issued_by_known_root, | 849 EXPECT_TRUE(state.CheckPublicKeyPins( |
850 ssl_info.public_key_hashes, | 850 "example.com", is_issued_by_known_root, ssl_info.public_key_hashes, 0, |
851 &failure_log)); | 851 nullptr, nullptr, |
| 852 TransportSecurityState::DO_NOT_SEND_PUBLIC_KEY_PIN_REPORT, &failure_log)); |
852 | 853 |
853 // Now assert an invalid one. This should fail. | 854 // Now assert an invalid one. This should fail. |
854 EXPECT_FALSE(state.AddHPKPHeader( | 855 EXPECT_FALSE(state.AddHPKPHeader( |
855 "example.com", "max-age = 10000; " + bad_pin + "; " + backup_pin, | 856 "example.com", "max-age = 10000; " + bad_pin + "; " + backup_pin, |
856 ssl_info)); | 857 ssl_info)); |
857 | 858 |
858 // The old pins must still exist. | 859 // The old pins must still exist. |
859 EXPECT_TRUE(state.HasPublicKeyPins("example.com")); | 860 EXPECT_TRUE(state.HasPublicKeyPins("example.com")); |
860 EXPECT_TRUE(state.CheckPublicKeyPins("example.com", is_issued_by_known_root, | 861 EXPECT_TRUE(state.CheckPublicKeyPins( |
861 ssl_info.public_key_hashes, | 862 "example.com", is_issued_by_known_root, ssl_info.public_key_hashes, 0, |
862 &failure_log)); | 863 nullptr, nullptr, |
| 864 TransportSecurityState::DO_NOT_SEND_PUBLIC_KEY_PIN_REPORT, &failure_log)); |
863 } | 865 } |
864 | 866 |
865 }; // namespace net | 867 }; // namespace net |
OLD | NEW |