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

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: Created 5 years, 6 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
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 601 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698