summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/base/transport_security_state.cc55
-rw-r--r--net/base/transport_security_state.h144
-rw-r--r--net/base/transport_security_state_unittest.cc83
-rw-r--r--net/url_request/url_request_unittest.cc8
-rw-r--r--net/websockets/websocket_job_spdy2_unittest.cc8
-rw-r--r--net/websockets/websocket_job_spdy3_unittest.cc8
6 files changed, 196 insertions, 110 deletions
diff --git a/net/base/transport_security_state.cc b/net/base/transport_security_state.cc
index d61c0fb..50b4dac 100644
--- a/net/base/transport_security_state.cc
+++ b/net/base/transport_security_state.cc
@@ -126,14 +126,14 @@ void TransportSecurityState::EnableHost(const std::string& host,
DirtyNotify();
}
-bool TransportSecurityState::DeleteHost(const std::string& host) {
+bool TransportSecurityState::DeleteDynamicDataForHost(const std::string& host) {
DCHECK(CalledOnValidThread());
const std::string canonicalized_host = CanonicalizeHost(host);
if (canonicalized_host.empty())
return false;
- std::map<std::string, DomainState>::iterator i = enabled_hosts_.find(
+ DomainStateMap::iterator i = enabled_hosts_.find(
HashHost(canonicalized_host));
if (i != enabled_hosts_.end()) {
enabled_hosts_.erase(i);
@@ -168,7 +168,7 @@ bool TransportSecurityState::GetDomainState(const std::string& host,
return true;
}
- std::map<std::string, DomainState>::iterator j =
+ DomainStateMap::iterator j =
enabled_hosts_.find(HashHost(host_sub_chunk));
if (j == enabled_hosts_.end())
continue;
@@ -196,12 +196,16 @@ bool TransportSecurityState::GetDomainState(const std::string& host,
return false;
}
-void TransportSecurityState::DeleteSince(const base::Time& time) {
+void TransportSecurityState::ClearDynamicData() {
+ enabled_hosts_.clear();
+}
+
+void TransportSecurityState::DeleteAllDynamicDataSince(const base::Time& time) {
DCHECK(CalledOnValidThread());
bool dirtied = false;
- std::map<std::string, DomainState>::iterator i = enabled_hosts_.begin();
+ DomainStateMap::iterator i = enabled_hosts_.begin();
while (i != enabled_hosts_.end()) {
if (i->second.created >= time) {
dirtied = true;
@@ -641,6 +645,47 @@ bool TransportSecurityState::AddHPKPHeader(const std::string& host,
return false;
}
+bool TransportSecurityState::AddHSTS(const std::string& host,
+ const base::Time& expiry,
+ bool include_subdomains) {
+ // Copy-and-modify the existing DomainState for this host (if any).
+ TransportSecurityState::DomainState domain_state;
+ const std::string canonicalized_host = CanonicalizeHost(host);
+ const std::string hashed_host = HashHost(canonicalized_host);
+ DomainStateMap::const_iterator i = enabled_hosts_.find(
+ hashed_host);
+ if (i != enabled_hosts_.end())
+ domain_state = i->second;
+
+ domain_state.created = base::Time::Now();
+ domain_state.include_subdomains = include_subdomains;
+ domain_state.upgrade_expiry = expiry;
+ domain_state.upgrade_mode = DomainState::MODE_FORCE_HTTPS;
+ EnableHost(host, domain_state);
+ return true;
+}
+
+bool TransportSecurityState::AddHPKP(const std::string& host,
+ const base::Time& expiry,
+ bool include_subdomains,
+ const HashValueVector& hashes) {
+ // Copy-and-modify the existing DomainState for this host (if any).
+ TransportSecurityState::DomainState domain_state;
+ const std::string canonicalized_host = CanonicalizeHost(host);
+ const std::string hashed_host = HashHost(canonicalized_host);
+ DomainStateMap::const_iterator i = enabled_hosts_.find(
+ hashed_host);
+ if (i != enabled_hosts_.end())
+ domain_state = i->second;
+
+ domain_state.created = base::Time::Now();
+ domain_state.include_subdomains = include_subdomains;
+ domain_state.dynamic_spki_hashes_expiry = expiry;
+ domain_state.dynamic_spki_hashes = hashes;
+ EnableHost(host, domain_state);
+ return true;
+}
+
// static
bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host,
bool sni_enabled) {
diff --git a/net/base/transport_security_state.h b/net/base/transport_security_state.h
index ca9dec4..8eb76d1 100644
--- a/net/base/transport_security_state.h
+++ b/net/base/transport_security_state.h
@@ -158,24 +158,51 @@ class NET_EXPORT TransportSecurityState
};
// Assign a |Delegate| for persisting the transport security state. If
- // |NULL|, state will not be persisted. Caller owns |delegate|.
+ // |NULL|, state will not be persisted. The caller retains
+ // ownership of |delegate|.
+ // Note: This is only used for serializing/deserializing the
+ // TransportSecurityState.
void SetDelegate(Delegate* delegate);
- // Enable TransportSecurity for |host|. |state| supercedes any previous
- // state for the |host|, including static entries.
+ // Clears all dynamic data (e.g. HSTS and HPKP data).
//
- // The new state for |host| is persisted using the Delegate (if any).
- void EnableHost(const std::string& host, const DomainState& state);
+ // Does NOT persist changes using the Delegate, as this function is only
+ // used to clear any dynamic data prior to re-loading it from a file.
+ // Note: This is only used for serializing/deserializing the
+ // TransportSecurityState.
+ void ClearDynamicData();
- // Delete any entry for |host|. If |host| doesn't have an exact entry then
- // no action is taken. Does not delete static entries. Returns true iff an
- // entry was deleted.
- //
- // The new state for |host| is persisted using the Delegate (if any).
- bool DeleteHost(const std::string& host);
+ // Inserts |state| into |enabled_hosts_| under the key |hashed_host|.
+ // |hashed_host| is already in the internal representation
+ // HashHost(CanonicalizeHost(host)).
+ // Note: This is only used for serializing/deserializing the
+ // TransportSecurityState.
+ void AddOrUpdateEnabledHosts(const std::string& hashed_host,
+ const DomainState& state);
+
+ // Inserts |state| into |forced_hosts_| under the key |hashed_host|.
+ // |hashed_host| is already in the internal representation
+ // HashHost(CanonicalizeHost(host)).
+ // Note: This is only used for serializing/deserializing the
+ // TransportSecurityState.
+ void AddOrUpdateForcedHosts(const std::string& hashed_host,
+ const DomainState& state);
- // Deletes all records created since a given time.
- void DeleteSince(const base::Time& time);
+ // Deletes all dynamic data (e.g. HSTS or HPKP data) created since a given
+ // time.
+ //
+ // If any entries are deleted, the new state will be persisted through
+ // the Delegate (if any).
+ void DeleteAllDynamicDataSince(const base::Time& time);
+
+ // Deletes any dynamic data stored for |host| (e.g. HSTS or HPKP data).
+ // If |host| doesn't have an exact entry then no action is taken. Does
+ // not delete static (i.e. preloaded) data. Returns true iff an entry
+ // was deleted.
+ //
+ // If an entry is deleted, the new state will be persisted through
+ // the Delegate (if any).
+ bool DeleteDynamicDataForHost(const std::string& host);
// Returns true and updates |*result| iff there is a DomainState for
// |host|.
@@ -192,42 +219,6 @@ class NET_EXPORT TransportSecurityState
bool sni_enabled,
DomainState* result);
- // Returns true and updates |*result| iff there is a static DomainState for
- // |host|.
- //
- // |GetStaticDomainState| is identical to |GetDomainState| except that it
- // searches only the statically-defined transport security state, ignoring
- // all dynamically-added DomainStates.
- //
- // If |sni_enabled| is true, searches the static pins defined for
- // SNI-using hosts as well as the rest of the pins.
- //
- // If |host| matches both an exact entry and is a subdomain of another
- // entry, the exact match determines the return value.
- //
- // Note that this method is not const because it opportunistically removes
- // entries that have expired.
- bool GetStaticDomainState(const std::string& host,
- bool sni_enabled,
- DomainState* result);
-
- // Removed all DomainState records.
- void Clear() { enabled_hosts_.clear(); }
-
- // Inserts |state| into |enabled_hosts_| under the key |hashed_host|.
- // |hashed_host| is already in the internal representation
- // HashHost(CanonicalizeHost(host)); thus, most callers will use
- // |EnableHost|.
- void AddOrUpdateEnabledHosts(const std::string& hashed_host,
- const DomainState& state);
-
- // Inserts |state| into |forced_hosts_| under the key |hashed_host|.
- // |hashed_host| is already in the internal representation
- // HashHost(CanonicalizeHost(host)); thus, most callers will use
- // |EnableHost|.
- void AddOrUpdateForcedHosts(const std::string& hashed_host,
- const DomainState& state);
-
// Processes an HSTS header value from the host, adding entries to
// dynamic state if necessary.
bool AddHSTSHeader(const std::string& host, const std::string& value);
@@ -238,6 +229,16 @@ class NET_EXPORT TransportSecurityState
bool AddHPKPHeader(const std::string& host, const std::string& value,
const SSLInfo& ssl_info);
+ // Adds explicitly-specified data as if it was processed from an
+ // HSTS header (used for net-internals and unit tests).
+ bool AddHSTS(const std::string& host, const base::Time& expiry,
+ bool include_subdomains);
+
+ // Adds explicitly-specified data as if it was processed from an
+ // HPKP header (used for net-internals and unit tests).
+ bool AddHPKP(const std::string& host, const base::Time& expiry,
+ bool include_subdomains, const HashValueVector& hashes);
+
// Returns true iff we have any static public key pins for the |host| and
// iff its set of required pins is the set we expect for Google
// properties.
@@ -253,11 +254,6 @@ class NET_EXPORT TransportSecurityState
// The maximum number of seconds for which we'll cache an HSTS request.
static const long int kMaxHSTSAgeSecs;
- // Converts |hostname| from dotted form ("www.google.com") to the form
- // used in DNS: "\x03www\x06google\x03com", lowercases that, and returns
- // the result.
- static std::string CanonicalizeHost(const std::string& hostname);
-
// Send an UMA report on pin validation failure, if the host is in a
// statically-defined list of domains.
//
@@ -268,24 +264,56 @@ class NET_EXPORT TransportSecurityState
// to the caller with |GetStaticDomainState|.
static void ReportUMAOnPinFailure(const std::string& host);
- static const char* HashValueLabel(const HashValue& hash_value);
-
// IsBuildTimely returns true if the current build is new enough ensure that
// built in security information (i.e. HSTS preloading and pinning
// information) is timely.
static bool IsBuildTimely();
private:
+ friend class TransportSecurityStateTest;
+
+ typedef std::map<std::string, DomainState> DomainStateMap;
+
// If a Delegate is present, notify it that the internal state has
// changed.
void DirtyNotify();
+ // Enable TransportSecurity for |host|. |state| supercedes any previous
+ // state for the |host|, including static entries.
+ //
+ // The new state for |host| is persisted using the Delegate (if any).
+ void EnableHost(const std::string& host, const DomainState& state);
+
+ // Converts |hostname| from dotted form ("www.google.com") to the form
+ // used in DNS: "\x03www\x06google\x03com", lowercases that, and returns
+ // the result.
+ static std::string CanonicalizeHost(const std::string& hostname);
+
+ // Returns true and updates |*result| iff there is a static DomainState for
+ // |host|.
+ //
+ // |GetStaticDomainState| is identical to |GetDomainState| except that it
+ // searches only the statically-defined transport security state, ignoring
+ // all dynamically-added DomainStates.
+ //
+ // If |sni_enabled| is true, searches the static pins defined for
+ // SNI-using hosts as well as the rest of the pins.
+ //
+ // If |host| matches both an exact entry and is a subdomain of another
+ // entry, the exact match determines the return value.
+ //
+ // Note that this method is not const because it opportunistically removes
+ // entries that have expired.
+ bool GetStaticDomainState(const std::string& host,
+ bool sni_enabled,
+ DomainState* result);
+
// The set of hosts that have enabled TransportSecurity.
- std::map<std::string, DomainState> enabled_hosts_;
+ DomainStateMap enabled_hosts_;
// Extra entries, provided by the user at run-time, to treat as if they
// were static.
- std::map<std::string, DomainState> forced_hosts_;
+ DomainStateMap forced_hosts_;
Delegate* delegate_;
diff --git a/net/base/transport_security_state_unittest.cc b/net/base/transport_security_state_unittest.cc
index 025faea..0d0a58f 100644
--- a/net/base/transport_security_state_unittest.cc
+++ b/net/base/transport_security_state_unittest.cc
@@ -44,6 +44,24 @@ class TransportSecurityStateTest : public testing::Test {
crypto::EnsureNSSInit();
#endif
}
+
+ protected:
+ std::string CanonicalizeHost(const std::string& host) {
+ return TransportSecurityState::CanonicalizeHost(host);
+ }
+
+ bool GetStaticDomainState(TransportSecurityState* state,
+ const std::string& host,
+ bool sni_enabled,
+ TransportSecurityState::DomainState* result) {
+ return state->GetStaticDomainState(host, sni_enabled, result);
+ }
+
+ void EnableHost(TransportSecurityState* state,
+ const std::string& host,
+ const TransportSecurityState::DomainState& domain_state) {
+ return state->EnableHost(host, domain_state);
+ }
};
TEST_F(TransportSecurityStateTest, SimpleMatches) {
@@ -53,8 +71,8 @@ TEST_F(TransportSecurityStateTest, SimpleMatches) {
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state));
- domain_state.upgrade_expiry = expiry;
- state.EnableHost("yahoo.com", domain_state);
+ bool include_subdomains = false;
+ state.AddHSTS("yahoo.com", expiry, include_subdomains);
EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state));
}
@@ -65,8 +83,8 @@ TEST_F(TransportSecurityStateTest, MatchesCase1) {
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state));
- domain_state.upgrade_expiry = expiry;
- state.EnableHost("YAhoo.coM", domain_state);
+ bool include_subdomains = false;
+ state.AddHSTS("YAhoo.coM", expiry, include_subdomains);
EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state));
}
@@ -77,8 +95,8 @@ TEST_F(TransportSecurityStateTest, MatchesCase2) {
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
EXPECT_FALSE(state.GetDomainState("YAhoo.coM", true, &domain_state));
- domain_state.upgrade_expiry = expiry;
- state.EnableHost("yahoo.com", domain_state);
+ bool include_subdomains = false;
+ state.AddHSTS("yahoo.com", expiry, include_subdomains);
EXPECT_TRUE(state.GetDomainState("YAhoo.coM", true, &domain_state));
}
@@ -89,9 +107,8 @@ TEST_F(TransportSecurityStateTest, SubdomainMatches) {
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state));
- domain_state.upgrade_expiry = expiry;
- domain_state.include_subdomains = true;
- state.EnableHost("yahoo.com", domain_state);
+ bool include_subdomains = true;
+ state.AddHSTS("yahoo.com", expiry, include_subdomains);
EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state));
EXPECT_TRUE(state.GetDomainState("foo.yahoo.com", true, &domain_state));
EXPECT_TRUE(state.GetDomainState("foo.bar.yahoo.com", true, &domain_state));
@@ -100,7 +117,7 @@ TEST_F(TransportSecurityStateTest, SubdomainMatches) {
EXPECT_FALSE(state.GetDomainState("com", true, &domain_state));
}
-TEST_F(TransportSecurityStateTest, DeleteSince) {
+TEST_F(TransportSecurityStateTest, DeleteAllDynamicDataSince) {
TransportSecurityState state;
TransportSecurityState::DomainState domain_state;
const base::Time current_time(base::Time::Now());
@@ -108,57 +125,53 @@ TEST_F(TransportSecurityStateTest, DeleteSince) {
const base::Time older = current_time - base::TimeDelta::FromSeconds(1000);
EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state));
- domain_state.upgrade_mode =
- TransportSecurityState::DomainState::MODE_FORCE_HTTPS;
- domain_state.upgrade_expiry = expiry;
- state.EnableHost("yahoo.com", domain_state);
+ bool include_subdomains = false;
+ state.AddHSTS("yahoo.com", expiry, include_subdomains);
- state.DeleteSince(expiry);
+ state.DeleteAllDynamicDataSince(expiry);
EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state));
- state.DeleteSince(older);
+ state.DeleteAllDynamicDataSince(older);
EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state));
}
-TEST_F(TransportSecurityStateTest, DeleteHost) {
+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);
- domain_state.upgrade_mode =
- TransportSecurityState::DomainState::MODE_FORCE_HTTPS;
- domain_state.upgrade_expiry = expiry;
- state.EnableHost("yahoo.com", domain_state);
+ bool include_subdomains = false;
+ state.AddHSTS("yahoo.com", expiry, include_subdomains);
EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state));
EXPECT_FALSE(state.GetDomainState("example.com", true, &domain_state));
- EXPECT_TRUE(state.DeleteHost("yahoo.com"));
+ EXPECT_TRUE(state.DeleteDynamicDataForHost("yahoo.com"));
EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state));
}
TEST_F(TransportSecurityStateTest, IsPreloaded) {
const std::string paypal =
- TransportSecurityState::CanonicalizeHost("paypal.com");
+ CanonicalizeHost("paypal.com");
const std::string www_paypal =
- TransportSecurityState::CanonicalizeHost("www.paypal.com");
+ CanonicalizeHost("www.paypal.com");
const std::string a_www_paypal =
- TransportSecurityState::CanonicalizeHost("a.www.paypal.com");
+ CanonicalizeHost("a.www.paypal.com");
const std::string abc_paypal =
- TransportSecurityState::CanonicalizeHost("a.b.c.paypal.com");
+ CanonicalizeHost("a.b.c.paypal.com");
const std::string example =
- TransportSecurityState::CanonicalizeHost("example.com");
+ CanonicalizeHost("example.com");
const std::string aypal =
- TransportSecurityState::CanonicalizeHost("aypal.com");
+ CanonicalizeHost("aypal.com");
TransportSecurityState state;
TransportSecurityState::DomainState domain_state;
- EXPECT_FALSE(state.GetStaticDomainState(paypal, true, &domain_state));
- EXPECT_TRUE(state.GetStaticDomainState(www_paypal, true, &domain_state));
+ EXPECT_FALSE(GetStaticDomainState(&state, paypal, true, &domain_state));
+ EXPECT_TRUE(GetStaticDomainState(&state, www_paypal, true, &domain_state));
EXPECT_FALSE(domain_state.include_subdomains);
- EXPECT_FALSE(state.GetStaticDomainState(a_www_paypal, true, &domain_state));
- EXPECT_FALSE(state.GetStaticDomainState(abc_paypal, true, &domain_state));
- EXPECT_FALSE(state.GetStaticDomainState(example, true, &domain_state));
- EXPECT_FALSE(state.GetStaticDomainState(aypal, true, &domain_state));
+ EXPECT_FALSE(GetStaticDomainState(&state, a_www_paypal, true, &domain_state));
+ EXPECT_FALSE(GetStaticDomainState(&state, abc_paypal, true, &domain_state));
+ EXPECT_FALSE(GetStaticDomainState(&state, example, true, &domain_state));
+ EXPECT_FALSE(GetStaticDomainState(&state, aypal, true, &domain_state));
}
TEST_F(TransportSecurityStateTest, PreloadedDomainSet) {
@@ -733,7 +746,7 @@ TEST_F(TransportSecurityStateTest, OverrideBuiltins) {
const base::Time current_time(base::Time::Now());
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
domain_state.upgrade_expiry = expiry;
- state.EnableHost("www.google.com", domain_state);
+ EnableHost(&state, "www.google.com", domain_state);
EXPECT_TRUE(state.GetDomainState("www.google.com", true, &domain_state));
}
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index 28df2a1..0967bd9 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -4393,10 +4393,10 @@ TEST_F(HTTPSRequestTest, HSTSPreservesPosts) {
// Force https for www.somewhere.com.
TransportSecurityState transport_security_state;
- net::TransportSecurityState::DomainState domain_state;
- domain_state.upgrade_expiry =
- domain_state.created + base::TimeDelta::FromDays(1000);
- transport_security_state.EnableHost("www.somewhere.com", domain_state);
+ base::Time expiry = base::Time::Now() + base::TimeDelta::FromDays(1000);
+ bool include_subdomains = false;
+ transport_security_state.AddHSTS("www.somewhere.com", expiry,
+ include_subdomains);
TestNetworkDelegate network_delegate; // Must outlive URLRequest.
diff --git a/net/websockets/websocket_job_spdy2_unittest.cc b/net/websockets/websocket_job_spdy2_unittest.cc
index ee7c6fd..df5fe21 100644
--- a/net/websockets/websocket_job_spdy2_unittest.cc
+++ b/net/websockets/websocket_job_spdy2_unittest.cc
@@ -245,10 +245,10 @@ class MockURLRequestContext : public net::URLRequestContext {
: transport_security_state_() {
set_cookie_store(cookie_store);
set_transport_security_state(&transport_security_state_);
- net::TransportSecurityState::DomainState state;
- state.upgrade_expiry = base::Time::Now() +
- base::TimeDelta::FromSeconds(1000);
- transport_security_state_.EnableHost("upgrademe.com", state);
+ base::Time expiry = base::Time::Now() + base::TimeDelta::FromDays(1000);
+ bool include_subdomains = false;
+ transport_security_state_.AddHSTS("upgrademe.com", expiry,
+ include_subdomains);
}
virtual ~MockURLRequestContext() {}
diff --git a/net/websockets/websocket_job_spdy3_unittest.cc b/net/websockets/websocket_job_spdy3_unittest.cc
index b4f0e55..9027808 100644
--- a/net/websockets/websocket_job_spdy3_unittest.cc
+++ b/net/websockets/websocket_job_spdy3_unittest.cc
@@ -249,10 +249,10 @@ class MockURLRequestContext : public net::URLRequestContext {
: transport_security_state_() {
set_cookie_store(cookie_store);
set_transport_security_state(&transport_security_state_);
- net::TransportSecurityState::DomainState state;
- state.upgrade_expiry = base::Time::Now() +
- base::TimeDelta::FromSeconds(1000);
- transport_security_state_.EnableHost("upgrademe.com", state);
+ base::Time expiry = base::Time::Now() + base::TimeDelta::FromDays(1000);
+ bool include_subdomains = false;
+ transport_security_state_.AddHSTS("upgrademe.com", expiry,
+ include_subdomains);
}
virtual ~MockURLRequestContext() {}