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

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

Issue 282873003: Handle max-age in HPKP. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Test bad hashes to force a pin validation failure. Created 6 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | net/http/transport_security_state.cc » ('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 <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 554 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 new_dynamic_domain_state.pkp.spki_hashes.end(), 565 new_dynamic_domain_state.pkp.spki_hashes.end(),
566 HashValuesEqual(good_hash)); 566 HashValuesEqual(good_hash));
567 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash); 567 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash);
568 568
569 hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(), 569 hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(),
570 new_dynamic_domain_state.pkp.spki_hashes.end(), 570 new_dynamic_domain_state.pkp.spki_hashes.end(),
571 HashValuesEqual(backup_hash)); 571 HashValuesEqual(backup_hash));
572 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash); 572 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash);
573 } 573 }
574 574
575 TEST_F(HttpSecurityHeadersTest, UpdateDynamicPKPMaxAge0) {
576 TransportSecurityState state;
577 TransportSecurityState::DomainState static_domain_state;
578
579 // docs.google.com has preloaded pins.
580 const bool sni_enabled = true;
581 std::string domain = "docs.google.com";
582 EXPECT_TRUE(
agl 2014/05/15 00:01:53 ASSERT_TRUE? (I.e. the test is boned if this is fa
palmer 2014/05/15 00:22:31 Done.
583 state.GetStaticDomainState(domain, sni_enabled, &static_domain_state));
584 EXPECT_GT(static_domain_state.pkp.spki_hashes.size(), 1UL);
585 HashValueVector saved_hashes = static_domain_state.pkp.spki_hashes;
586
587 // Add a header, which should only update the dynamic state.
588 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1);
589 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1);
590 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1);
591 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin;
592
593 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks.
594 SSLInfo ssl_info;
595 ssl_info.public_key_hashes.push_back(good_hash);
596 ssl_info.public_key_hashes.push_back(saved_hashes[0]);
597 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
598
599 // Expect the static state to remain unchanged.
600 TransportSecurityState::DomainState new_static_domain_state;
601 EXPECT_TRUE(state.GetStaticDomainState(
602 domain, sni_enabled, &new_static_domain_state));
agl 2014/05/15 00:01:53 EXPECT_EQ(saved_hashes.size(), new_static_domain_s
palmer 2014/05/15 00:22:31 Done.
603 for (size_t i = 0; i < saved_hashes.size(); ++i) {
604 EXPECT_TRUE(HashValuesEqual(saved_hashes[i])(
605 new_static_domain_state.pkp.spki_hashes[i]));
606 }
607
608 // Expect the dynamic state to have pins.
609 TransportSecurityState::DomainState new_dynamic_domain_state;
610 EXPECT_TRUE(state.GetDynamicDomainState(domain, &new_dynamic_domain_state));
611 EXPECT_EQ(2UL, new_dynamic_domain_state.pkp.spki_hashes.size());
612 EXPECT_TRUE(new_dynamic_domain_state.HasPublicKeyPins());
613
614 // Now set another header with max-age=0, and check that the pins are
615 // cleared in the dynamic state only.
616 header = "max-age = 0; " + good_pin + "; " + backup_pin;
617 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
618
619 // Expect the static state to remain unchanged.
620 TransportSecurityState::DomainState new_static_domain_state2;
621 EXPECT_TRUE(state.GetStaticDomainState(
622 domain, sni_enabled, &new_static_domain_state2));
agl 2014/05/15 00:01:53 ditto about checking the length too.
palmer 2014/05/15 00:22:31 Done.
623 for (size_t i = 0; i < saved_hashes.size(); ++i) {
624 EXPECT_TRUE(HashValuesEqual(saved_hashes[i])(
625 new_static_domain_state2.pkp.spki_hashes[i]));
626 }
627
628 // Expect the dynamic pins to be gone.
629 TransportSecurityState::DomainState new_dynamic_domain_state2;
630 EXPECT_FALSE(state.GetDynamicDomainState(domain, &new_dynamic_domain_state2));
631
632 // Expect the exact-matching static policy to continue to apply, even
633 // though dynamic policy has been removed. (This policy may change in the
634 // future, in which case this test must be updated.)
635 EXPECT_TRUE(state.HasPublicKeyPins(domain, true));
636 EXPECT_TRUE(state.ShouldSSLErrorsBeFatal(domain, true));
637 std::string failure_log;
638 // Damage the hashes to cause a pin validation failure.
639 new_static_domain_state2.pkp.spki_hashes[0].data()[0] = 0;
agl 2014/05/15 00:01:53 ^= 0x80 rather than setting the byte to zero as se
640 new_static_domain_state2.pkp.spki_hashes[1].data()[0] = 0;
641 EXPECT_FALSE(state.CheckPublicKeyPins(
642 domain, true, new_static_domain_state2.pkp.spki_hashes, &failure_log));
643 EXPECT_NE(0UL, failure_log.length());
644 }
645
575 // Tests that when a static HSTS and a static HPKP entry are present, adding a 646 // Tests that when a static HSTS and a static HPKP entry are present, adding a
576 // dynamic HSTS header does not clobber the static HPKP entry. Further, adding a 647 // dynamic HSTS header does not clobber the static HPKP entry. Further, adding a
577 // dynamic HPKP entry could not affect the HSTS entry for the site. 648 // dynamic HPKP entry could not affect the HSTS entry for the site.
578 TEST_F(HttpSecurityHeadersTest, NoClobberPins) { 649 TEST_F(HttpSecurityHeadersTest, NoClobberPins) {
579 TransportSecurityState state; 650 TransportSecurityState state;
580 TransportSecurityState::DomainState domain_state; 651 TransportSecurityState::DomainState domain_state;
581 652
582 // accounts.google.com has preloaded pins. 653 // accounts.google.com has preloaded pins.
583 std::string domain = "accounts.google.com"; 654 std::string domain = "accounts.google.com";
584 655
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 // HSTS should still be configured for this domain. 688 // HSTS should still be configured for this domain.
618 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL()); 689 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL());
619 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled)); 690 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled));
620 // The dynamic pins, which do not match |saved_hashes|, should take 691 // The dynamic pins, which do not match |saved_hashes|, should take
621 // precedence over the static pins and cause the check to fail. 692 // precedence over the static pins and cause the check to fail.
622 EXPECT_FALSE(state.CheckPublicKeyPins( 693 EXPECT_FALSE(state.CheckPublicKeyPins(
623 domain, sni_enabled, saved_hashes, &failure_log)); 694 domain, sni_enabled, saved_hashes, &failure_log));
624 } 695 }
625 696
626 }; // namespace net 697 }; // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/http/transport_security_state.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698