Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(63)

Side by Side Diff: net/http/http_security_headers_unittest.cc

Issue 1213783005: Send HPKP violation reports when a pin check fails (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/profiles/profile_io_data.cc ('k') | net/http/transport_security_state.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 661 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 HashValuesEqual(backup_hash)); 672 HashValuesEqual(backup_hash));
673 EXPECT_NE(dynamic_pkp_state.spki_hashes.end(), hash); 673 EXPECT_NE(dynamic_pkp_state.spki_hashes.end(), hash);
674 674
675 // Expect the overall state to reflect the header, too. 675 // Expect the overall state to reflect the header, too.
676 EXPECT_TRUE(state.HasPublicKeyPins(domain)); 676 EXPECT_TRUE(state.HasPublicKeyPins(domain));
677 HashValueVector hashes; 677 HashValueVector hashes;
678 hashes.push_back(good_hash); 678 hashes.push_back(good_hash);
679 std::string failure_log; 679 std::string failure_log;
680 const bool is_issued_by_known_root = true; 680 const bool is_issued_by_known_root = true;
681 EXPECT_TRUE(state.CheckPublicKeyPins( 681 EXPECT_TRUE(state.CheckPublicKeyPins(
682 domain, is_issued_by_known_root, hashes, &failure_log)); 682 domain, is_issued_by_known_root, hashes, 0, nullptr, nullptr,
683 TransportSecurityState::DISABLE_PIN_REPORTS, &failure_log));
683 684
684 TransportSecurityState::PKPState new_dynamic_pkp_state; 685 TransportSecurityState::PKPState new_dynamic_pkp_state;
685 EXPECT_TRUE(state.GetDynamicPKPState(domain, &new_dynamic_pkp_state)); 686 EXPECT_TRUE(state.GetDynamicPKPState(domain, &new_dynamic_pkp_state));
686 EXPECT_EQ(2UL, new_dynamic_pkp_state.spki_hashes.size()); 687 EXPECT_EQ(2UL, new_dynamic_pkp_state.spki_hashes.size());
687 EXPECT_EQ(report_uri, new_dynamic_pkp_state.report_uri); 688 EXPECT_EQ(report_uri, new_dynamic_pkp_state.report_uri);
688 689
689 hash = std::find_if(new_dynamic_pkp_state.spki_hashes.begin(), 690 hash = std::find_if(new_dynamic_pkp_state.spki_hashes.begin(),
690 new_dynamic_pkp_state.spki_hashes.end(), 691 new_dynamic_pkp_state.spki_hashes.end(),
691 HashValuesEqual(good_hash)); 692 HashValuesEqual(good_hash));
692 EXPECT_NE(new_dynamic_pkp_state.spki_hashes.end(), hash); 693 EXPECT_NE(new_dynamic_pkp_state.spki_hashes.end(), hash);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 EXPECT_TRUE(state.HasPublicKeyPins(domain)); 765 EXPECT_TRUE(state.HasPublicKeyPins(domain));
765 EXPECT_TRUE(state.ShouldSSLErrorsBeFatal(domain)); 766 EXPECT_TRUE(state.ShouldSSLErrorsBeFatal(domain));
766 std::string failure_log; 767 std::string failure_log;
767 768
768 // Damage the hashes to cause a pin validation failure. 769 // Damage the hashes to cause a pin validation failure.
769 new_static_pkp_state2.spki_hashes[0].data()[0] ^= 0x80; 770 new_static_pkp_state2.spki_hashes[0].data()[0] ^= 0x80;
770 new_static_pkp_state2.spki_hashes[1].data()[0] ^= 0x80; 771 new_static_pkp_state2.spki_hashes[1].data()[0] ^= 0x80;
771 new_static_pkp_state2.spki_hashes[2].data()[0] ^= 0x80; 772 new_static_pkp_state2.spki_hashes[2].data()[0] ^= 0x80;
772 773
773 const bool is_issued_by_known_root = true; 774 const bool is_issued_by_known_root = true;
774 EXPECT_FALSE(state.CheckPublicKeyPins(domain, is_issued_by_known_root, 775 EXPECT_FALSE(state.CheckPublicKeyPins(
775 new_static_pkp_state2.spki_hashes, 776 domain, is_issued_by_known_root, new_static_pkp_state2.spki_hashes, 0,
776 &failure_log)); 777 nullptr, nullptr, TransportSecurityState::DISABLE_PIN_REPORTS,
778 &failure_log));
777 EXPECT_NE(0UL, failure_log.length()); 779 EXPECT_NE(0UL, failure_log.length());
778 } 780 }
779 781
780 // Tests that when a static HSTS and a static HPKP entry are present, adding a 782 // Tests that when a static HSTS and a static HPKP entry are present, adding a
781 // dynamic HSTS header does not clobber the static HPKP entry. Further, adding a 783 // dynamic HSTS header does not clobber the static HPKP entry. Further, adding a
782 // dynamic HPKP entry could not affect the HSTS entry for the site. 784 // dynamic HPKP entry could not affect the HSTS entry for the site.
783 TEST_F(HttpSecurityHeadersTest, NoClobberPins) { 785 TEST_F(HttpSecurityHeadersTest, NoClobberPins) {
784 TransportSecurityState state; 786 TransportSecurityState state;
785 TransportSecurityState::STSState sts_state; 787 TransportSecurityState::STSState sts_state;
786 TransportSecurityState::PKPState pkp_state; 788 TransportSecurityState::PKPState pkp_state;
(...skipping 11 matching lines...) Expand all
798 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain)); 800 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain));
799 EXPECT_TRUE(state.HasPublicKeyPins(domain)); 801 EXPECT_TRUE(state.HasPublicKeyPins(domain));
800 802
801 // Add a dynamic HSTS header. CheckPublicKeyPins should still pass when given 803 // Add a dynamic HSTS header. CheckPublicKeyPins should still pass when given
802 // the original |saved_hashes|, indicating that the static PKP data is still 804 // the original |saved_hashes|, indicating that the static PKP data is still
803 // configured for the domain. 805 // configured for the domain.
804 EXPECT_TRUE(state.AddHSTSHeader(domain, "includesubdomains; max-age=10000")); 806 EXPECT_TRUE(state.AddHSTSHeader(domain, "includesubdomains; max-age=10000"));
805 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain)); 807 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain));
806 std::string failure_log; 808 std::string failure_log;
807 const bool is_issued_by_known_root = true; 809 const bool is_issued_by_known_root = true;
808 EXPECT_TRUE(state.CheckPublicKeyPins(domain, 810 EXPECT_TRUE(state.CheckPublicKeyPins(
809 is_issued_by_known_root, 811 domain, is_issued_by_known_root, saved_hashes, 0, nullptr, nullptr,
810 saved_hashes, 812 TransportSecurityState::DISABLE_PIN_REPORTS, &failure_log));
811 &failure_log));
812 813
813 // Add an HPKP header, which should only update the dynamic state. 814 // Add an HPKP header, which should only update the dynamic state.
814 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1); 815 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1);
815 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1); 816 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1);
816 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1); 817 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1);
817 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin; 818 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin;
818 819
819 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks. 820 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks.
820 SSLInfo ssl_info; 821 SSLInfo ssl_info;
821 ssl_info.public_key_hashes.push_back(good_hash); 822 ssl_info.public_key_hashes.push_back(good_hash);
822 ssl_info.public_key_hashes.push_back(saved_hashes[0]); 823 ssl_info.public_key_hashes.push_back(saved_hashes[0]);
823 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); 824 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
824 825
825 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); 826 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
826 // HSTS should still be configured for this domain. 827 // HSTS should still be configured for this domain.
827 EXPECT_TRUE(sts_state.ShouldUpgradeToSSL()); 828 EXPECT_TRUE(sts_state.ShouldUpgradeToSSL());
828 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain)); 829 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain));
829 // The dynamic pins, which do not match |saved_hashes|, should take 830 // The dynamic pins, which do not match |saved_hashes|, should take
830 // precedence over the static pins and cause the check to fail. 831 // precedence over the static pins and cause the check to fail.
831 EXPECT_FALSE(state.CheckPublicKeyPins(domain, 832 EXPECT_FALSE(state.CheckPublicKeyPins(
832 is_issued_by_known_root, 833 domain, is_issued_by_known_root, saved_hashes, 0, nullptr, nullptr,
833 saved_hashes, 834 TransportSecurityState::DISABLE_PIN_REPORTS, &failure_log));
834 &failure_log));
835 } 835 }
836 836
837 // Tests that seeing an invalid HPKP header leaves the existing one alone. 837 // Tests that seeing an invalid HPKP header leaves the existing one alone.
838 TEST_F(HttpSecurityHeadersTest, IgnoreInvalidHeaders) { 838 TEST_F(HttpSecurityHeadersTest, IgnoreInvalidHeaders) {
839 TransportSecurityState state; 839 TransportSecurityState state;
840 840
841 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA256); 841 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA256);
842 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA256); 842 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA256);
843 std::string bad_pin = GetTestPin(2, HASH_VALUE_SHA256); 843 std::string bad_pin = GetTestPin(2, HASH_VALUE_SHA256);
844 std::string backup_pin = GetTestPin(3, HASH_VALUE_SHA256); 844 std::string backup_pin = GetTestPin(3, HASH_VALUE_SHA256);
845 845
846 SSLInfo ssl_info; 846 SSLInfo ssl_info;
847 ssl_info.public_key_hashes.push_back(good_hash); 847 ssl_info.public_key_hashes.push_back(good_hash);
848 848
849 // Add a valid HPKP header. 849 // Add a valid HPKP header.
850 EXPECT_TRUE(state.AddHPKPHeader( 850 EXPECT_TRUE(state.AddHPKPHeader(
851 "example.com", "max-age = 10000; " + good_pin + "; " + backup_pin, 851 "example.com", "max-age = 10000; " + good_pin + "; " + backup_pin,
852 ssl_info)); 852 ssl_info));
853 853
854 // Check the insertion was valid. 854 // Check the insertion was valid.
855 EXPECT_TRUE(state.HasPublicKeyPins("example.com")); 855 EXPECT_TRUE(state.HasPublicKeyPins("example.com"));
856 std::string failure_log; 856 std::string failure_log;
857 bool is_issued_by_known_root = true; 857 bool is_issued_by_known_root = true;
858 EXPECT_TRUE(state.CheckPublicKeyPins("example.com", is_issued_by_known_root, 858 EXPECT_TRUE(state.CheckPublicKeyPins(
859 ssl_info.public_key_hashes, 859 "example.com", is_issued_by_known_root, ssl_info.public_key_hashes, 0,
860 &failure_log)); 860 nullptr, nullptr, TransportSecurityState::DISABLE_PIN_REPORTS,
861 &failure_log));
861 862
862 // Now assert an invalid one. This should fail. 863 // Now assert an invalid one. This should fail.
863 EXPECT_FALSE(state.AddHPKPHeader( 864 EXPECT_FALSE(state.AddHPKPHeader(
864 "example.com", "max-age = 10000; " + bad_pin + "; " + backup_pin, 865 "example.com", "max-age = 10000; " + bad_pin + "; " + backup_pin,
865 ssl_info)); 866 ssl_info));
866 867
867 // The old pins must still exist. 868 // The old pins must still exist.
868 EXPECT_TRUE(state.HasPublicKeyPins("example.com")); 869 EXPECT_TRUE(state.HasPublicKeyPins("example.com"));
869 EXPECT_TRUE(state.CheckPublicKeyPins("example.com", is_issued_by_known_root, 870 EXPECT_TRUE(state.CheckPublicKeyPins(
870 ssl_info.public_key_hashes, 871 "example.com", is_issued_by_known_root, ssl_info.public_key_hashes, 0,
871 &failure_log)); 872 nullptr, nullptr, TransportSecurityState::DISABLE_PIN_REPORTS,
873 &failure_log));
872 } 874 }
873 875
874 }; // namespace net 876 }; // namespace net
OLDNEW
« no previous file with comments | « chrome/browser/profiles/profile_io_data.cc ('k') | net/http/transport_security_state.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698