summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorcevans@chromium.org <cevans@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-09 19:55:00 +0000
committercevans@chromium.org <cevans@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-09 19:55:00 +0000
commit55cb2118814170e24069cff71ca7f22d7a8bd51d (patch)
tree9a365f99f21c39ebf74b515fbca87ea83ab82d4d /net
parent27072cad3c586ef5949d06041de9233d6d6cacae (diff)
downloadchromium_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.cc27
-rw-r--r--net/base/transport_security_state_unittest.cc18
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