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

Unified Diff: net/http/transport_security_state.cc

Issue 2747173005: Store dynamic Expect-CT state (Closed)
Patch Set: clear dynamic Expect-CT data when needed Created 3 years, 8 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.h ('k') | net/http/transport_security_state_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/http/transport_security_state.cc
diff --git a/net/http/transport_security_state.cc b/net/http/transport_security_state.cc
index 2e829ad4a9e101fbc669934991b8bfe82a194849..c5fb02e4163499cf44e7df2ff24c0ad71b6afffd 100644
--- a/net/http/transport_security_state.cc
+++ b/net/http/transport_security_state.cc
@@ -56,6 +56,11 @@ const TransportSecurityStateSource* g_hsts_source = &kHSTSSource;
// 1: Unless a delegate says otherwise, require CT.
int g_ct_required_for_testing = 0;
+bool IsDynamicExpectCTEnabled() {
+ return base::FeatureList::IsEnabled(
+ TransportSecurityState::kDynamicExpectCTFeature);
+}
+
// LessThan comparator for use with std::binary_search() in determining
// whether a SHA-256 HashValue appears within a sorted array of
// SHA256HashValues.
@@ -726,6 +731,10 @@ bool SerializeExpectStapleReport(const HostPortPair& host_port_pair,
} // namespace
+// static
+const base::Feature TransportSecurityState::kDynamicExpectCTFeature{
+ "DynamicExpectCT", base::FEATURE_DISABLED_BY_DEFAULT};
+
void SetTransportSecurityStateSourceForTesting(
const TransportSecurityStateSource* source) {
g_hsts_source = source ? source : &kHSTSSource;
@@ -988,6 +997,23 @@ void TransportSecurityState::AddHPKPInternal(const std::string& host,
EnablePKPHost(host, pkp_state);
}
+void TransportSecurityState::AddExpectCTInternal(
+ const std::string& host,
+ const base::Time& last_observed,
+ const base::Time& expiry,
+ bool enforce,
+ const GURL& report_uri) {
+ DCHECK(CalledOnValidThread());
+
+ ExpectCTState expect_ct_state;
+ expect_ct_state.last_observed = last_observed;
+ expect_ct_state.expiry = expiry;
+ expect_ct_state.enforce = enforce;
+ expect_ct_state.report_uri = report_uri;
+
+ EnableExpectCTHost(host, expect_ct_state);
+}
+
void TransportSecurityState::
SetEnablePublicKeyPinningBypassForLocalTrustAnchors(bool value) {
enable_pkp_bypass_for_local_trust_anchors_ = value;
@@ -1043,6 +1069,33 @@ void TransportSecurityState::EnablePKPHost(const std::string& host,
DirtyNotify();
}
+void TransportSecurityState::EnableExpectCTHost(const std::string& host,
+ const ExpectCTState& state) {
+ DCHECK(CalledOnValidThread());
+ if (!IsDynamicExpectCTEnabled())
+ return;
+
+ const std::string canonicalized_host = CanonicalizeHost(host);
+ if (canonicalized_host.empty())
+ return;
+
+ // Only store new state when Expect-CT is explicitly enabled. If it is
+ // disabled, remove the state from the enabled hosts.
+ if (state.enforce || !state.report_uri.is_empty()) {
+ ExpectCTState expect_ct_state(state);
+ // No need to store this value since it is redundant. (|canonicalized_host|
+ // is the map key.)
+ expect_ct_state.domain.clear();
+
+ enabled_expect_ct_hosts_[HashHost(canonicalized_host)] = expect_ct_state;
+ } else {
+ const std::string hashed_host = HashHost(canonicalized_host);
+ enabled_expect_ct_hosts_.erase(hashed_host);
+ }
+
+ DirtyNotify();
+}
+
TransportSecurityState::PKPStatus
TransportSecurityState::CheckPinsAndMaybeSendReport(
const HostPortPair& host_port_pair,
@@ -1164,6 +1217,13 @@ bool TransportSecurityState::DeleteDynamicDataForHost(const std::string& host) {
deleted = true;
}
+ ExpectCTStateMap::iterator expect_ct_iterator =
+ enabled_expect_ct_hosts_.find(hashed_host);
+ if (expect_ct_iterator != enabled_expect_ct_hosts_.end()) {
+ enabled_expect_ct_hosts_.erase(expect_ct_iterator);
+ deleted = true;
+ }
+
if (deleted)
DirtyNotify();
return deleted;
@@ -1173,6 +1233,7 @@ void TransportSecurityState::ClearDynamicData() {
DCHECK(CalledOnValidThread());
enabled_sts_hosts_.clear();
enabled_pkp_hosts_.clear();
+ enabled_expect_ct_hosts_.clear();
}
void TransportSecurityState::DeleteAllDynamicDataSince(const base::Time& time) {
@@ -1201,6 +1262,18 @@ void TransportSecurityState::DeleteAllDynamicDataSince(const base::Time& time) {
++pkp_iterator;
}
+ ExpectCTStateMap::iterator expect_ct_iterator =
+ enabled_expect_ct_hosts_.begin();
+ while (expect_ct_iterator != enabled_expect_ct_hosts_.end()) {
+ if (expect_ct_iterator->second.last_observed >= time) {
+ dirtied = true;
+ enabled_expect_ct_hosts_.erase(expect_ct_iterator++);
+ continue;
+ }
+
+ ++expect_ct_iterator;
+ }
+
if (dirtied)
DirtyNotify();
}
@@ -1279,6 +1352,14 @@ void TransportSecurityState::AddHPKP(const std::string& host,
report_uri);
}
+void TransportSecurityState::AddExpectCT(const std::string& host,
+ const base::Time& expiry,
+ bool enforce,
+ const GURL& report_uri) {
+ DCHECK(CalledOnValidThread());
+ AddExpectCTInternal(host, base::Time::Now(), expiry, enforce, report_uri);
+}
+
bool TransportSecurityState::ProcessHPKPReportOnlyHeader(
const std::string& value,
const HostPortPair& host_port_pair,
@@ -1571,6 +1652,30 @@ bool TransportSecurityState::GetDynamicPKPState(const std::string& host,
return false;
}
+bool TransportSecurityState::GetDynamicExpectCTState(const std::string& host,
+ ExpectCTState* result) {
+ DCHECK(CalledOnValidThread());
+
+ const std::string canonicalized_host = CanonicalizeHost(host);
+ if (canonicalized_host.empty())
+ return false;
+
+ base::Time current_time(base::Time::Now());
+ ExpectCTStateMap::iterator j =
+ enabled_expect_ct_hosts_.find(HashHost(canonicalized_host));
+ if (j == enabled_expect_ct_hosts_.end())
+ return false;
+ // If the entry is invalid, drop it.
+ if (current_time > j->second.expiry) {
+ enabled_expect_ct_hosts_.erase(j);
+ DirtyNotify();
+ return false;
+ }
+
+ *result = j->second;
+ return true;
+}
+
void TransportSecurityState::AddOrUpdateEnabledSTSHosts(
const std::string& hashed_host,
const STSState& state) {
@@ -1587,6 +1692,14 @@ void TransportSecurityState::AddOrUpdateEnabledPKPHosts(
enabled_pkp_hosts_[hashed_host] = state;
}
+void TransportSecurityState::AddOrUpdateEnabledExpectCTHosts(
+ const std::string& hashed_host,
+ const ExpectCTState& state) {
+ DCHECK(CalledOnValidThread());
+ DCHECK(state.enforce || !state.report_uri.is_empty());
+ enabled_expect_ct_hosts_[hashed_host] = state;
+}
+
TransportSecurityState::STSState::STSState()
: upgrade_mode(MODE_DEFAULT), include_subdomains(false) {
}
@@ -1615,10 +1728,19 @@ TransportSecurityState::PKPState::PKPState(const PKPState& other) = default;
TransportSecurityState::PKPState::~PKPState() {
}
-TransportSecurityState::ExpectCTState::ExpectCTState() {}
+TransportSecurityState::ExpectCTState::ExpectCTState() : enforce(false) {}
TransportSecurityState::ExpectCTState::~ExpectCTState() {}
+TransportSecurityState::ExpectCTStateIterator::ExpectCTStateIterator(
+ const TransportSecurityState& state)
+ : iterator_(state.enabled_expect_ct_hosts_.begin()),
+ end_(state.enabled_expect_ct_hosts_.end()) {
+ DCHECK(state.CalledOnValidThread());
+}
+
+TransportSecurityState::ExpectCTStateIterator::~ExpectCTStateIterator() {}
+
TransportSecurityState::ExpectStapleState::ExpectStapleState()
: include_subdomains(false) {}
« no previous file with comments | « net/http/transport_security_state.h ('k') | net/http/transport_security_state_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698