Chromium Code Reviews| 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..2a9bbba73165ea5988e11e5cb2b7b1a2aab4cbf9 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, |
| @@ -1279,6 +1332,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 +1632,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 +1672,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 +1708,17 @@ 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()) {} |
|
mattm
2017/04/15 04:50:17
Can you check state.CalledOnValidThread() here to
estark
2017/04/15 19:16:08
Done.
|
| + |
| +TransportSecurityState::ExpectCTStateIterator::~ExpectCTStateIterator() {} |
| + |
| TransportSecurityState::ExpectStapleState::ExpectStapleState() |
| : include_subdomains(false) {} |