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 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
499 TestValidPKPHeaders(HASH_VALUE_SHA256); | 499 TestValidPKPHeaders(HASH_VALUE_SHA256); |
500 } | 500 } |
501 | 501 |
502 TEST_F(HttpSecurityHeadersTest, UpdateDynamicPKPOnly) { | 502 TEST_F(HttpSecurityHeadersTest, UpdateDynamicPKPOnly) { |
503 TransportSecurityState state; | 503 TransportSecurityState state; |
504 TransportSecurityState::DomainState static_domain_state; | 504 TransportSecurityState::DomainState static_domain_state; |
505 | 505 |
506 // docs.google.com has preloaded pins. | 506 // docs.google.com has preloaded pins. |
507 const bool sni_enabled = true; | 507 const bool sni_enabled = true; |
508 std::string domain = "docs.google.com"; | 508 std::string domain = "docs.google.com"; |
| 509 state.enable_static_pins_ = true; |
509 EXPECT_TRUE( | 510 EXPECT_TRUE( |
510 state.GetStaticDomainState(domain, sni_enabled, &static_domain_state)); | 511 state.GetStaticDomainState(domain, sni_enabled, &static_domain_state)); |
511 EXPECT_GT(static_domain_state.pkp.spki_hashes.size(), 1UL); | 512 EXPECT_GT(static_domain_state.pkp.spki_hashes.size(), 1UL); |
512 HashValueVector saved_hashes = static_domain_state.pkp.spki_hashes; | 513 HashValueVector saved_hashes = static_domain_state.pkp.spki_hashes; |
513 | 514 |
514 // Add a header, which should only update the dynamic state. | 515 // Add a header, which should only update the dynamic state. |
515 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1); | 516 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1); |
516 HashValue backup_hash = GetTestHashValue(2, HASH_VALUE_SHA1); | 517 HashValue backup_hash = GetTestHashValue(2, HASH_VALUE_SHA1); |
517 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1); | 518 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1); |
518 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1); | 519 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1); |
(...skipping 28 matching lines...) Expand all Loading... |
547 hash = std::find_if(dynamic_domain_state.pkp.spki_hashes.begin(), | 548 hash = std::find_if(dynamic_domain_state.pkp.spki_hashes.begin(), |
548 dynamic_domain_state.pkp.spki_hashes.end(), | 549 dynamic_domain_state.pkp.spki_hashes.end(), |
549 HashValuesEqual(backup_hash)); | 550 HashValuesEqual(backup_hash)); |
550 EXPECT_NE(dynamic_domain_state.pkp.spki_hashes.end(), hash); | 551 EXPECT_NE(dynamic_domain_state.pkp.spki_hashes.end(), hash); |
551 | 552 |
552 // Expect the overall state to reflect the header, too. | 553 // Expect the overall state to reflect the header, too. |
553 EXPECT_TRUE(state.HasPublicKeyPins(domain, sni_enabled)); | 554 EXPECT_TRUE(state.HasPublicKeyPins(domain, sni_enabled)); |
554 HashValueVector hashes; | 555 HashValueVector hashes; |
555 hashes.push_back(good_hash); | 556 hashes.push_back(good_hash); |
556 std::string failure_log; | 557 std::string failure_log; |
557 EXPECT_TRUE( | 558 const bool is_issued_by_known_root = true; |
558 state.CheckPublicKeyPins(domain, sni_enabled, hashes, &failure_log)); | 559 EXPECT_TRUE(state.CheckPublicKeyPins( |
| 560 domain, sni_enabled, is_issued_by_known_root, hashes, &failure_log)); |
559 | 561 |
560 TransportSecurityState::DomainState new_dynamic_domain_state; | 562 TransportSecurityState::DomainState new_dynamic_domain_state; |
561 EXPECT_TRUE(state.GetDynamicDomainState(domain, &new_dynamic_domain_state)); | 563 EXPECT_TRUE(state.GetDynamicDomainState(domain, &new_dynamic_domain_state)); |
562 EXPECT_EQ(2UL, new_dynamic_domain_state.pkp.spki_hashes.size()); | 564 EXPECT_EQ(2UL, new_dynamic_domain_state.pkp.spki_hashes.size()); |
563 | 565 |
564 hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(), | 566 hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(), |
565 new_dynamic_domain_state.pkp.spki_hashes.end(), | 567 new_dynamic_domain_state.pkp.spki_hashes.end(), |
566 HashValuesEqual(good_hash)); | 568 HashValuesEqual(good_hash)); |
567 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash); | 569 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash); |
568 | 570 |
569 hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(), | 571 hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(), |
570 new_dynamic_domain_state.pkp.spki_hashes.end(), | 572 new_dynamic_domain_state.pkp.spki_hashes.end(), |
571 HashValuesEqual(backup_hash)); | 573 HashValuesEqual(backup_hash)); |
572 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash); | 574 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash); |
573 } | 575 } |
574 | 576 |
575 // Failing on win_chromium_rel. crbug.com/375538 | 577 // Failing on win_chromium_rel. crbug.com/375538 |
576 #if defined(OS_WIN) | 578 #if defined(OS_WIN) |
577 #define MAYBE_UpdateDynamicPKPMaxAge0 DISABLED_UpdateDynamicPKPMaxAge0 | 579 #define MAYBE_UpdateDynamicPKPMaxAge0 DISABLED_UpdateDynamicPKPMaxAge0 |
578 #else | 580 #else |
579 #define MAYBE_UpdateDynamicPKPMaxAge0 UpdateDynamicPKPMaxAge0 | 581 #define MAYBE_UpdateDynamicPKPMaxAge0 UpdateDynamicPKPMaxAge0 |
580 #endif | 582 #endif |
581 TEST_F(HttpSecurityHeadersTest, MAYBE_UpdateDynamicPKPMaxAge0) { | 583 TEST_F(HttpSecurityHeadersTest, MAYBE_UpdateDynamicPKPMaxAge0) { |
582 TransportSecurityState state; | 584 TransportSecurityState state; |
583 TransportSecurityState::DomainState static_domain_state; | 585 TransportSecurityState::DomainState static_domain_state; |
584 | 586 |
585 // docs.google.com has preloaded pins. | 587 // docs.google.com has preloaded pins. |
586 const bool sni_enabled = true; | 588 const bool sni_enabled = true; |
587 std::string domain = "docs.google.com"; | 589 std::string domain = "docs.google.com"; |
| 590 state.enable_static_pins_ = true; |
588 ASSERT_TRUE( | 591 ASSERT_TRUE( |
589 state.GetStaticDomainState(domain, sni_enabled, &static_domain_state)); | 592 state.GetStaticDomainState(domain, sni_enabled, &static_domain_state)); |
590 EXPECT_GT(static_domain_state.pkp.spki_hashes.size(), 1UL); | 593 EXPECT_GT(static_domain_state.pkp.spki_hashes.size(), 1UL); |
591 HashValueVector saved_hashes = static_domain_state.pkp.spki_hashes; | 594 HashValueVector saved_hashes = static_domain_state.pkp.spki_hashes; |
592 | 595 |
593 // Add a header, which should only update the dynamic state. | 596 // Add a header, which should only update the dynamic state. |
594 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1); | 597 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1); |
595 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1); | 598 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1); |
596 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1); | 599 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1); |
597 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin; | 600 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
641 | 644 |
642 // Expect the exact-matching static policy to continue to apply, even | 645 // Expect the exact-matching static policy to continue to apply, even |
643 // though dynamic policy has been removed. (This policy may change in the | 646 // though dynamic policy has been removed. (This policy may change in the |
644 // future, in which case this test must be updated.) | 647 // future, in which case this test must be updated.) |
645 EXPECT_TRUE(state.HasPublicKeyPins(domain, true)); | 648 EXPECT_TRUE(state.HasPublicKeyPins(domain, true)); |
646 EXPECT_TRUE(state.ShouldSSLErrorsBeFatal(domain, true)); | 649 EXPECT_TRUE(state.ShouldSSLErrorsBeFatal(domain, true)); |
647 std::string failure_log; | 650 std::string failure_log; |
648 // Damage the hashes to cause a pin validation failure. | 651 // Damage the hashes to cause a pin validation failure. |
649 new_static_domain_state2.pkp.spki_hashes[0].data()[0] ^= 0x80; | 652 new_static_domain_state2.pkp.spki_hashes[0].data()[0] ^= 0x80; |
650 new_static_domain_state2.pkp.spki_hashes[1].data()[0] ^= 0x80; | 653 new_static_domain_state2.pkp.spki_hashes[1].data()[0] ^= 0x80; |
651 EXPECT_FALSE(state.CheckPublicKeyPins( | 654 const bool is_issued_by_known_root = true; |
652 domain, true, new_static_domain_state2.pkp.spki_hashes, &failure_log)); | 655 EXPECT_FALSE( |
| 656 state.CheckPublicKeyPins(domain, |
| 657 true, |
| 658 is_issued_by_known_root, |
| 659 new_static_domain_state2.pkp.spki_hashes, |
| 660 &failure_log)); |
653 EXPECT_NE(0UL, failure_log.length()); | 661 EXPECT_NE(0UL, failure_log.length()); |
654 } | 662 } |
655 #undef MAYBE_UpdateDynamicPKPMaxAge0 | 663 #undef MAYBE_UpdateDynamicPKPMaxAge0 |
656 | 664 |
657 // Tests that when a static HSTS and a static HPKP entry are present, adding a | 665 // Tests that when a static HSTS and a static HPKP entry are present, adding a |
658 // dynamic HSTS header does not clobber the static HPKP entry. Further, adding a | 666 // dynamic HSTS header does not clobber the static HPKP entry. Further, adding a |
659 // dynamic HPKP entry could not affect the HSTS entry for the site. | 667 // dynamic HPKP entry could not affect the HSTS entry for the site. |
660 TEST_F(HttpSecurityHeadersTest, NoClobberPins) { | 668 TEST_F(HttpSecurityHeadersTest, NoClobberPins) { |
661 TransportSecurityState state; | 669 TransportSecurityState state; |
662 TransportSecurityState::DomainState domain_state; | 670 TransportSecurityState::DomainState domain_state; |
663 | 671 |
664 // accounts.google.com has preloaded pins. | 672 // accounts.google.com has preloaded pins. |
665 std::string domain = "accounts.google.com"; | 673 std::string domain = "accounts.google.com"; |
| 674 state.enable_static_pins_ = true; |
666 | 675 |
667 // Retrieve the DomainState as it is by default, including its known good | 676 // Retrieve the DomainState as it is by default, including its known good |
668 // pins. | 677 // pins. |
669 const bool sni_enabled = true; | 678 const bool sni_enabled = true; |
670 EXPECT_TRUE(state.GetStaticDomainState(domain, sni_enabled, &domain_state)); | 679 EXPECT_TRUE(state.GetStaticDomainState(domain, sni_enabled, &domain_state)); |
671 HashValueVector saved_hashes = domain_state.pkp.spki_hashes; | 680 HashValueVector saved_hashes = domain_state.pkp.spki_hashes; |
672 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL()); | 681 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL()); |
673 EXPECT_TRUE(domain_state.HasPublicKeyPins()); | 682 EXPECT_TRUE(domain_state.HasPublicKeyPins()); |
674 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled)); | 683 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled)); |
675 EXPECT_TRUE(state.HasPublicKeyPins(domain, sni_enabled)); | 684 EXPECT_TRUE(state.HasPublicKeyPins(domain, sni_enabled)); |
676 | 685 |
677 // Add a dynamic HSTS header. CheckPublicKeyPins should still pass when given | 686 // Add a dynamic HSTS header. CheckPublicKeyPins should still pass when given |
678 // the original |saved_hashes|, indicating that the static PKP data is still | 687 // the original |saved_hashes|, indicating that the static PKP data is still |
679 // configured for the domain. | 688 // configured for the domain. |
680 EXPECT_TRUE(state.AddHSTSHeader(domain, "includesubdomains; max-age=10000")); | 689 EXPECT_TRUE(state.AddHSTSHeader(domain, "includesubdomains; max-age=10000")); |
681 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled)); | 690 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled)); |
682 std::string failure_log; | 691 std::string failure_log; |
683 EXPECT_TRUE(state.CheckPublicKeyPins( | 692 const bool is_issued_by_known_root = true; |
684 domain, sni_enabled, saved_hashes, &failure_log)); | 693 EXPECT_TRUE(state.CheckPublicKeyPins(domain, |
| 694 sni_enabled, |
| 695 is_issued_by_known_root, |
| 696 saved_hashes, |
| 697 &failure_log)); |
685 | 698 |
686 // Add an HPKP header, which should only update the dynamic state. | 699 // Add an HPKP header, which should only update the dynamic state. |
687 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1); | 700 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1); |
688 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1); | 701 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1); |
689 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1); | 702 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1); |
690 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin; | 703 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin; |
691 | 704 |
692 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks. | 705 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks. |
693 SSLInfo ssl_info; | 706 SSLInfo ssl_info; |
694 ssl_info.public_key_hashes.push_back(good_hash); | 707 ssl_info.public_key_hashes.push_back(good_hash); |
695 ssl_info.public_key_hashes.push_back(saved_hashes[0]); | 708 ssl_info.public_key_hashes.push_back(saved_hashes[0]); |
696 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); | 709 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); |
697 | 710 |
698 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); | 711 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); |
699 // HSTS should still be configured for this domain. | 712 // HSTS should still be configured for this domain. |
700 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL()); | 713 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL()); |
701 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled)); | 714 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled)); |
702 // The dynamic pins, which do not match |saved_hashes|, should take | 715 // The dynamic pins, which do not match |saved_hashes|, should take |
703 // precedence over the static pins and cause the check to fail. | 716 // precedence over the static pins and cause the check to fail. |
704 EXPECT_FALSE(state.CheckPublicKeyPins( | 717 EXPECT_FALSE(state.CheckPublicKeyPins(domain, |
705 domain, sni_enabled, saved_hashes, &failure_log)); | 718 sni_enabled, |
| 719 is_issued_by_known_root, |
| 720 saved_hashes, |
| 721 &failure_log)); |
706 } | 722 } |
707 | 723 |
708 }; // namespace net | 724 }; // namespace net |
OLD | NEW |