| 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..9e757432539f83eb133b880ebe4ea9cc7114c4c9 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);
|
| + 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_stat()) {
|
| + // The candidate cert is not be subject to the CT policy, because it
|
| + // 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(
|
|
|