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

Unified Diff: net/http/transport_security_state_unittest.cc

Issue 826423009: Treat HSTS and HPKP state independently. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rsleevi comments Created 5 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/http/transport_security_state.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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) {
« no previous file with comments | « net/http/transport_security_state.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698