| Index: net/http/transport_security_state_unittest.cc
|
| diff --git a/net/http/transport_security_state_unittest.cc b/net/http/transport_security_state_unittest.cc
|
| index b9369faaf8339d10d85385b6ce57401d40e85424..44fc2d67d44efff67b6b9c38423a56e561619a4b 100644
|
| --- a/net/http/transport_security_state_unittest.cc
|
| +++ b/net/http/transport_security_state_unittest.cc
|
| @@ -55,42 +55,42 @@ class TransportSecurityStateTest : public testing::Test {
|
| state->enable_static_pins_ = true;
|
| }
|
|
|
| + static HashValueVector GetSampleSPKIHashes() {
|
| + HashValueVector spki_hashes;
|
| + HashValue hash(HASH_VALUE_SHA1);
|
| + memset(hash.data(), 0, hash.size());
|
| + spki_hashes.push_back(hash);
|
| + return spki_hashes;
|
| + }
|
| +
|
| protected:
|
| bool GetStaticDomainState(TransportSecurityState* state,
|
| const std::string& host,
|
| TransportSecurityState::DomainState* result) {
|
| return state->GetStaticDomainState(host, result);
|
| }
|
| -
|
| - void EnableHost(TransportSecurityState* state,
|
| - const std::string& host,
|
| - const TransportSecurityState::DomainState& domain_state) {
|
| - return state->EnableHost(host, domain_state);
|
| - }
|
| };
|
|
|
| TEST_F(TransportSecurityStateTest, SimpleMatches) {
|
| TransportSecurityState state;
|
| - TransportSecurityState::DomainState domain_state;
|
| const base::Time current_time(base::Time::Now());
|
| const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
|
|
|
| - EXPECT_FALSE(state.GetDynamicDomainState("yahoo.com", &domain_state));
|
| + EXPECT_FALSE(state.ShouldUpgradeToSSL("yahoo.com"));
|
| bool include_subdomains = false;
|
| state.AddHSTS("yahoo.com", expiry, include_subdomains);
|
| - EXPECT_TRUE(state.GetDynamicDomainState("yahoo.com", &domain_state));
|
| + EXPECT_TRUE(state.ShouldUpgradeToSSL("yahoo.com"));
|
| }
|
|
|
| TEST_F(TransportSecurityStateTest, MatchesCase1) {
|
| TransportSecurityState state;
|
| - TransportSecurityState::DomainState domain_state;
|
| const base::Time current_time(base::Time::Now());
|
| const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
|
|
|
| - EXPECT_FALSE(state.GetDynamicDomainState("yahoo.com", &domain_state));
|
| + EXPECT_FALSE(state.ShouldUpgradeToSSL("yahoo.com"));
|
| bool include_subdomains = false;
|
| state.AddHSTS("YAhoo.coM", expiry, include_subdomains);
|
| - EXPECT_TRUE(state.GetDynamicDomainState("yahoo.com", &domain_state));
|
| + EXPECT_TRUE(state.ShouldUpgradeToSSL("yahoo.com"));
|
| }
|
|
|
| TEST_F(TransportSecurityStateTest, Fuzz) {
|
| @@ -117,80 +117,238 @@ TEST_F(TransportSecurityStateTest, Fuzz) {
|
|
|
| TEST_F(TransportSecurityStateTest, MatchesCase2) {
|
| TransportSecurityState state;
|
| - TransportSecurityState::DomainState domain_state;
|
| const base::Time current_time(base::Time::Now());
|
| const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
|
|
|
| - EXPECT_FALSE(state.GetDynamicDomainState("YAhoo.coM", &domain_state));
|
| + EXPECT_FALSE(state.ShouldUpgradeToSSL("YAhoo.coM"));
|
| bool include_subdomains = false;
|
| state.AddHSTS("yahoo.com", expiry, include_subdomains);
|
| - EXPECT_TRUE(state.GetDynamicDomainState("YAhoo.coM", &domain_state));
|
| + EXPECT_TRUE(state.ShouldUpgradeToSSL("YAhoo.coM"));
|
| }
|
|
|
| TEST_F(TransportSecurityStateTest, SubdomainMatches) {
|
| TransportSecurityState state;
|
| - TransportSecurityState::DomainState domain_state;
|
| const base::Time current_time(base::Time::Now());
|
| const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
|
|
|
| - EXPECT_FALSE(state.GetDynamicDomainState("yahoo.com", &domain_state));
|
| + EXPECT_FALSE(state.ShouldUpgradeToSSL("yahoo.com"));
|
| bool include_subdomains = true;
|
| state.AddHSTS("yahoo.com", expiry, include_subdomains);
|
| - EXPECT_TRUE(state.GetDynamicDomainState("yahoo.com", &domain_state));
|
| - EXPECT_TRUE(state.GetDynamicDomainState("foo.yahoo.com", &domain_state));
|
| - EXPECT_TRUE(state.GetDynamicDomainState("foo.bar.yahoo.com", &domain_state));
|
| - EXPECT_TRUE(
|
| - state.GetDynamicDomainState("foo.bar.baz.yahoo.com", &domain_state));
|
| - EXPECT_FALSE(state.GetDynamicDomainState("com", &domain_state));
|
| + EXPECT_TRUE(state.ShouldUpgradeToSSL("yahoo.com"));
|
| + EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.yahoo.com"));
|
| + EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.bar.yahoo.com"));
|
| + EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.bar.baz.yahoo.com"));
|
| + EXPECT_FALSE(state.ShouldUpgradeToSSL("com"));
|
| + EXPECT_FALSE(state.ShouldUpgradeToSSL("notyahoo.com"));
|
| +}
|
| +
|
| +TEST_F(TransportSecurityStateTest, FatalSSLErrors) {
|
| + TransportSecurityState state;
|
| + const base::Time current_time(base::Time::Now());
|
| + const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
|
| +
|
| + state.AddHSTS("example1.com", expiry, false);
|
| + state.AddHPKP("example2.com", expiry, false, GetSampleSPKIHashes());
|
| +
|
| + // The presense of either HSTS or HPKP is enough to make SSL errors fatal.
|
| + EXPECT_TRUE(state.ShouldSSLErrorsBeFatal("example1.com"));
|
| + EXPECT_TRUE(state.ShouldSSLErrorsBeFatal("example2.com"));
|
| +}
|
| +
|
| +// Tests that HPKP and HSTS state both expire. Also tests that expired entries
|
| +// are pruned.
|
| +TEST_F(TransportSecurityStateTest, Expiration) {
|
| + TransportSecurityState state;
|
| + const base::Time current_time(base::Time::Now());
|
| + const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
|
| + const base::Time older = current_time - base::TimeDelta::FromSeconds(1000);
|
| +
|
| + // Note: this test assumes that inserting an entry with an expiration time in
|
| + // the past works and is pruned on query.
|
| + state.AddHSTS("example1.com", older, false);
|
| + EXPECT_TRUE(TransportSecurityState::Iterator(state).HasNext());
|
| + EXPECT_FALSE(state.ShouldUpgradeToSSL("example1.com"));
|
| + // Querying |state| for a domain should flush out expired entries.
|
| + EXPECT_FALSE(TransportSecurityState::Iterator(state).HasNext());
|
| +
|
| + state.AddHPKP("example1.com", older, false, GetSampleSPKIHashes());
|
| + EXPECT_TRUE(TransportSecurityState::Iterator(state).HasNext());
|
| + EXPECT_FALSE(state.HasPublicKeyPins("example1.com"));
|
| + // Querying |state| for a domain should flush out expired entries.
|
| + EXPECT_FALSE(TransportSecurityState::Iterator(state).HasNext());
|
| +
|
| + state.AddHSTS("example1.com", older, false);
|
| + state.AddHPKP("example1.com", older, false, GetSampleSPKIHashes());
|
| + EXPECT_TRUE(TransportSecurityState::Iterator(state).HasNext());
|
| + EXPECT_FALSE(state.ShouldSSLErrorsBeFatal("example1.com"));
|
| + // Querying |state| for a domain should flush out expired entries.
|
| + EXPECT_FALSE(TransportSecurityState::Iterator(state).HasNext());
|
| +
|
| + // Test that HSTS can outlive HPKP.
|
| + state.AddHSTS("example1.com", expiry, false);
|
| + state.AddHPKP("example1.com", older, false, GetSampleSPKIHashes());
|
| + EXPECT_TRUE(state.ShouldUpgradeToSSL("example1.com"));
|
| + EXPECT_FALSE(state.HasPublicKeyPins("example1.com"));
|
| +
|
| + // Test that HPKP can outlive HSTS.
|
| + state.AddHSTS("example2.com", older, false);
|
| + state.AddHPKP("example2.com", expiry, false, GetSampleSPKIHashes());
|
| + EXPECT_FALSE(state.ShouldUpgradeToSSL("example2.com"));
|
| + EXPECT_TRUE(state.HasPublicKeyPins("example2.com"));
|
| }
|
|
|
| TEST_F(TransportSecurityStateTest, InvalidDomains) {
|
| TransportSecurityState state;
|
| - TransportSecurityState::DomainState domain_state;
|
| const base::Time current_time(base::Time::Now());
|
| const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
|
|
|
| - EXPECT_FALSE(state.GetDynamicDomainState("yahoo.com", &domain_state));
|
| + EXPECT_FALSE(state.ShouldUpgradeToSSL("yahoo.com"));
|
| bool include_subdomains = true;
|
| state.AddHSTS("yahoo.com", expiry, include_subdomains);
|
| - EXPECT_TRUE(state.GetDynamicDomainState("www-.foo.yahoo.com", &domain_state));
|
| - EXPECT_TRUE(
|
| - state.GetDynamicDomainState("2\x01.foo.yahoo.com", &domain_state));
|
| + EXPECT_TRUE(state.ShouldUpgradeToSSL("www-.foo.yahoo.com"));
|
| + EXPECT_TRUE(state.ShouldUpgradeToSSL("2\x01.foo.yahoo.com"));
|
| }
|
|
|
| -TEST_F(TransportSecurityStateTest, DeleteAllDynamicDataSince) {
|
| +// Tests that HPKP and HSTS state are queried independently for subdomain
|
| +// matches.
|
| +TEST_F(TransportSecurityStateTest, IndependentSubdomain) {
|
| + TransportSecurityState state;
|
| + const base::Time current_time(base::Time::Now());
|
| + const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
|
| +
|
| + state.AddHSTS("example1.com", expiry, true);
|
| + state.AddHPKP("example1.com", expiry, false, GetSampleSPKIHashes());
|
| +
|
| + state.AddHSTS("example2.com", expiry, false);
|
| + state.AddHPKP("example2.com", expiry, true, GetSampleSPKIHashes());
|
| +
|
| + EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.example1.com"));
|
| + EXPECT_FALSE(state.HasPublicKeyPins("foo.example1.com"));
|
| + EXPECT_FALSE(state.ShouldUpgradeToSSL("foo.example2.com"));
|
| + EXPECT_TRUE(state.HasPublicKeyPins("foo.example2.com"));
|
| +}
|
| +
|
| +// Tests that HPKP and HSTS state are inserted and overridden independently.
|
| +TEST_F(TransportSecurityStateTest, IndependentInsertion) {
|
| + TransportSecurityState state;
|
| + const base::Time current_time(base::Time::Now());
|
| + const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
|
| +
|
| + // Place an includeSubdomains HSTS entry below a normal HPKP entry.
|
| + state.AddHSTS("example1.com", expiry, true);
|
| + state.AddHPKP("foo.example1.com", expiry, false, GetSampleSPKIHashes());
|
| +
|
| + EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.example1.com"));
|
| + EXPECT_TRUE(state.HasPublicKeyPins("foo.example1.com"));
|
| + EXPECT_TRUE(state.ShouldUpgradeToSSL("example1.com"));
|
| + EXPECT_FALSE(state.HasPublicKeyPins("example1.com"));
|
| +
|
| + // Drop the includeSubdomains from the HSTS entry.
|
| + state.AddHSTS("example1.com", expiry, false);
|
| +
|
| + EXPECT_FALSE(state.ShouldUpgradeToSSL("foo.example1.com"));
|
| + EXPECT_TRUE(state.HasPublicKeyPins("foo.example1.com"));
|
| +
|
| + // Place an includeSubdomains HPKP entry below a normal HSTS entry.
|
| + state.AddHSTS("foo.example2.com", expiry, false);
|
| + state.AddHPKP("example2.com", expiry, true, GetSampleSPKIHashes());
|
| +
|
| + EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.example2.com"));
|
| + EXPECT_TRUE(state.HasPublicKeyPins("foo.example2.com"));
|
| +
|
| + // Drop the includeSubdomains from the HSTS entry.
|
| + state.AddHPKP("example2.com", expiry, false, GetSampleSPKIHashes());
|
| +
|
| + EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.example2.com"));
|
| + EXPECT_FALSE(state.HasPublicKeyPins("foo.example2.com"));
|
| +}
|
| +
|
| +// Tests that GetDynamicDomainState appropriately stitches together the results
|
| +// of HSTS and HPKP.
|
| +TEST_F(TransportSecurityStateTest, DynamicDomainState) {
|
| + TransportSecurityState state;
|
| + const base::Time current_time(base::Time::Now());
|
| + const base::Time expiry1 = current_time + base::TimeDelta::FromSeconds(1000);
|
| + const base::Time expiry2 = current_time + base::TimeDelta::FromSeconds(2000);
|
| +
|
| + state.AddHSTS("example.com", expiry1, true);
|
| + state.AddHPKP("foo.example.com", expiry2, false, GetSampleSPKIHashes());
|
| +
|
| + TransportSecurityState::DomainState domain_state;
|
| + ASSERT_TRUE(state.GetDynamicDomainState("foo.example.com", &domain_state));
|
| + EXPECT_TRUE(domain_state.ShouldUpgradeToSSL());
|
| + EXPECT_TRUE(domain_state.HasPublicKeyPins());
|
| + EXPECT_TRUE(domain_state.sts.include_subdomains);
|
| + EXPECT_FALSE(domain_state.pkp.include_subdomains);
|
| + EXPECT_EQ(expiry1, domain_state.sts.expiry);
|
| + EXPECT_EQ(expiry2, domain_state.pkp.expiry);
|
| + EXPECT_EQ("example.com", domain_state.sts.domain);
|
| + EXPECT_EQ("foo.example.com", domain_state.pkp.domain);
|
| +}
|
| +
|
| +// Tests that new pins always override previous pins. This should be true for
|
| +// both pins at the same domain or includeSubdomains pins at a parent domain.
|
| +TEST_F(TransportSecurityStateTest, NewPinsOverride) {
|
| TransportSecurityState state;
|
| TransportSecurityState::DomainState domain_state;
|
| const base::Time current_time(base::Time::Now());
|
| const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
|
| + HashValue hash1(HASH_VALUE_SHA1);
|
| + memset(hash1.data(), 0x01, hash1.size());
|
| + HashValue hash2(HASH_VALUE_SHA1);
|
| + memset(hash2.data(), 0x02, hash1.size());
|
| + HashValue hash3(HASH_VALUE_SHA1);
|
| + memset(hash3.data(), 0x03, hash1.size());
|
| +
|
| + state.AddHPKP("example.com", expiry, true, HashValueVector(1, hash1));
|
| +
|
| + ASSERT_TRUE(state.GetDynamicDomainState("foo.example.com", &domain_state));
|
| + ASSERT_EQ(1u, domain_state.pkp.spki_hashes.size());
|
| + EXPECT_TRUE(domain_state.pkp.spki_hashes[0].Equals(hash1));
|
| +
|
| + state.AddHPKP("foo.example.com", expiry, false, HashValueVector(1, hash2));
|
| +
|
| + ASSERT_TRUE(state.GetDynamicDomainState("foo.example.com", &domain_state));
|
| + ASSERT_EQ(1u, domain_state.pkp.spki_hashes.size());
|
| + EXPECT_TRUE(domain_state.pkp.spki_hashes[0].Equals(hash2));
|
| +
|
| + state.AddHPKP("foo.example.com", expiry, false, HashValueVector(1, hash3));
|
| +
|
| + ASSERT_TRUE(state.GetDynamicDomainState("foo.example.com", &domain_state));
|
| + ASSERT_EQ(1u, domain_state.pkp.spki_hashes.size());
|
| + EXPECT_TRUE(domain_state.pkp.spki_hashes[0].Equals(hash3));
|
| +}
|
| +
|
| +TEST_F(TransportSecurityStateTest, DeleteAllDynamicDataSince) {
|
| + TransportSecurityState state;
|
| + const base::Time current_time(base::Time::Now());
|
| + const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
|
| const base::Time older = current_time - base::TimeDelta::FromSeconds(1000);
|
|
|
| - EXPECT_FALSE(state.GetDynamicDomainState("yahoo.com", &domain_state));
|
| + EXPECT_FALSE(state.ShouldUpgradeToSSL("yahoo.com"));
|
| bool include_subdomains = false;
|
| state.AddHSTS("yahoo.com", expiry, include_subdomains);
|
|
|
| state.DeleteAllDynamicDataSince(expiry);
|
| - EXPECT_TRUE(state.GetDynamicDomainState("yahoo.com", &domain_state));
|
| - EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS,
|
| - domain_state.sts.upgrade_mode);
|
| + EXPECT_TRUE(state.ShouldUpgradeToSSL("yahoo.com"));
|
| state.DeleteAllDynamicDataSince(older);
|
| - EXPECT_TRUE(state.GetDynamicDomainState("yahoo.com", &domain_state));
|
| - EXPECT_EQ(TransportSecurityState::DomainState::MODE_DEFAULT,
|
| - domain_state.sts.upgrade_mode);
|
| + EXPECT_FALSE(state.ShouldUpgradeToSSL("yahoo.com"));
|
| +
|
| + // |state| should be empty now.
|
| + EXPECT_FALSE(TransportSecurityState::Iterator(state).HasNext());
|
| }
|
|
|
| TEST_F(TransportSecurityStateTest, DeleteDynamicDataForHost) {
|
| TransportSecurityState state;
|
| - TransportSecurityState::DomainState domain_state;
|
| const base::Time current_time(base::Time::Now());
|
| const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
|
| bool include_subdomains = false;
|
| state.AddHSTS("yahoo.com", expiry, include_subdomains);
|
|
|
| - EXPECT_TRUE(state.GetDynamicDomainState("yahoo.com", &domain_state));
|
| - EXPECT_FALSE(state.GetDynamicDomainState("example.com", &domain_state));
|
| + EXPECT_TRUE(state.ShouldUpgradeToSSL("yahoo.com"));
|
| + EXPECT_FALSE(state.ShouldUpgradeToSSL("example.com"));
|
| EXPECT_TRUE(state.DeleteDynamicDataForHost("yahoo.com"));
|
| - EXPECT_FALSE(state.GetDynamicDomainState("yahoo.com", &domain_state));
|
| + EXPECT_FALSE(state.ShouldUpgradeToSSL("yahoo.com"));
|
| }
|
|
|
| TEST_F(TransportSecurityStateTest, EnableStaticPins) {
|
| @@ -243,10 +401,12 @@ TEST_F(TransportSecurityStateTest, PreloadedDomainSet) {
|
| // chrome://net-internals/#hsts UI. So test that.
|
| EXPECT_TRUE(
|
| state.GetStaticDomainState("market.android.com", &domain_state));
|
| - EXPECT_EQ(domain_state.domain, "market.android.com");
|
| + EXPECT_EQ(domain_state.sts.domain, "market.android.com");
|
| + EXPECT_EQ(domain_state.pkp.domain, "market.android.com");
|
| EXPECT_TRUE(state.GetStaticDomainState(
|
| "sub.market.android.com", &domain_state));
|
| - EXPECT_EQ(domain_state.domain, "market.android.com");
|
| + EXPECT_EQ(domain_state.sts.domain, "market.android.com");
|
| + EXPECT_EQ(domain_state.pkp.domain, "market.android.com");
|
| }
|
|
|
| static bool StaticShouldRedirect(const char* hostname) {
|
| @@ -697,13 +857,11 @@ TEST_F(TransportSecurityStateTest, OverrideBuiltins) {
|
| EXPECT_FALSE(StaticShouldRedirect("www.google.com"));
|
|
|
| TransportSecurityState state;
|
| - TransportSecurityState::DomainState domain_state;
|
| const base::Time current_time(base::Time::Now());
|
| const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
|
| - domain_state.sts.expiry = expiry;
|
| - EnableHost(&state, "www.google.com", domain_state);
|
| + state.AddHSTS("www.google.com", expiry, true);
|
|
|
| - EXPECT_TRUE(state.GetDynamicDomainState("www.google.com", &domain_state));
|
| + EXPECT_TRUE(state.ShouldUpgradeToSSL("www.google.com"));
|
| }
|
|
|
| TEST_F(TransportSecurityStateTest, GooglePinnedProperties) {
|
|
|