Chromium Code Reviews| 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 <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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |