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

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

Issue 103803012: Make HSTS headers not clobber preloaded pins. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix browser_tests by setting the domain name correctly. Rebase. Created 6 years, 8 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
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 432 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 TEST_F(HttpSecurityHeadersTest, ValidPKPHeadersSHA1) { 443 TEST_F(HttpSecurityHeadersTest, ValidPKPHeadersSHA1) {
444 TestValidPKPHeaders(HASH_VALUE_SHA1); 444 TestValidPKPHeaders(HASH_VALUE_SHA1);
445 } 445 }
446 446
447 TEST_F(HttpSecurityHeadersTest, ValidPKPHeadersSHA256) { 447 TEST_F(HttpSecurityHeadersTest, ValidPKPHeadersSHA256) {
448 TestValidPKPHeaders(HASH_VALUE_SHA256); 448 TestValidPKPHeaders(HASH_VALUE_SHA256);
449 } 449 }
450 450
451 TEST_F(HttpSecurityHeadersTest, UpdateDynamicPKPOnly) { 451 TEST_F(HttpSecurityHeadersTest, UpdateDynamicPKPOnly) {
452 TransportSecurityState state; 452 TransportSecurityState state;
453 TransportSecurityState::DomainState domain_state; 453 TransportSecurityState::DomainState static_domain_state;
454 454
455 // docs.google.com has preloaded pins. 455 // docs.google.com has preloaded pins.
456 const bool sni_enabled = true;
456 std::string domain = "docs.google.com"; 457 std::string domain = "docs.google.com";
457 EXPECT_TRUE(state.GetDomainState(domain, true, &domain_state)); 458 EXPECT_TRUE(
458 EXPECT_GT(domain_state.static_spki_hashes.size(), 1UL); 459 state.GetStaticDomainState(domain, sni_enabled, &static_domain_state));
459 HashValueVector saved_hashes = domain_state.static_spki_hashes; 460 EXPECT_GT(static_domain_state.pkp.spki_hashes.size(), 1UL);
461 HashValueVector saved_hashes = static_domain_state.pkp.spki_hashes;
460 462
461 // Add a header, which should only update the dynamic state. 463 // Add a header, which should only update the dynamic state.
462 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1); 464 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1);
463 HashValue backup_hash = GetTestHashValue(2, HASH_VALUE_SHA1); 465 HashValue backup_hash = GetTestHashValue(2, HASH_VALUE_SHA1);
464 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1); 466 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1);
465 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1); 467 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1);
466 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin; 468 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin;
467 469
468 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks. 470 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks.
469 SSLInfo ssl_info; 471 SSLInfo ssl_info;
470 ssl_info.public_key_hashes.push_back(good_hash); 472 ssl_info.public_key_hashes.push_back(good_hash);
471 ssl_info.public_key_hashes.push_back(saved_hashes[0]); 473 ssl_info.public_key_hashes.push_back(saved_hashes[0]);
472 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); 474 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
473 475
474 // Expect the preloaded state to remain unchanged. 476 // Expect the static state to remain unchanged.
475 std::string canonicalized_host = TransportSecurityState::CanonicalizeHost( 477 TransportSecurityState::DomainState new_static_domain_state;
476 domain); 478 EXPECT_TRUE(state.GetStaticDomainState(
477 TransportSecurityState::DomainState static_domain_state; 479 domain, sni_enabled, &new_static_domain_state));
478 EXPECT_TRUE(state.GetStaticDomainState(canonicalized_host,
479 true,
480 &static_domain_state));
481 for (size_t i = 0; i < saved_hashes.size(); ++i) { 480 for (size_t i = 0; i < saved_hashes.size(); ++i) {
482 EXPECT_TRUE(HashValuesEqual( 481 EXPECT_TRUE(HashValuesEqual(saved_hashes[i])(
483 saved_hashes[i])(static_domain_state.static_spki_hashes[i])); 482 new_static_domain_state.pkp.spki_hashes[i]));
484 } 483 }
485 484
486 // Expect the dynamic state to reflect the header. 485 // Expect the dynamic state to reflect the header.
487 TransportSecurityState::DomainState dynamic_domain_state; 486 TransportSecurityState::DomainState dynamic_domain_state;
488 EXPECT_TRUE(state.GetDynamicDomainState(domain, &dynamic_domain_state)); 487 EXPECT_TRUE(state.GetDynamicDomainState(domain, &dynamic_domain_state));
489 EXPECT_EQ(2UL, dynamic_domain_state.dynamic_spki_hashes.size()); 488 EXPECT_EQ(2UL, dynamic_domain_state.pkp.spki_hashes.size());
490 489
491 HashValueVector::const_iterator hash = std::find_if( 490 HashValueVector::const_iterator hash =
492 dynamic_domain_state.dynamic_spki_hashes.begin(), 491 std::find_if(dynamic_domain_state.pkp.spki_hashes.begin(),
493 dynamic_domain_state.dynamic_spki_hashes.end(), 492 dynamic_domain_state.pkp.spki_hashes.end(),
494 HashValuesEqual(good_hash)); 493 HashValuesEqual(good_hash));
495 EXPECT_NE(dynamic_domain_state.dynamic_spki_hashes.end(), hash); 494 EXPECT_NE(dynamic_domain_state.pkp.spki_hashes.end(), hash);
496 495
497 hash = std::find_if( 496 hash = std::find_if(dynamic_domain_state.pkp.spki_hashes.begin(),
498 dynamic_domain_state.dynamic_spki_hashes.begin(), 497 dynamic_domain_state.pkp.spki_hashes.end(),
499 dynamic_domain_state.dynamic_spki_hashes.end(), 498 HashValuesEqual(backup_hash));
500 HashValuesEqual(backup_hash)); 499 EXPECT_NE(dynamic_domain_state.pkp.spki_hashes.end(), hash);
501 EXPECT_NE(dynamic_domain_state.dynamic_spki_hashes.end(), hash);
502 500
503 // Expect the overall state to reflect the header, too. 501 // Expect the overall state to reflect the header, too.
504 EXPECT_TRUE(state.GetDomainState(domain, true, &domain_state)); 502 EXPECT_TRUE(state.HasPublicKeyPins(domain, sni_enabled));
505 EXPECT_EQ(2UL, domain_state.dynamic_spki_hashes.size()); 503 HashValueVector hashes;
504 hashes.push_back(good_hash);
505 std::string failure_log;
506 EXPECT_TRUE(
507 state.CheckPublicKeyPins(domain, sni_enabled, hashes, &failure_log));
506 508
507 hash = std::find_if(domain_state.dynamic_spki_hashes.begin(), 509 TransportSecurityState::DomainState new_dynamic_domain_state;
508 domain_state.dynamic_spki_hashes.end(), 510 EXPECT_TRUE(state.GetDynamicDomainState(domain, &new_dynamic_domain_state));
511 EXPECT_EQ(2UL, new_dynamic_domain_state.pkp.spki_hashes.size());
512
513 hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(),
514 new_dynamic_domain_state.pkp.spki_hashes.end(),
509 HashValuesEqual(good_hash)); 515 HashValuesEqual(good_hash));
510 EXPECT_NE(domain_state.dynamic_spki_hashes.end(), hash); 516 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash);
511 517
512 hash = std::find_if( 518 hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(),
513 domain_state.dynamic_spki_hashes.begin(), 519 new_dynamic_domain_state.pkp.spki_hashes.end(),
514 domain_state.dynamic_spki_hashes.end(), 520 HashValuesEqual(backup_hash));
515 HashValuesEqual(backup_hash)); 521 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash);
516 EXPECT_NE(domain_state.dynamic_spki_hashes.end(), hash); 522 }
523
524 TEST_F(HttpSecurityHeadersTest, NoClobberPins) {
Ryan Sleevi 2014/04/24 21:40:21 Document test // Tests that when a static HSTS an
palmer 2014/04/25 00:59:59 Done.
525 TransportSecurityState state;
526 TransportSecurityState::DomainState domain_state;
527
528 // accounts.google.com has preloaded pins.
529 std::string domain = "accounts.google.com";
530
531 // Retrieve the DomainState as it is by default, including its known good
532 // pins.
533 const bool sni_enabled = true;
534 EXPECT_TRUE(state.GetStaticDomainState(domain, sni_enabled, &domain_state));
535 HashValueVector saved_hashes = domain_state.pkp.spki_hashes;
536 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL());
537 EXPECT_TRUE(domain_state.HasPublicKeyPins());
538 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled));
539 EXPECT_TRUE(state.HasPublicKeyPins(domain, sni_enabled));
540
541 // Add a dynamic HSTS header. CheckPublicKeyPins should still pass when given
542 // the original |saved_hashes|, indicating that the static PKP data is still
543 // configured for the domain.
544 EXPECT_TRUE(state.AddHSTSHeader(domain, "includesubdomains; max-age=10000"));
545 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled));
546 std::string failure_log;
547 EXPECT_TRUE(state.CheckPublicKeyPins(
548 domain, sni_enabled, saved_hashes, &failure_log));
549
550 // Add an HPKP header, which should only update the dynamic state.
551 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1);
552 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1);
553 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1);
554 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin;
555
556 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks.
557 SSLInfo ssl_info;
558 ssl_info.public_key_hashes.push_back(good_hash);
559 ssl_info.public_key_hashes.push_back(saved_hashes[0]);
560 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
561
562 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
563 // HSTS should still be configured for this domain.
564 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL());
565 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled));
566 // Check that a good pin is still valid.
567 EXPECT_TRUE(state.CheckPublicKeyPins(
568 domain, sni_enabled, saved_hashes, &failure_log));
517 } 569 }
518 570
519 }; // namespace net 571 }; // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698