diff options
author | cevans@chromium.org <cevans@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-09 19:55:00 +0000 |
---|---|---|
committer | cevans@chromium.org <cevans@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-09 19:55:00 +0000 |
commit | 55cb2118814170e24069cff71ca7f22d7a8bd51d (patch) | |
tree | 9a365f99f21c39ebf74b515fbca87ea83ab82d4d /net | |
parent | 27072cad3c586ef5949d06041de9233d6d6cacae (diff) | |
download | chromium_src-55cb2118814170e24069cff71ca7f22d7a8bd51d.zip chromium_src-55cb2118814170e24069cff71ca7f22d7a8bd51d.tar.gz chromium_src-55cb2118814170e24069cff71ca7f22d7a8bd51d.tar.bz2 |
Make sure that the built-in pins for *.google.com don't prevent non-built-in
subdomains from turning on mode="strict" HSTS.
TEST=TransportSecurityStateTest.OverrideBuiltins
Review URL: http://codereview.chromium.org/6965001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@84659 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/base/transport_security_state.cc | 27 | ||||
-rw-r--r-- | net/base/transport_security_state_unittest.cc | 18 |
2 files changed, 31 insertions, 14 deletions
diff --git a/net/base/transport_security_state.cc b/net/base/transport_security_state.cc index 62bfd40..56ae1df 100644 --- a/net/base/transport_security_state.cc +++ b/net/base/transport_security_state.cc @@ -46,9 +46,11 @@ void TransportSecurityState::EnableHost(const std::string& host, // TODO(cevans) -- we likely want to permit a host to override a built-in, // for at least the case where the override is stricter (i.e. includes // subdomains, or includes certificate pinning). - DomainState temp; - if (IsPreloadedSTS(canonicalized_host, true, &temp)) + DomainState out; + if (IsPreloadedSTS(canonicalized_host, true, &out) && + canonicalized_host == CanonicalizeHost(out.domain)) { return; + } // Use the original creation date if we already have this host. DomainState state_copy(state); @@ -79,12 +81,6 @@ bool TransportSecurityState::DeleteHost(const std::string& host) { return false; } -// IncludeNUL converts a char* to a std::string and includes the terminating -// NUL in the result. -static std::string IncludeNUL(const char* in) { - return std::string(in, strlen(in) + 1); -} - bool TransportSecurityState::HasPinsForHost(DomainState* result, const std::string& host, bool sni_available) { @@ -108,16 +104,20 @@ bool TransportSecurityState::HasMetadata(DomainState* result, if (canonicalized_host.empty()) return false; - if (IsPreloadedSTS(canonicalized_host, sni_available, result)) - return true; + bool has_preload = IsPreloadedSTS(canonicalized_host, sni_available, result); + std::string canonicalized_preload = CanonicalizeHost(result->domain); base::Time current_time(base::Time::Now()); for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) { - std::string hashed_domain(HashHost(IncludeNUL(&canonicalized_host[i]))); + std::string host_sub_chunk(&canonicalized_host[i], + canonicalized_host.size() - i); + // Exact match of a preload always wins. + if (has_preload && host_sub_chunk == canonicalized_preload) + return true; std::map<std::string, DomainState>::iterator j = - enabled_hosts_.find(hashed_domain); + enabled_hosts_.find(HashHost(host_sub_chunk)); if (j == enabled_hosts_.end()) continue; @@ -128,8 +128,7 @@ bool TransportSecurityState::HasMetadata(DomainState* result, } *result = j->second; - result->domain = DNSDomainToString( - canonicalized_host.substr(i, canonicalized_host.size() - i)); + result->domain = DNSDomainToString(host_sub_chunk); // If we matched the domain exactly, it doesn't matter what the value of // include_subdomains is. diff --git a/net/base/transport_security_state_unittest.cc b/net/base/transport_security_state_unittest.cc index e666bc0..4f4cf24 100644 --- a/net/base/transport_security_state_unittest.cc +++ b/net/base/transport_security_state_unittest.cc @@ -728,4 +728,22 @@ TEST_F(TransportSecurityStateTest, ForcePreloads) { EXPECT_FALSE(state->IsEnabledForHost(&domain_state, "docs.google.com", true)); } +TEST_F(TransportSecurityStateTest, OverrideBuiltins) { + scoped_refptr<TransportSecurityState> state( + new TransportSecurityState(std::string())); + + TransportSecurityState::DomainState domain_state; + EXPECT_TRUE(state->HasPinsForHost(&domain_state, "google.com", true)); + EXPECT_FALSE(state->IsEnabledForHost(&domain_state, "google.com", true)); + EXPECT_FALSE(state->IsEnabledForHost(&domain_state, "www.google.com", true)); + + domain_state = TransportSecurityState::DomainState(); + const base::Time current_time(base::Time::Now()); + const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); + domain_state.expiry = expiry; + state->EnableHost("www.google.com", domain_state); + + EXPECT_TRUE(state->IsEnabledForHost(&domain_state, "www.google.com", true)); +} + } // namespace net |