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

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: Rebase and updated comment. Created 6 years, 9 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 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 domain_state;
454 454
455 // docs.google.com has preloaded pins. 455 // docs.google.com has preloaded pins.
456 std::string domain = "docs.google.com"; 456 std::string domain = "docs.google.com";
457 EXPECT_TRUE(state.GetDomainState(domain, true, &domain_state)); 457 EXPECT_TRUE(state.GetDomainState(domain, true, &domain_state));
458 EXPECT_GT(domain_state.static_spki_hashes.size(), 1UL); 458 EXPECT_GT(domain_state.static_pkp.spki_hashes.size(), 1UL);
459 HashValueVector saved_hashes = domain_state.static_spki_hashes; 459 HashValueVector saved_hashes = domain_state.static_pkp.spki_hashes;
460 460
461 // Add a header, which should only update the dynamic state. 461 // Add a header, which should only update the dynamic state.
462 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1); 462 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1);
463 HashValue backup_hash = GetTestHashValue(2, HASH_VALUE_SHA1); 463 HashValue backup_hash = GetTestHashValue(2, HASH_VALUE_SHA1);
464 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1); 464 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1);
465 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1); 465 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1);
466 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin; 466 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin;
467 467
468 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks. 468 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks.
469 SSLInfo ssl_info; 469 SSLInfo ssl_info;
470 ssl_info.public_key_hashes.push_back(good_hash); 470 ssl_info.public_key_hashes.push_back(good_hash);
471 ssl_info.public_key_hashes.push_back(saved_hashes[0]); 471 ssl_info.public_key_hashes.push_back(saved_hashes[0]);
472 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info)); 472 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
473 473
474 // Expect the preloaded state to remain unchanged. 474 // Expect the preloaded state to remain unchanged.
475 std::string canonicalized_host = TransportSecurityState::CanonicalizeHost( 475 std::string canonicalized_host = TransportSecurityState::CanonicalizeHost(
476 domain); 476 domain);
477 TransportSecurityState::DomainState static_domain_state; 477 TransportSecurityState::DomainState static_domain_state;
478 EXPECT_TRUE(state.GetStaticDomainState(canonicalized_host, 478 EXPECT_TRUE(state.GetStaticDomainState(canonicalized_host,
479 true, 479 true,
480 &static_domain_state)); 480 &static_domain_state));
481 for (size_t i = 0; i < saved_hashes.size(); ++i) { 481 for (size_t i = 0; i < saved_hashes.size(); ++i) {
482 EXPECT_TRUE(HashValuesEqual( 482 EXPECT_TRUE(HashValuesEqual(
483 saved_hashes[i])(static_domain_state.static_spki_hashes[i])); 483 saved_hashes[i])(static_domain_state.static_pkp.spki_hashes[i]));
484 } 484 }
485 485
486 // Expect the dynamic state to reflect the header. 486 // Expect the dynamic state to reflect the header.
487 TransportSecurityState::DomainState dynamic_domain_state; 487 TransportSecurityState::DomainState dynamic_domain_state;
488 EXPECT_TRUE(state.GetDynamicDomainState(domain, &dynamic_domain_state)); 488 EXPECT_TRUE(state.GetDynamicDomainState(domain, &dynamic_domain_state));
489 EXPECT_EQ(2UL, dynamic_domain_state.dynamic_spki_hashes.size()); 489 EXPECT_EQ(2UL, dynamic_domain_state.dynamic_pkp.spki_hashes.size());
490 490
491 HashValueVector::const_iterator hash = std::find_if( 491 HashValueVector::const_iterator hash = std::find_if(
492 dynamic_domain_state.dynamic_spki_hashes.begin(), 492 dynamic_domain_state.dynamic_pkp.spki_hashes.begin(),
493 dynamic_domain_state.dynamic_spki_hashes.end(), 493 dynamic_domain_state.dynamic_pkp.spki_hashes.end(),
494 HashValuesEqual(good_hash)); 494 HashValuesEqual(good_hash));
495 EXPECT_NE(dynamic_domain_state.dynamic_spki_hashes.end(), hash); 495 EXPECT_NE(dynamic_domain_state.dynamic_pkp.spki_hashes.end(), hash);
496 496
497 hash = std::find_if( 497 hash = std::find_if(
498 dynamic_domain_state.dynamic_spki_hashes.begin(), 498 dynamic_domain_state.dynamic_pkp.spki_hashes.begin(),
499 dynamic_domain_state.dynamic_spki_hashes.end(), 499 dynamic_domain_state.dynamic_pkp.spki_hashes.end(),
500 HashValuesEqual(backup_hash)); 500 HashValuesEqual(backup_hash));
501 EXPECT_NE(dynamic_domain_state.dynamic_spki_hashes.end(), hash); 501 EXPECT_NE(dynamic_domain_state.dynamic_pkp.spki_hashes.end(), hash);
502 502
503 // Expect the overall state to reflect the header, too. 503 // Expect the overall state to reflect the header, too.
504 EXPECT_TRUE(state.GetDomainState(domain, true, &domain_state)); 504 EXPECT_TRUE(state.GetDomainState(domain, true, &domain_state));
505 EXPECT_EQ(2UL, domain_state.dynamic_spki_hashes.size()); 505 EXPECT_EQ(2UL, domain_state.dynamic_pkp.spki_hashes.size());
506 506
507 hash = std::find_if(domain_state.dynamic_spki_hashes.begin(), 507 hash = std::find_if(domain_state.dynamic_pkp.spki_hashes.begin(),
508 domain_state.dynamic_spki_hashes.end(), 508 domain_state.dynamic_pkp.spki_hashes.end(),
509 HashValuesEqual(good_hash)); 509 HashValuesEqual(good_hash));
510 EXPECT_NE(domain_state.dynamic_spki_hashes.end(), hash); 510 EXPECT_NE(domain_state.dynamic_pkp.spki_hashes.end(), hash);
511 511
512 hash = std::find_if( 512 hash = std::find_if(
513 domain_state.dynamic_spki_hashes.begin(), 513 domain_state.dynamic_pkp.spki_hashes.begin(),
514 domain_state.dynamic_spki_hashes.end(), 514 domain_state.dynamic_pkp.spki_hashes.end(),
515 HashValuesEqual(backup_hash)); 515 HashValuesEqual(backup_hash));
516 EXPECT_NE(domain_state.dynamic_spki_hashes.end(), hash); 516 EXPECT_NE(domain_state.dynamic_pkp.spki_hashes.end(), hash);
517 }
518
519 TEST_F(HttpSecurityHeadersTest, NoClobberPins) {
520 TransportSecurityState state;
521 TransportSecurityState::DomainState domain_state;
522
523 std::string domain("accounts.google.com");
Ryan Sleevi 2014/03/07 01:39:19 Use the same form as the other tests? See line 456
palmer 2014/03/14 21:33:39 Done.
524
525 // Retrieve the DomainState as it is by default, including its known good
526 // pins. Assert sanity.
Ryan Sleevi 2014/03/07 01:39:19 "Assert sanity" is superflous.
palmer 2014/03/14 21:33:39 Done.
527 EXPECT_TRUE(state.GetDomainState(domain, true, &domain_state));
528 HashValueVector saved_hashes = domain_state.static_pkp.spki_hashes;
529 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL());
530 EXPECT_TRUE(domain_state.HasPublicKeyPins());
531
532 // Add a dynamic header. CheckPublicKeyPins (invoked below).
533 // CheckPublicKeyPins should still pass when given the original
534 // |saved_hashes|, indicating that CheckPublicKeyPins can still access and
535 // check the static_pkp data.
Ryan Sleevi 2014/03/07 01:39:19 Rework this comment: // Add a dynamic HSTS header
palmer 2014/03/14 21:33:39 Done.
536 EXPECT_TRUE(state.AddHSTSHeader(domain, "includesubdomains; max-age=10000"));
537 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL());
538 EXPECT_TRUE(state.GetDomainState(domain, true, &domain_state));
539 EXPECT_TRUE(domain_state.CheckPublicKeyPins(saved_hashes));
540
541 // Add a header, which should only update the dynamic state.
542 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1);
543 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1);
544 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1);
545 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin;
Ryan Sleevi 2014/03/07 01:39:19 // Add a HPKP header, which should only update the
palmer 2014/03/14 21:33:39 Done.
546
547 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks.
548 SSLInfo ssl_info;
549 ssl_info.public_key_hashes.push_back(good_hash);
550 ssl_info.public_key_hashes.push_back(saved_hashes[0]);
551 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
552
553 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
554 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL());
Ryan Sleevi 2014/03/07 01:39:19 // HSTS should still be configured for this domain
palmer 2014/03/14 21:33:39 Done.
555 EXPECT_TRUE(state.GetDomainState(domain, true, &domain_state));
556 EXPECT_TRUE(domain_state.CheckPublicKeyPins(saved_hashes));
Ryan Sleevi 2014/03/07 01:39:19 What are you testing here? Add a comment. 1) Shou
palmer 2014/03/14 21:33:39 It's to check that a good pin is still valid. Adde
517 } 557 }
518 558
519 }; // namespace net 559 }; // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698