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

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

Issue 433123003: Centralize the logic for checking public key pins (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: make IsBuildTimely and ReportUMAOnPinFailure static, as per wtc Created 6 years, 4 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.h » ('j') | net/http/transport_security_state.h » ('J')
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 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
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_pinning_ = 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
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;
558 const bool is_issued_by_known_root = true;
557 EXPECT_TRUE( 559 EXPECT_TRUE(
558 state.CheckPublicKeyPins(domain, sni_enabled, hashes, &failure_log)); 560 state.CheckPublicKeyPins(domain, sni_enabled, is_issued_by_known_root,
561 hashes, &failure_log));
559 562
560 TransportSecurityState::DomainState new_dynamic_domain_state; 563 TransportSecurityState::DomainState new_dynamic_domain_state;
561 EXPECT_TRUE(state.GetDynamicDomainState(domain, &new_dynamic_domain_state)); 564 EXPECT_TRUE(state.GetDynamicDomainState(domain, &new_dynamic_domain_state));
562 EXPECT_EQ(2UL, new_dynamic_domain_state.pkp.spki_hashes.size()); 565 EXPECT_EQ(2UL, new_dynamic_domain_state.pkp.spki_hashes.size());
563 566
564 hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(), 567 hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(),
565 new_dynamic_domain_state.pkp.spki_hashes.end(), 568 new_dynamic_domain_state.pkp.spki_hashes.end(),
566 HashValuesEqual(good_hash)); 569 HashValuesEqual(good_hash));
567 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash); 570 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash);
568 571
569 hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(), 572 hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(),
570 new_dynamic_domain_state.pkp.spki_hashes.end(), 573 new_dynamic_domain_state.pkp.spki_hashes.end(),
571 HashValuesEqual(backup_hash)); 574 HashValuesEqual(backup_hash));
572 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash); 575 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash);
573 } 576 }
574 577
575 // Failing on win_chromium_rel. crbug.com/375538 578 // Failing on win_chromium_rel. crbug.com/375538
576 #if defined(OS_WIN) 579 #if defined(OS_WIN)
577 #define MAYBE_UpdateDynamicPKPMaxAge0 DISABLED_UpdateDynamicPKPMaxAge0 580 #define MAYBE_UpdateDynamicPKPMaxAge0 DISABLED_UpdateDynamicPKPMaxAge0
578 #else 581 #else
579 #define MAYBE_UpdateDynamicPKPMaxAge0 UpdateDynamicPKPMaxAge0 582 #define MAYBE_UpdateDynamicPKPMaxAge0 UpdateDynamicPKPMaxAge0
580 #endif 583 #endif
581 TEST_F(HttpSecurityHeadersTest, MAYBE_UpdateDynamicPKPMaxAge0) { 584 TEST_F(HttpSecurityHeadersTest, MAYBE_UpdateDynamicPKPMaxAge0) {
582 TransportSecurityState state; 585 TransportSecurityState state;
583 TransportSecurityState::DomainState static_domain_state; 586 TransportSecurityState::DomainState static_domain_state;
584 587
585 // docs.google.com has preloaded pins. 588 // docs.google.com has preloaded pins.
586 const bool sni_enabled = true; 589 const bool sni_enabled = true;
587 std::string domain = "docs.google.com"; 590 std::string domain = "docs.google.com";
591 state.enable_static_pinning_ = true;
588 ASSERT_TRUE( 592 ASSERT_TRUE(
589 state.GetStaticDomainState(domain, sni_enabled, &static_domain_state)); 593 state.GetStaticDomainState(domain, sni_enabled, &static_domain_state));
590 EXPECT_GT(static_domain_state.pkp.spki_hashes.size(), 1UL); 594 EXPECT_GT(static_domain_state.pkp.spki_hashes.size(), 1UL);
591 HashValueVector saved_hashes = static_domain_state.pkp.spki_hashes; 595 HashValueVector saved_hashes = static_domain_state.pkp.spki_hashes;
592 596
593 // Add a header, which should only update the dynamic state. 597 // Add a header, which should only update the dynamic state.
594 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1); 598 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1);
595 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1); 599 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1);
596 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1); 600 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1);
597 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin; 601 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 645
642 // Expect the exact-matching static policy to continue to apply, even 646 // Expect the exact-matching static policy to continue to apply, even
643 // though dynamic policy has been removed. (This policy may change in the 647 // though dynamic policy has been removed. (This policy may change in the
644 // future, in which case this test must be updated.) 648 // future, in which case this test must be updated.)
645 EXPECT_TRUE(state.HasPublicKeyPins(domain, true)); 649 EXPECT_TRUE(state.HasPublicKeyPins(domain, true));
646 EXPECT_TRUE(state.ShouldSSLErrorsBeFatal(domain, true)); 650 EXPECT_TRUE(state.ShouldSSLErrorsBeFatal(domain, true));
647 std::string failure_log; 651 std::string failure_log;
648 // Damage the hashes to cause a pin validation failure. 652 // Damage the hashes to cause a pin validation failure.
649 new_static_domain_state2.pkp.spki_hashes[0].data()[0] ^= 0x80; 653 new_static_domain_state2.pkp.spki_hashes[0].data()[0] ^= 0x80;
650 new_static_domain_state2.pkp.spki_hashes[1].data()[0] ^= 0x80; 654 new_static_domain_state2.pkp.spki_hashes[1].data()[0] ^= 0x80;
655 const bool is_issued_by_known_root = true;
651 EXPECT_FALSE(state.CheckPublicKeyPins( 656 EXPECT_FALSE(state.CheckPublicKeyPins(
652 domain, true, new_static_domain_state2.pkp.spki_hashes, &failure_log)); 657 domain, true, is_issued_by_known_root,
658 new_static_domain_state2.pkp.spki_hashes, &failure_log));
653 EXPECT_NE(0UL, failure_log.length()); 659 EXPECT_NE(0UL, failure_log.length());
654 } 660 }
655 #undef MAYBE_UpdateDynamicPKPMaxAge0 661 #undef MAYBE_UpdateDynamicPKPMaxAge0
656 662
657 // Tests that when a static HSTS and a static HPKP entry are present, adding a 663 // 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 664 // 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. 665 // dynamic HPKP entry could not affect the HSTS entry for the site.
660 TEST_F(HttpSecurityHeadersTest, NoClobberPins) { 666 TEST_F(HttpSecurityHeadersTest, NoClobberPins) {
661 TransportSecurityState state; 667 TransportSecurityState state;
662 TransportSecurityState::DomainState domain_state; 668 TransportSecurityState::DomainState domain_state;
663 669
664 // accounts.google.com has preloaded pins. 670 // accounts.google.com has preloaded pins.
665 std::string domain = "accounts.google.com"; 671 std::string domain = "accounts.google.com";
666 672
667 // Retrieve the DomainState as it is by default, including its known good 673 // Retrieve the DomainState as it is by default, including its known good
668 // pins. 674 // pins.
669 const bool sni_enabled = true; 675 const bool sni_enabled = true;
676 state.enable_static_pinning_ = true;
wtc 2014/08/07 23:39:12 Move this to line 671 to stay close to the comment
Ryan Hamilton 2014/08/08 00:54:00 Done.
670 EXPECT_TRUE(state.GetStaticDomainState(domain, sni_enabled, &domain_state)); 677 EXPECT_TRUE(state.GetStaticDomainState(domain, sni_enabled, &domain_state));
671 HashValueVector saved_hashes = domain_state.pkp.spki_hashes; 678 HashValueVector saved_hashes = domain_state.pkp.spki_hashes;
672 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL()); 679 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL());
673 EXPECT_TRUE(domain_state.HasPublicKeyPins()); 680 EXPECT_TRUE(domain_state.HasPublicKeyPins());
674 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled)); 681 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled));
675 EXPECT_TRUE(state.HasPublicKeyPins(domain, sni_enabled)); 682 EXPECT_TRUE(state.HasPublicKeyPins(domain, sni_enabled));
676 683
677 // Add a dynamic HSTS header. CheckPublicKeyPins should still pass when given 684 // Add a dynamic HSTS header. CheckPublicKeyPins should still pass when given
678 // the original |saved_hashes|, indicating that the static PKP data is still 685 // the original |saved_hashes|, indicating that the static PKP data is still
679 // configured for the domain. 686 // configured for the domain.
680 EXPECT_TRUE(state.AddHSTSHeader(domain, "includesubdomains; max-age=10000")); 687 EXPECT_TRUE(state.AddHSTSHeader(domain, "includesubdomains; max-age=10000"));
681 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled)); 688 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled));
682 std::string failure_log; 689 std::string failure_log;
690 const bool is_issued_by_known_root = true;
683 EXPECT_TRUE(state.CheckPublicKeyPins( 691 EXPECT_TRUE(state.CheckPublicKeyPins(
684 domain, sni_enabled, saved_hashes, &failure_log)); 692 domain, sni_enabled, is_issued_by_known_root, saved_hashes,
693 &failure_log));
685 694
686 // Add an HPKP header, which should only update the dynamic state. 695 // Add an HPKP header, which should only update the dynamic state.
687 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1); 696 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1);
688 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1); 697 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1);
689 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1); 698 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1);
690 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin; 699 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin;
691 700
692 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks. 701 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks.
693 SSLInfo ssl_info; 702 SSLInfo ssl_info;
694 ssl_info.public_key_hashes.push_back(good_hash); 703 ssl_info.public_key_hashes.push_back(good_hash);
695 ssl_info.public_key_hashes.push_back(saved_hashes[0]); 704 ssl_info.public_key_hashes.push_back(saved_hashes[0]);
696 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); 705 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
697 706
698 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); 707 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
699 // HSTS should still be configured for this domain. 708 // HSTS should still be configured for this domain.
700 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL()); 709 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL());
701 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled)); 710 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled));
702 // The dynamic pins, which do not match |saved_hashes|, should take 711 // The dynamic pins, which do not match |saved_hashes|, should take
703 // precedence over the static pins and cause the check to fail. 712 // precedence over the static pins and cause the check to fail.
704 EXPECT_FALSE(state.CheckPublicKeyPins( 713 EXPECT_FALSE(state.CheckPublicKeyPins(
705 domain, sni_enabled, saved_hashes, &failure_log)); 714 domain, sni_enabled, is_issued_by_known_root, saved_hashes,
715 &failure_log));
706 } 716 }
707 717
708 }; // namespace net 718 }; // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/http/transport_security_state.h » ('j') | net/http/transport_security_state.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698