Index: net/http/transport_security_state.cc |
diff --git a/net/http/transport_security_state.cc b/net/http/transport_security_state.cc |
index 30d352712f27739fb9aecbd9a72e56680e93b60c..9bee2128669d85f9823dce2ad8975be286f66260 100644 |
--- a/net/http/transport_security_state.cc |
+++ b/net/http/transport_security_state.cc |
@@ -35,6 +35,7 @@ namespace net { |
namespace { |
+#include "net/http/transport_security_state_ct_policies.inc" |
#include "net/http/transport_security_state_static.h" |
const size_t kMaxHPKPReportCacheEntries = 50; |
@@ -47,6 +48,21 @@ const size_t kReportCacheKeyLength = 16; |
// 1: Unless a delegate says otherwise, require CT. |
int g_ct_required_for_testing = 0; |
+// LessThan comparator for use with std::binary_search() in determining |
+// whether a SHA-256 HashValue appears within a sorted array of |
+// SHA256HashValues. |
+struct SHA256ToHashValueComparator { |
+ bool operator()(const SHA256HashValue& lhs, const HashValue& rhs) const { |
+ DCHECK(rhs.tag == HASH_VALUE_SHA256); |
eroman
2016/06/29 23:22:21
dcheck_eq (and below)
|
+ return memcmp(lhs.data, rhs.data(), rhs.size()) < 0; |
+ } |
+ |
+ bool operator()(const HashValue& lhs, const SHA256HashValue& rhs) const { |
+ DCHECK(lhs.tag == HASH_VALUE_SHA256); |
+ return memcmp(lhs.data(), rhs.data, lhs.size()) < 0; |
+ } |
+}; |
+ |
void RecordUMAForHPKPReportFailure(const GURL& report_uri, int net_error) { |
UMA_HISTOGRAM_SPARSE_SLOWLY("Net.PublicKeyPinReportSendingFailure", |
net_error); |
@@ -722,7 +738,48 @@ bool TransportSecurityState::ShouldRequireCT( |
if (g_ct_required_for_testing) |
return g_ct_required_for_testing == 1; |
- return false; |
+ bool default_response = false; |
+ const base::Time epoch = base::Time::UnixEpoch(); |
+ for (const auto& restricted_ca : kCTRequiredPolicies) { |
+ if (epoch + restricted_ca.effective_date > |
+ validated_certificate_chain->valid_start()) { |
+ // The candidate cert is not be subject to the CT policy, because it |
eroman
2016/06/29 23:22:21
Is there anything preventing re-issuing the target
Ryan Sleevi
2016/06/30 00:03:20
Unfortunately, no, and that's legitimately my bigg
|
+ // was issued before the effective CT date. |
+ continue; |
+ } |
+ |
+ for (const auto& hash : public_key_hashes) { |
+ if (hash.tag != HASH_VALUE_SHA256) |
+ continue; |
+ |
+ // Determine if |hash| is in the set of roots of |restricted_ca|. |
+ if (!std::binary_search(restricted_ca.roots, |
+ restricted_ca.roots + restricted_ca.roots_length, |
+ hash, SHA256ToHashValueComparator())) { |
+ continue; |
+ } |
+ |
+ // Found a match, indicating this certificate is potentially |
+ // restricted. Determine if any of the hashes are on the exclusion |
+ // list as exempt from the CT requirement. |
+ for (const auto& sub_ca_hash : public_key_hashes) { |
+ if (sub_ca_hash.tag != HASH_VALUE_SHA256) |
+ continue; |
+ if (std::binary_search( |
+ restricted_ca.exceptions, |
+ restricted_ca.exceptions + restricted_ca.exceptions_length, |
+ sub_ca_hash, SHA256ToHashValueComparator())) { |
+ // Found an excluded sub-CA; CT is not required. |
+ return default_response; |
+ } |
+ } |
+ |
+ // No exception found. This certificate must conform to the CT policy. |
+ return true; |
+ } |
+ } |
+ |
+ return default_response; |
} |
void TransportSecurityState::SetDelegate( |