transport_security_state.cc 59 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/http/transport_security_state.h"
  5. #include <algorithm>
  6. #include <memory>
  7. #include <tuple>
  8. #include <utility>
  9. #include <vector>
  10. #include "base/base64.h"
  11. #include "base/bind.h"
  12. #include "base/build_time.h"
  13. #include "base/containers/contains.h"
  14. #include "base/containers/span.h"
  15. #include "base/feature_list.h"
  16. #include "base/json/json_writer.h"
  17. #include "base/logging.h"
  18. #include "base/metrics/field_trial.h"
  19. #include "base/metrics/field_trial_params.h"
  20. #include "base/metrics/histogram_functions.h"
  21. #include "base/metrics/histogram_macros.h"
  22. #include "base/strings/string_number_conversions.h"
  23. #include "base/strings/string_util.h"
  24. #include "base/strings/utf_string_conversions.h"
  25. #include "base/time/time.h"
  26. #include "base/time/time_to_iso8601.h"
  27. #include "base/values.h"
  28. #include "build/branding_buildflags.h"
  29. #include "build/build_config.h"
  30. #include "crypto/sha2.h"
  31. #include "net/base/features.h"
  32. #include "net/base/hash_value.h"
  33. #include "net/base/host_port_pair.h"
  34. #include "net/cert/ct_policy_status.h"
  35. #include "net/cert/symantec_certs.h"
  36. #include "net/cert/x509_certificate.h"
  37. #include "net/dns/dns_util.h"
  38. #include "net/extras/preload_data/decoder.h"
  39. #include "net/http/http_security_headers.h"
  40. #include "net/net_buildflags.h"
  41. #include "net/ssl/ssl_info.h"
  42. #include "third_party/abseil-cpp/absl/types/optional.h"
  43. namespace net {
  44. namespace {
  45. #include "net/http/transport_security_state_ct_policies.inc"
  46. #if BUILDFLAG(INCLUDE_TRANSPORT_SECURITY_STATE_PRELOAD_LIST)
  47. #include "net/http/transport_security_state_static.h" // nogncheck
  48. // Points to the active transport security state source.
  49. const TransportSecurityStateSource* const kDefaultHSTSSource = &kHSTSSource;
  50. #else
  51. const TransportSecurityStateSource* const kDefaultHSTSSource = nullptr;
  52. #endif
  53. const TransportSecurityStateSource* g_hsts_source = kDefaultHSTSSource;
  54. // Parameters for remembering sent HPKP and Expect-CT reports.
  55. const size_t kMaxReportCacheEntries = 50;
  56. const int kTimeToRememberReportsMins = 60;
  57. const size_t kReportCacheKeyLength = 16;
  58. // Override for CheckCTRequirements() for unit tests. Possible values:
  59. // false: Use the default implementation (e.g. production)
  60. // true: Unless a delegate says otherwise, require CT.
  61. bool g_ct_required_for_testing = false;
  62. bool IsDynamicExpectCTEnabled() {
  63. return base::FeatureList::IsEnabled(
  64. TransportSecurityState::kDynamicExpectCTFeature);
  65. }
  66. base::Value GetPEMEncodedChainAsList(const net::X509Certificate* cert_chain) {
  67. if (!cert_chain)
  68. return base::Value(base::Value::Type::LIST);
  69. base::Value::List result;
  70. std::vector<std::string> pem_encoded_chain;
  71. cert_chain->GetPEMEncodedChain(&pem_encoded_chain);
  72. for (const std::string& cert : pem_encoded_chain)
  73. result.Append(cert);
  74. return base::Value(std::move(result));
  75. }
  76. bool HashReportForCache(const base::Value::Dict& report,
  77. const GURL& report_uri,
  78. std::string* cache_key) {
  79. char hashed[crypto::kSHA256Length];
  80. std::string to_hash;
  81. if (!base::JSONWriter::Write(report, &to_hash))
  82. return false;
  83. to_hash += "," + report_uri.spec();
  84. crypto::SHA256HashString(to_hash, hashed, sizeof(hashed));
  85. static_assert(kReportCacheKeyLength <= sizeof(hashed),
  86. "HPKP report cache key size is larger than hash size.");
  87. *cache_key = std::string(hashed, kReportCacheKeyLength);
  88. return true;
  89. }
  90. bool GetHPKPReport(const HostPortPair& host_port_pair,
  91. const TransportSecurityState::PKPState& pkp_state,
  92. const X509Certificate* served_certificate_chain,
  93. const X509Certificate* validated_certificate_chain,
  94. std::string* serialized_report,
  95. std::string* cache_key) {
  96. if (pkp_state.report_uri.is_empty())
  97. return false;
  98. base::Value::Dict report;
  99. base::Time now = base::Time::Now();
  100. report.Set("hostname", host_port_pair.host());
  101. report.Set("port", host_port_pair.port());
  102. report.Set("include-subdomains", pkp_state.include_subdomains);
  103. report.Set("noted-hostname", pkp_state.domain);
  104. auto served_certificate_chain_list =
  105. GetPEMEncodedChainAsList(served_certificate_chain);
  106. auto validated_certificate_chain_list =
  107. GetPEMEncodedChainAsList(validated_certificate_chain);
  108. report.Set("served-certificate-chain",
  109. std::move(served_certificate_chain_list));
  110. report.Set("validated-certificate-chain",
  111. std::move(validated_certificate_chain_list));
  112. base::Value::List known_pin_list;
  113. for (const auto& hash_value : pkp_state.spki_hashes) {
  114. std::string known_pin;
  115. switch (hash_value.tag()) {
  116. case HASH_VALUE_SHA256:
  117. known_pin += "pin-sha256=";
  118. break;
  119. default:
  120. // Don't bother reporting about hash types we don't support. SHA-256 is
  121. // the only standardized hash function for HPKP anyway.
  122. continue;
  123. }
  124. std::string base64_value;
  125. base::Base64Encode(
  126. base::StringPiece(reinterpret_cast<const char*>(hash_value.data()),
  127. hash_value.size()),
  128. &base64_value);
  129. known_pin += "\"" + base64_value + "\"";
  130. known_pin_list.Append(known_pin);
  131. }
  132. report.Set("known-pins", std::move(known_pin_list));
  133. // For the sent reports cache, do not include the effective expiration
  134. // date. The expiration date will likely change every time the user
  135. // visits the site, so it would prevent reports from being effectively
  136. // deduplicated.
  137. if (!HashReportForCache(report, pkp_state.report_uri, cache_key)) {
  138. LOG(ERROR) << "Failed to compute cache key for HPKP violation report.";
  139. return false;
  140. }
  141. report.Set("date-time", base::TimeToISO8601(now));
  142. report.Set("effective-expiration-date",
  143. base::TimeToISO8601(pkp_state.expiry));
  144. if (!base::JSONWriter::Write(report, serialized_report)) {
  145. LOG(ERROR) << "Failed to serialize HPKP violation report.";
  146. return false;
  147. }
  148. return true;
  149. }
  150. // Do not send a report over HTTPS to the same host that set the
  151. // pin. Such report URIs will result in loops. (A.com has a pinning
  152. // violation which results in a report being sent to A.com, which
  153. // results in a pinning violation which results in a report being sent
  154. // to A.com, etc.)
  155. bool IsReportUriValidForHost(const GURL& report_uri, const std::string& host) {
  156. return (report_uri.host_piece() != host ||
  157. !report_uri.SchemeIsCryptographic());
  158. }
  159. std::string HashesToBase64String(const HashValueVector& hashes) {
  160. std::string str;
  161. for (size_t i = 0; i != hashes.size(); ++i) {
  162. if (i != 0)
  163. str += ",";
  164. str += hashes[i].ToString();
  165. }
  166. return str;
  167. }
  168. std::string HashHost(base::StringPiece canonicalized_host) {
  169. char hashed[crypto::kSHA256Length];
  170. crypto::SHA256HashString(canonicalized_host, hashed, sizeof(hashed));
  171. return std::string(hashed, sizeof(hashed));
  172. }
  173. // Returns true if the intersection of |a| and |b| is not empty. If either
  174. // |a| or |b| is empty, returns false.
  175. bool HashesIntersect(const HashValueVector& a,
  176. const HashValueVector& b) {
  177. for (const auto& hash : a) {
  178. if (base::Contains(b, hash))
  179. return true;
  180. }
  181. return false;
  182. }
  183. bool AddHash(const char* sha256_hash, HashValueVector* out) {
  184. HashValue hash(HASH_VALUE_SHA256);
  185. memcpy(hash.data(), sha256_hash, hash.size());
  186. out->push_back(hash);
  187. return true;
  188. }
  189. // Converts |hostname| from dotted form ("www.google.com") to the form
  190. // used in DNS: "\x03www\x06google\x03com", lowercases that, and returns
  191. // the result.
  192. std::string CanonicalizeHost(const std::string& host) {
  193. // We cannot perform the operations as detailed in the spec here as |host|
  194. // has already undergone IDN processing before it reached us. Thus, we check
  195. // that there are no invalid characters in the host and lowercase the result.
  196. std::string new_host;
  197. if (!DNSDomainFromDot(host, &new_host)) {
  198. // DNSDomainFromDot can fail if any label is > 63 bytes or if the whole
  199. // name is >255 bytes. However, search terms can have those properties.
  200. return std::string();
  201. }
  202. for (size_t i = 0; new_host[i]; i += new_host[i] + 1) {
  203. const unsigned label_length = static_cast<unsigned>(new_host[i]);
  204. if (!label_length)
  205. break;
  206. for (size_t j = 0; j < label_length; ++j) {
  207. new_host[i + 1 + j] = static_cast<char>(tolower(new_host[i + 1 + j]));
  208. }
  209. }
  210. return new_host;
  211. }
  212. // PreloadResult is the result of resolving a specific name in the preloaded
  213. // data.
  214. struct PreloadResult {
  215. uint32_t pinset_id = 0;
  216. // hostname_offset contains the number of bytes from the start of the given
  217. // hostname where the name of the matching entry starts.
  218. size_t hostname_offset = 0;
  219. bool sts_include_subdomains = false;
  220. bool pkp_include_subdomains = false;
  221. bool force_https = false;
  222. bool has_pins = false;
  223. bool expect_ct = false;
  224. uint32_t expect_ct_report_uri_id = 0;
  225. };
  226. using net::extras::PreloadDecoder;
  227. // Extracts the current PreloadResult entry from the given Huffman encoded trie.
  228. // If an "end of string" matches a period in the hostname then the information
  229. // is remembered because, if no more specific node is found, then that
  230. // information applies to the hostname.
  231. class HSTSPreloadDecoder : public net::extras::PreloadDecoder {
  232. public:
  233. using net::extras::PreloadDecoder::PreloadDecoder;
  234. // net::extras::PreloadDecoder:
  235. bool ReadEntry(net::extras::PreloadDecoder::BitReader* reader,
  236. const std::string& search,
  237. size_t current_search_offset,
  238. bool* out_found) override {
  239. bool is_simple_entry;
  240. if (!reader->Next(&is_simple_entry)) {
  241. return false;
  242. }
  243. PreloadResult tmp;
  244. // Simple entries only configure HSTS with IncludeSubdomains and use a
  245. // compact serialization format where the other policy flags are
  246. // omitted. The omitted flags are assumed to be 0 and the associated
  247. // policies are disabled.
  248. if (is_simple_entry) {
  249. tmp.force_https = true;
  250. tmp.sts_include_subdomains = true;
  251. } else {
  252. if (!reader->Next(&tmp.sts_include_subdomains) ||
  253. !reader->Next(&tmp.force_https) || !reader->Next(&tmp.has_pins)) {
  254. return false;
  255. }
  256. tmp.pkp_include_subdomains = tmp.sts_include_subdomains;
  257. if (tmp.has_pins) {
  258. if (!reader->Read(4, &tmp.pinset_id) ||
  259. (!tmp.sts_include_subdomains &&
  260. !reader->Next(&tmp.pkp_include_subdomains))) {
  261. return false;
  262. }
  263. }
  264. if (!reader->Next(&tmp.expect_ct))
  265. return false;
  266. if (tmp.expect_ct) {
  267. if (!reader->Read(4, &tmp.expect_ct_report_uri_id))
  268. return false;
  269. }
  270. }
  271. tmp.hostname_offset = current_search_offset;
  272. if (current_search_offset == 0 ||
  273. search[current_search_offset - 1] == '.') {
  274. *out_found = tmp.sts_include_subdomains || tmp.pkp_include_subdomains;
  275. result_ = tmp;
  276. if (current_search_offset > 0) {
  277. result_.force_https &= tmp.sts_include_subdomains;
  278. } else {
  279. *out_found = true;
  280. return true;
  281. }
  282. }
  283. return true;
  284. }
  285. PreloadResult result() const { return result_; }
  286. private:
  287. PreloadResult result_;
  288. };
  289. bool DecodeHSTSPreload(const std::string& search_hostname, PreloadResult* out) {
  290. #if !BUILDFLAG(INCLUDE_TRANSPORT_SECURITY_STATE_PRELOAD_LIST)
  291. if (g_hsts_source == nullptr)
  292. return false;
  293. #endif
  294. bool found = false;
  295. // Ensure that |search_hostname| is a valid hostname before
  296. // processing.
  297. if (CanonicalizeHost(search_hostname).empty()) {
  298. return false;
  299. }
  300. // Normalize any trailing '.' used for DNS suffix searches.
  301. std::string hostname = search_hostname;
  302. size_t trailing_dot_found = hostname.find_last_not_of('.');
  303. if (trailing_dot_found != std::string::npos) {
  304. hostname.erase(trailing_dot_found + 1);
  305. } else {
  306. hostname.clear();
  307. }
  308. // |hostname| has already undergone IDN conversion, so should be
  309. // entirely A-Labels. The preload data is entirely normalized to
  310. // lower case.
  311. hostname = base::ToLowerASCII(hostname);
  312. if (hostname.empty()) {
  313. return false;
  314. }
  315. HSTSPreloadDecoder decoder(
  316. g_hsts_source->huffman_tree, g_hsts_source->huffman_tree_size,
  317. g_hsts_source->preloaded_data, g_hsts_source->preloaded_bits,
  318. g_hsts_source->root_position);
  319. if (!decoder.Decode(hostname, &found)) {
  320. DCHECK(false) << "Internal error in DecodeHSTSPreload for hostname "
  321. << hostname;
  322. return false;
  323. }
  324. if (found)
  325. *out = decoder.result();
  326. return found;
  327. }
  328. } // namespace
  329. // static
  330. const base::Feature TransportSecurityState::kDynamicExpectCTFeature{
  331. "DynamicExpectCT", base::FEATURE_ENABLED_BY_DEFAULT};
  332. // static
  333. const base::Feature TransportSecurityState::kCertificateTransparencyEnforcement{
  334. "CertificateTransparencyEnforcement", base::FEATURE_ENABLED_BY_DEFAULT};
  335. void SetTransportSecurityStateSourceForTesting(
  336. const TransportSecurityStateSource* source) {
  337. g_hsts_source = source ? source : kDefaultHSTSSource;
  338. }
  339. TransportSecurityState::TransportSecurityState()
  340. : TransportSecurityState(std::vector<std::string>()) {
  341. // By default the CT log list is treated as last updated at build time (since
  342. // a compiled-in list is used), this is overridden if the list is dynamically
  343. // updated.
  344. ct_log_list_last_update_time_ = base::GetBuildTime();
  345. }
  346. TransportSecurityState::TransportSecurityState(
  347. std::vector<std::string> hsts_host_bypass_list)
  348. : sent_hpkp_reports_cache_(kMaxReportCacheEntries),
  349. sent_expect_ct_reports_cache_(kMaxReportCacheEntries),
  350. key_expect_ct_by_nik_(base::FeatureList::IsEnabled(
  351. features::kPartitionExpectCTStateByNetworkIsolationKey)) {
  352. // Static pinning is only enabled for official builds to make sure that
  353. // others don't end up with pins that cannot be easily updated.
  354. #if !BUILDFLAG(GOOGLE_CHROME_BRANDING) || BUILDFLAG(IS_IOS)
  355. enable_static_pins_ = false;
  356. enable_static_expect_ct_ = false;
  357. #endif
  358. // Check that there no invalid entries in the static HSTS bypass list.
  359. for (auto& host : hsts_host_bypass_list) {
  360. DCHECK(host.find('.') == std::string::npos);
  361. hsts_host_bypass_list_.insert(host);
  362. }
  363. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  364. }
  365. // Both HSTS and HPKP cause fatal SSL errors, so return true if a
  366. // host has either.
  367. bool TransportSecurityState::ShouldSSLErrorsBeFatal(const std::string& host) {
  368. STSState unused_sts;
  369. PKPState unused_pkp;
  370. return GetSTSState(host, &unused_sts) || GetPKPState(host, &unused_pkp);
  371. }
  372. base::Value TransportSecurityState::NetLogUpgradeToSSLParam(
  373. const std::string& host) {
  374. STSState sts_state;
  375. base::Value::Dict dict;
  376. dict.Set("host", host);
  377. dict.Set("get_sts_state_result", GetSTSState(host, &sts_state));
  378. dict.Set("should_upgrade_to_ssl", sts_state.ShouldUpgradeToSSL());
  379. dict.Set("host_found_in_hsts_bypass_list",
  380. hsts_host_bypass_list_.find(host) != hsts_host_bypass_list_.end());
  381. return base::Value(std::move(dict));
  382. }
  383. bool TransportSecurityState::ShouldUpgradeToSSL(
  384. const std::string& host,
  385. const NetLogWithSource& net_log) {
  386. STSState sts_state;
  387. net_log.AddEvent(
  388. NetLogEventType::TRANSPORT_SECURITY_STATE_SHOULD_UPGRADE_TO_SSL,
  389. [&] { return NetLogUpgradeToSSLParam(host); });
  390. return GetSTSState(host, &sts_state) && sts_state.ShouldUpgradeToSSL();
  391. }
  392. TransportSecurityState::PKPStatus TransportSecurityState::CheckPublicKeyPins(
  393. const HostPortPair& host_port_pair,
  394. bool is_issued_by_known_root,
  395. const HashValueVector& public_key_hashes,
  396. const X509Certificate* served_certificate_chain,
  397. const X509Certificate* validated_certificate_chain,
  398. const PublicKeyPinReportStatus report_status,
  399. const NetworkIsolationKey& network_isolation_key,
  400. std::string* pinning_failure_log) {
  401. // Perform pin validation only if the server actually has public key pins.
  402. if (!HasPublicKeyPins(host_port_pair.host())) {
  403. return PKPStatus::OK;
  404. }
  405. PKPStatus pin_validity = CheckPublicKeyPinsImpl(
  406. host_port_pair, is_issued_by_known_root, public_key_hashes,
  407. served_certificate_chain, validated_certificate_chain, report_status,
  408. network_isolation_key, pinning_failure_log);
  409. // Don't track statistics when a local trust anchor would override the pinning
  410. // anyway.
  411. if (!is_issued_by_known_root)
  412. return pin_validity;
  413. UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess",
  414. pin_validity == PKPStatus::OK);
  415. return pin_validity;
  416. }
  417. bool TransportSecurityState::HasPublicKeyPins(const std::string& host) {
  418. PKPState pkp_state;
  419. return GetPKPState(host, &pkp_state) && pkp_state.HasPublicKeyPins();
  420. }
  421. TransportSecurityState::CTRequirementsStatus
  422. TransportSecurityState::CheckCTRequirements(
  423. const net::HostPortPair& host_port_pair,
  424. bool is_issued_by_known_root,
  425. const HashValueVector& public_key_hashes,
  426. const X509Certificate* validated_certificate_chain,
  427. const X509Certificate* served_certificate_chain,
  428. const SignedCertificateTimestampAndStatusList&
  429. signed_certificate_timestamps,
  430. const ExpectCTReportStatus report_status,
  431. ct::CTPolicyCompliance policy_compliance,
  432. const NetworkIsolationKey& network_isolation_key) {
  433. using CTRequirementLevel = RequireCTDelegate::CTRequirementLevel;
  434. std::string hostname = host_port_pair.host();
  435. // If CT is emergency disabled, either through a component updater set flag or
  436. // through the feature flag, we don't require CT for any host.
  437. if (ct_emergency_disable_ ||
  438. !base::FeatureList::IsEnabled(kCertificateTransparencyEnforcement)) {
  439. return CT_NOT_REQUIRED;
  440. }
  441. // CT is not required if the certificate does not chain to a publicly
  442. // trusted root certificate. Testing can override this, as certain tests
  443. // rely on using a non-publicly-trusted root.
  444. if (!is_issued_by_known_root && !g_ct_required_for_testing)
  445. return CT_NOT_REQUIRED;
  446. // A connection is considered compliant if it has sufficient SCTs or if the
  447. // build is outdated. Other statuses are not considered compliant; this
  448. // includes COMPLIANCE_DETAILS_NOT_AVAILABLE because compliance must have been
  449. // evaluated in order to determine that the connection is compliant.
  450. bool complies =
  451. (policy_compliance ==
  452. ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS ||
  453. policy_compliance == ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY);
  454. // Check Expect-CT first so that other CT requirements do not prevent
  455. // Expect-CT reports from being sent.
  456. bool required_via_expect_ct = false;
  457. ExpectCTState state;
  458. if (IsDynamicExpectCTEnabled() &&
  459. GetDynamicExpectCTState(hostname, network_isolation_key, &state)) {
  460. if (!complies && expect_ct_reporter_ && !state.report_uri.is_empty() &&
  461. report_status == ENABLE_EXPECT_CT_REPORTS) {
  462. MaybeNotifyExpectCTFailed(
  463. host_port_pair, state.report_uri, state.expiry,
  464. validated_certificate_chain, served_certificate_chain,
  465. signed_certificate_timestamps, network_isolation_key);
  466. }
  467. required_via_expect_ct = state.enforce;
  468. }
  469. CTRequirementLevel ct_required = CTRequirementLevel::DEFAULT;
  470. if (require_ct_delegate_) {
  471. // Allow the delegate to override the CT requirement state, including
  472. // overriding any Expect-CT enforcement.
  473. ct_required = require_ct_delegate_->IsCTRequiredForHost(
  474. hostname, validated_certificate_chain, public_key_hashes);
  475. }
  476. switch (ct_required) {
  477. case CTRequirementLevel::REQUIRED:
  478. return complies ? CT_REQUIREMENTS_MET : CT_REQUIREMENTS_NOT_MET;
  479. case CTRequirementLevel::NOT_REQUIRED:
  480. return CT_NOT_REQUIRED;
  481. case CTRequirementLevel::DEFAULT:
  482. if (required_via_expect_ct) {
  483. // If Expect-CT is set, short-circuit checking additional policies,
  484. // since they will only enable CT requirement, not exclude from it.
  485. return complies ? CT_REQUIREMENTS_MET : CT_REQUIREMENTS_NOT_MET;
  486. }
  487. break;
  488. }
  489. const base::Time epoch = base::Time::UnixEpoch();
  490. const CTRequiredPolicies& ct_required_policies = GetCTRequiredPolicies();
  491. bool found = false;
  492. for (const auto& restricted_ca : ct_required_policies) {
  493. if (!restricted_ca.effective_date.is_zero() &&
  494. (epoch + restricted_ca.effective_date >
  495. validated_certificate_chain->valid_start())) {
  496. // The candidate cert is not subject to the CT policy, because it
  497. // was issued before the effective CT date.
  498. continue;
  499. }
  500. if (!IsAnySHA256HashInSortedArray(
  501. public_key_hashes,
  502. base::make_span(restricted_ca.roots, restricted_ca.roots_length))) {
  503. // No match for this set of restricted roots.
  504. continue;
  505. }
  506. // Found a match, indicating this certificate is potentially
  507. // restricted. Determine if any of the hashes are on the exclusion
  508. // list as exempt from the CT requirement.
  509. if (restricted_ca.exceptions &&
  510. IsAnySHA256HashInSortedArray(
  511. public_key_hashes,
  512. base::make_span(restricted_ca.exceptions,
  513. restricted_ca.exceptions_length))) {
  514. // Found an excluded sub-CA; CT is not required.
  515. continue;
  516. }
  517. // No exception found. This certificate must conform to the CT policy. The
  518. // compliance state is treated as additive - it must comply with all
  519. // stated policies.
  520. found = true;
  521. }
  522. if (found || g_ct_required_for_testing)
  523. return complies ? CT_REQUIREMENTS_MET : CT_REQUIREMENTS_NOT_MET;
  524. return CT_NOT_REQUIRED;
  525. }
  526. void TransportSecurityState::SetDelegate(
  527. TransportSecurityState::Delegate* delegate) {
  528. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  529. delegate_ = delegate;
  530. }
  531. void TransportSecurityState::SetReportSender(
  532. TransportSecurityState::ReportSenderInterface* report_sender) {
  533. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  534. report_sender_ = report_sender;
  535. }
  536. void TransportSecurityState::SetExpectCTReporter(
  537. ExpectCTReporter* expect_ct_reporter) {
  538. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  539. expect_ct_reporter_ = expect_ct_reporter;
  540. }
  541. void TransportSecurityState::SetRequireCTDelegate(RequireCTDelegate* delegate) {
  542. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  543. require_ct_delegate_ = delegate;
  544. }
  545. void TransportSecurityState::SetCTLogListUpdateTime(base::Time update_time) {
  546. ct_log_list_last_update_time_ = update_time;
  547. }
  548. void TransportSecurityState::UpdatePinList(
  549. const std::vector<PinSet>& pinsets,
  550. const std::vector<PinSetInfo>& host_pins,
  551. base::Time update_time) {
  552. pinsets_ = pinsets;
  553. key_pins_list_last_update_time_ = update_time;
  554. host_pins_ = absl::make_optional(
  555. std::map<std::string, std::pair<PinSet const*, bool>>());
  556. std::map<std::string, PinSet const*> pinset_names_map;
  557. for (const auto& pinset : pinsets_) {
  558. pinset_names_map[pinset.name()] = &pinset;
  559. }
  560. for (const auto& pin : host_pins) {
  561. if (!base::Contains(pinset_names_map, pin.pinset_name_)) {
  562. // This should never happen, but if the component is bad and missing an
  563. // entry, we will ignore that particular pin.
  564. continue;
  565. }
  566. host_pins_.value()[pin.hostname_] = std::make_pair(
  567. pinset_names_map[pin.pinset_name_], pin.include_subdomains_);
  568. }
  569. }
  570. void TransportSecurityState::AddHSTSInternal(
  571. const std::string& host,
  572. TransportSecurityState::STSState::UpgradeMode upgrade_mode,
  573. const base::Time& expiry,
  574. bool include_subdomains) {
  575. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  576. const std::string canonicalized_host = CanonicalizeHost(host);
  577. if (canonicalized_host.empty())
  578. return;
  579. STSState sts_state;
  580. // No need to store |sts_state.domain| since it is redundant.
  581. // (|canonicalized_host| is the map key.)
  582. sts_state.last_observed = base::Time::Now();
  583. sts_state.include_subdomains = include_subdomains;
  584. sts_state.expiry = expiry;
  585. sts_state.upgrade_mode = upgrade_mode;
  586. // Only store new state when HSTS is explicitly enabled. If it is
  587. // disabled, remove the state from the enabled hosts.
  588. if (sts_state.ShouldUpgradeToSSL()) {
  589. enabled_sts_hosts_[HashHost(canonicalized_host)] = sts_state;
  590. } else {
  591. const std::string hashed_host = HashHost(canonicalized_host);
  592. enabled_sts_hosts_.erase(hashed_host);
  593. }
  594. DirtyNotify();
  595. }
  596. void TransportSecurityState::AddHPKPInternal(const std::string& host,
  597. const base::Time& last_observed,
  598. const base::Time& expiry,
  599. bool include_subdomains,
  600. const HashValueVector& hashes,
  601. const GURL& report_uri) {
  602. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  603. const std::string canonicalized_host = CanonicalizeHost(host);
  604. if (canonicalized_host.empty())
  605. return;
  606. PKPState pkp_state;
  607. // No need to store |pkp_state.domain| since it is redundant.
  608. // (|canonicalized_host| is the map key.)
  609. pkp_state.last_observed = last_observed;
  610. pkp_state.expiry = expiry;
  611. pkp_state.include_subdomains = include_subdomains;
  612. pkp_state.spki_hashes = hashes;
  613. pkp_state.report_uri = report_uri;
  614. // Only store new state when HPKP is explicitly enabled. If it is
  615. // disabled, remove the state from the enabled hosts.
  616. if (pkp_state.HasPublicKeyPins()) {
  617. enabled_pkp_hosts_[HashHost(canonicalized_host)] = pkp_state;
  618. } else {
  619. const std::string hashed_host = HashHost(canonicalized_host);
  620. enabled_pkp_hosts_.erase(hashed_host);
  621. }
  622. DirtyNotify();
  623. }
  624. void TransportSecurityState::AddExpectCTInternal(
  625. const std::string& host,
  626. const base::Time& last_observed,
  627. const base::Time& expiry,
  628. bool enforce,
  629. const GURL& report_uri,
  630. const NetworkIsolationKey& network_isolation_key) {
  631. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  632. if (!IsDynamicExpectCTEnabled())
  633. return;
  634. const std::string canonicalized_host = CanonicalizeHost(host);
  635. if (canonicalized_host.empty())
  636. return;
  637. ExpectCTState expect_ct_state;
  638. // No need to store |expect_ct_state.domain| since it is redundant.
  639. // (|canonicalized_host| is the map key.)
  640. expect_ct_state.last_observed = last_observed;
  641. expect_ct_state.expiry = expiry;
  642. expect_ct_state.enforce = enforce;
  643. expect_ct_state.report_uri = report_uri;
  644. // Only store new state when Expect-CT is explicitly enabled. If it is
  645. // disabled, remove the state from the enabled hosts.
  646. ExpectCTStateIndex index = CreateExpectCTStateIndex(
  647. HashHost(canonicalized_host), network_isolation_key);
  648. if (expect_ct_state.enforce || !expect_ct_state.report_uri.is_empty()) {
  649. enabled_expect_ct_hosts_[index] = expect_ct_state;
  650. MaybePruneExpectCTState();
  651. } else {
  652. enabled_expect_ct_hosts_.erase(index);
  653. }
  654. DirtyNotify();
  655. }
  656. void TransportSecurityState::
  657. SetEnablePublicKeyPinningBypassForLocalTrustAnchors(bool value) {
  658. enable_pkp_bypass_for_local_trust_anchors_ = value;
  659. }
  660. TransportSecurityState::PKPStatus
  661. TransportSecurityState::CheckPinsAndMaybeSendReport(
  662. const HostPortPair& host_port_pair,
  663. bool is_issued_by_known_root,
  664. const TransportSecurityState::PKPState& pkp_state,
  665. const HashValueVector& hashes,
  666. const X509Certificate* served_certificate_chain,
  667. const X509Certificate* validated_certificate_chain,
  668. const TransportSecurityState::PublicKeyPinReportStatus report_status,
  669. const net::NetworkIsolationKey& network_isolation_key,
  670. std::string* failure_log) {
  671. if (pkp_state.CheckPublicKeyPins(hashes, failure_log))
  672. return PKPStatus::OK;
  673. // Don't report violations for certificates that chain to local roots.
  674. if (!is_issued_by_known_root && enable_pkp_bypass_for_local_trust_anchors_)
  675. return PKPStatus::BYPASSED;
  676. if (!report_sender_ ||
  677. report_status != TransportSecurityState::ENABLE_PIN_REPORTS ||
  678. pkp_state.report_uri.is_empty()) {
  679. return PKPStatus::VIOLATED;
  680. }
  681. DCHECK(pkp_state.report_uri.is_valid());
  682. // Report URIs should not be used if they are the same host as the pin
  683. // and are HTTPS, to avoid going into a report-sending loop.
  684. if (!IsReportUriValidForHost(pkp_state.report_uri, host_port_pair.host()))
  685. return PKPStatus::VIOLATED;
  686. std::string serialized_report;
  687. std::string report_cache_key;
  688. if (!GetHPKPReport(host_port_pair, pkp_state, served_certificate_chain,
  689. validated_certificate_chain, &serialized_report,
  690. &report_cache_key)) {
  691. return PKPStatus::VIOLATED;
  692. }
  693. // Limit the rate at which duplicate reports are sent to the same
  694. // report URI. The same report will not be sent within
  695. // |kTimeToRememberReportsMins|, which reduces load on servers and
  696. // also prevents accidental loops (a.com triggers a report to b.com
  697. // which triggers a report to a.com). See section 2.1.4 of RFC 7469.
  698. if (sent_hpkp_reports_cache_.Get(report_cache_key, base::TimeTicks::Now()))
  699. return PKPStatus::VIOLATED;
  700. sent_hpkp_reports_cache_.Put(
  701. report_cache_key, true, base::TimeTicks::Now(),
  702. base::TimeTicks::Now() + base::Minutes(kTimeToRememberReportsMins));
  703. report_sender_->Send(pkp_state.report_uri, "application/json; charset=utf-8",
  704. serialized_report, network_isolation_key,
  705. base::OnceCallback<void()>(),
  706. base::OnceCallback<void(const GURL&, int, int)>());
  707. return PKPStatus::VIOLATED;
  708. }
  709. bool TransportSecurityState::GetStaticExpectCTState(
  710. const std::string& host,
  711. ExpectCTState* expect_ct_state) const {
  712. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  713. if (!IsCTLogListTimely())
  714. return false;
  715. PreloadResult result;
  716. if (!DecodeHSTSPreload(host, &result))
  717. return false;
  718. if (!enable_static_expect_ct_ || !result.expect_ct)
  719. return false;
  720. expect_ct_state->report_uri = GURL(
  721. g_hsts_source->expect_ct_report_uris[result.expect_ct_report_uri_id]);
  722. return true;
  723. }
  724. void TransportSecurityState::MaybeNotifyExpectCTFailed(
  725. const HostPortPair& host_port_pair,
  726. const GURL& report_uri,
  727. base::Time expiration,
  728. const X509Certificate* validated_certificate_chain,
  729. const X509Certificate* served_certificate_chain,
  730. const SignedCertificateTimestampAndStatusList&
  731. signed_certificate_timestamps,
  732. const NetworkIsolationKey& network_isolation_key) {
  733. // Do not send repeated reports to the same host/port pair within
  734. // |kTimeToRememberReportsMins|. Theoretically, there could be scenarios in
  735. // which the same host/port generates different reports and it would be useful
  736. // to the server operator to receive those different reports, but such
  737. // scenarios are not expected to arise very often in practice.
  738. const std::string report_cache_key(host_port_pair.ToString());
  739. if (sent_expect_ct_reports_cache_.Get(report_cache_key,
  740. base::TimeTicks::Now())) {
  741. return;
  742. }
  743. sent_expect_ct_reports_cache_.Put(
  744. report_cache_key, true, base::TimeTicks::Now(),
  745. base::TimeTicks::Now() + base::Minutes(kTimeToRememberReportsMins));
  746. expect_ct_reporter_->OnExpectCTFailed(
  747. host_port_pair, report_uri, expiration, validated_certificate_chain,
  748. served_certificate_chain, signed_certificate_timestamps,
  749. network_isolation_key);
  750. }
  751. bool TransportSecurityState::DeleteDynamicDataForHost(const std::string& host) {
  752. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  753. const std::string canonicalized_host = CanonicalizeHost(host);
  754. if (canonicalized_host.empty())
  755. return false;
  756. const std::string hashed_host = HashHost(canonicalized_host);
  757. bool deleted = false;
  758. auto sts_interator = enabled_sts_hosts_.find(hashed_host);
  759. if (sts_interator != enabled_sts_hosts_.end()) {
  760. enabled_sts_hosts_.erase(sts_interator);
  761. deleted = true;
  762. }
  763. auto pkp_iterator = enabled_pkp_hosts_.find(hashed_host);
  764. if (pkp_iterator != enabled_pkp_hosts_.end()) {
  765. enabled_pkp_hosts_.erase(pkp_iterator);
  766. deleted = true;
  767. }
  768. // Delete matching entries for all NetworkIsolationKeys. Performance isn't
  769. // important here, since this is only called when directly initiated by the
  770. // user, so a linear search is fine.
  771. for (auto it = enabled_expect_ct_hosts_.begin();
  772. it != enabled_expect_ct_hosts_.end();) {
  773. auto current = it;
  774. ++it;
  775. if (current->first.hashed_host != hashed_host)
  776. continue;
  777. enabled_expect_ct_hosts_.erase(current);
  778. deleted = true;
  779. }
  780. if (deleted)
  781. DirtyNotify();
  782. return deleted;
  783. }
  784. void TransportSecurityState::ClearDynamicData() {
  785. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  786. enabled_sts_hosts_.clear();
  787. enabled_pkp_hosts_.clear();
  788. enabled_expect_ct_hosts_.clear();
  789. }
  790. void TransportSecurityState::DeleteAllDynamicDataBetween(
  791. base::Time start_time,
  792. base::Time end_time,
  793. base::OnceClosure callback) {
  794. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  795. bool dirtied = false;
  796. auto sts_iterator = enabled_sts_hosts_.begin();
  797. while (sts_iterator != enabled_sts_hosts_.end()) {
  798. if (sts_iterator->second.last_observed >= start_time &&
  799. sts_iterator->second.last_observed < end_time) {
  800. dirtied = true;
  801. enabled_sts_hosts_.erase(sts_iterator++);
  802. continue;
  803. }
  804. ++sts_iterator;
  805. }
  806. auto pkp_iterator = enabled_pkp_hosts_.begin();
  807. while (pkp_iterator != enabled_pkp_hosts_.end()) {
  808. if (pkp_iterator->second.last_observed >= start_time &&
  809. pkp_iterator->second.last_observed < end_time) {
  810. dirtied = true;
  811. enabled_pkp_hosts_.erase(pkp_iterator++);
  812. continue;
  813. }
  814. ++pkp_iterator;
  815. }
  816. auto expect_ct_iterator = enabled_expect_ct_hosts_.begin();
  817. while (expect_ct_iterator != enabled_expect_ct_hosts_.end()) {
  818. if (expect_ct_iterator->second.last_observed >= start_time &&
  819. expect_ct_iterator->second.last_observed < end_time) {
  820. dirtied = true;
  821. enabled_expect_ct_hosts_.erase(expect_ct_iterator++);
  822. continue;
  823. }
  824. ++expect_ct_iterator;
  825. }
  826. if (dirtied && delegate_)
  827. delegate_->WriteNow(this, std::move(callback));
  828. else
  829. std::move(callback).Run();
  830. }
  831. TransportSecurityState::~TransportSecurityState() {
  832. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  833. }
  834. void TransportSecurityState::DirtyNotify() {
  835. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  836. if (delegate_)
  837. delegate_->StateIsDirty(this);
  838. }
  839. bool TransportSecurityState::AddHSTSHeader(const std::string& host,
  840. const std::string& value) {
  841. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  842. base::Time now = base::Time::Now();
  843. base::TimeDelta max_age;
  844. bool include_subdomains;
  845. if (!ParseHSTSHeader(value, &max_age, &include_subdomains)) {
  846. return false;
  847. }
  848. // Handle max-age == 0.
  849. STSState::UpgradeMode upgrade_mode;
  850. if (max_age.InSeconds() == 0) {
  851. upgrade_mode = STSState::MODE_DEFAULT;
  852. } else {
  853. upgrade_mode = STSState::MODE_FORCE_HTTPS;
  854. }
  855. AddHSTSInternal(host, upgrade_mode, now + max_age, include_subdomains);
  856. return true;
  857. }
  858. void TransportSecurityState::AddHSTS(const std::string& host,
  859. const base::Time& expiry,
  860. bool include_subdomains) {
  861. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  862. AddHSTSInternal(host, STSState::MODE_FORCE_HTTPS, expiry, include_subdomains);
  863. }
  864. void TransportSecurityState::AddHPKP(const std::string& host,
  865. const base::Time& expiry,
  866. bool include_subdomains,
  867. const HashValueVector& hashes,
  868. const GURL& report_uri) {
  869. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  870. AddHPKPInternal(host, base::Time::Now(), expiry, include_subdomains, hashes,
  871. report_uri);
  872. }
  873. void TransportSecurityState::AddExpectCT(
  874. const std::string& host,
  875. const base::Time& expiry,
  876. bool enforce,
  877. const GURL& report_uri,
  878. const NetworkIsolationKey& network_isolation_key) {
  879. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  880. AddExpectCTInternal(host, base::Time::Now(), expiry, enforce, report_uri,
  881. network_isolation_key);
  882. }
  883. void TransportSecurityState::ProcessExpectCTHeader(
  884. const std::string& value,
  885. const HostPortPair& host_port_pair,
  886. const SSLInfo& ssl_info,
  887. const NetworkIsolationKey& network_isolation_key) {
  888. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  889. // If a site sends `Expect-CT: preload` and appears on the preload list, they
  890. // are in the experimental preload-list-only, report-only version of
  891. // Expect-CT.
  892. if (value == "preload") {
  893. if (!expect_ct_reporter_)
  894. return;
  895. if (!ssl_info.is_issued_by_known_root)
  896. return;
  897. if (ssl_info.ct_policy_compliance ==
  898. ct::CTPolicyCompliance::
  899. CT_POLICY_COMPLIANCE_DETAILS_NOT_AVAILABLE ||
  900. ssl_info.ct_policy_compliance ==
  901. ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS ||
  902. ssl_info.ct_policy_compliance ==
  903. ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY) {
  904. return;
  905. }
  906. ExpectCTState state;
  907. if (GetStaticExpectCTState(host_port_pair.host(), &state)) {
  908. MaybeNotifyExpectCTFailed(
  909. host_port_pair, state.report_uri, base::Time(), ssl_info.cert.get(),
  910. ssl_info.unverified_cert.get(),
  911. ssl_info.signed_certificate_timestamps, network_isolation_key);
  912. }
  913. return;
  914. }
  915. // Otherwise, see if the site has sent a valid Expect-CT header to dynamically
  916. // turn on reporting and/or enforcement.
  917. if (!IsDynamicExpectCTEnabled())
  918. return;
  919. base::Time now = base::Time::Now();
  920. base::TimeDelta max_age;
  921. bool enforce;
  922. GURL report_uri;
  923. bool parsed = ParseExpectCTHeader(value, &max_age, &enforce, &report_uri);
  924. if (!parsed)
  925. return;
  926. // Do not persist Expect-CT headers if the connection was not chained to a
  927. // public root or did not comply with CT policy.
  928. if (!ssl_info.is_issued_by_known_root)
  929. return;
  930. if (ssl_info.ct_policy_compliance !=
  931. ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS) {
  932. // If an Expect-CT header is observed over a non-compliant connection, the
  933. // site owner should be notified about the misconfiguration. If the site was
  934. // already opted in to Expect-CT, this report would have been sent at
  935. // connection setup time. If the host is not already a noted Expect-CT host,
  936. // however, the lack of CT compliance would not have been evaluated/reported
  937. // at connection setup time, so it needs to be reported here while
  938. // processing the header.
  939. if (ssl_info.ct_policy_compliance ==
  940. ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY ||
  941. ssl_info.ct_policy_compliance ==
  942. ct::CTPolicyCompliance::
  943. CT_POLICY_COMPLIANCE_DETAILS_NOT_AVAILABLE) {
  944. // Only send reports for truly non-compliant connections, not those for
  945. // which compliance wasn't checked.
  946. return;
  947. }
  948. ExpectCTState state;
  949. if (expect_ct_reporter_ && !report_uri.is_empty() &&
  950. !GetDynamicExpectCTState(host_port_pair.host(), network_isolation_key,
  951. &state)) {
  952. MaybeNotifyExpectCTFailed(
  953. host_port_pair, report_uri, base::Time(), ssl_info.cert.get(),
  954. ssl_info.unverified_cert.get(),
  955. ssl_info.signed_certificate_timestamps, network_isolation_key);
  956. }
  957. return;
  958. }
  959. AddExpectCTInternal(host_port_pair.host(), now, now + max_age, enforce,
  960. report_uri, network_isolation_key);
  961. }
  962. // static
  963. void TransportSecurityState::SetRequireCTForTesting(bool required) {
  964. g_ct_required_for_testing = required;
  965. }
  966. void TransportSecurityState::ClearReportCachesForTesting() {
  967. sent_hpkp_reports_cache_.Clear();
  968. sent_expect_ct_reports_cache_.Clear();
  969. }
  970. size_t TransportSecurityState::num_expect_ct_entries_for_testing() const {
  971. return enabled_expect_ct_hosts_.size();
  972. }
  973. size_t TransportSecurityState::num_sts_entries() const {
  974. return enabled_sts_hosts_.size();
  975. }
  976. // static
  977. bool TransportSecurityState::IsBuildTimely() {
  978. const base::Time build_time = base::GetBuildTime();
  979. // We consider built-in information to be timely for 10 weeks.
  980. return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */;
  981. }
  982. TransportSecurityState::PKPStatus
  983. TransportSecurityState::CheckPublicKeyPinsImpl(
  984. const HostPortPair& host_port_pair,
  985. bool is_issued_by_known_root,
  986. const HashValueVector& hashes,
  987. const X509Certificate* served_certificate_chain,
  988. const X509Certificate* validated_certificate_chain,
  989. const PublicKeyPinReportStatus report_status,
  990. const NetworkIsolationKey& network_isolation_key,
  991. std::string* failure_log) {
  992. PKPState pkp_state;
  993. bool found_state = GetPKPState(host_port_pair.host(), &pkp_state);
  994. // HasPublicKeyPins should have returned true in order for this method to have
  995. // been called.
  996. DCHECK(found_state);
  997. return CheckPinsAndMaybeSendReport(
  998. host_port_pair, is_issued_by_known_root, pkp_state, hashes,
  999. served_certificate_chain, validated_certificate_chain, report_status,
  1000. network_isolation_key, failure_log);
  1001. }
  1002. bool TransportSecurityState::GetStaticSTSState(const std::string& host,
  1003. STSState* sts_result) const {
  1004. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  1005. if (!IsBuildTimely())
  1006. return false;
  1007. PreloadResult result;
  1008. if (DecodeHSTSPreload(host, &result) &&
  1009. hsts_host_bypass_list_.find(host) == hsts_host_bypass_list_.end() &&
  1010. result.force_https) {
  1011. sts_result->domain = host.substr(result.hostname_offset);
  1012. sts_result->include_subdomains = result.sts_include_subdomains;
  1013. sts_result->last_observed = base::GetBuildTime();
  1014. sts_result->upgrade_mode = STSState::MODE_FORCE_HTTPS;
  1015. return true;
  1016. }
  1017. return false;
  1018. }
  1019. bool TransportSecurityState::GetStaticPKPState(const std::string& host,
  1020. PKPState* pkp_result) const {
  1021. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  1022. if (!enable_static_pins_ || !IsStaticPKPListTimely() ||
  1023. !base::FeatureList::IsEnabled(features::kStaticKeyPinningEnforcement)) {
  1024. return false;
  1025. }
  1026. PreloadResult result;
  1027. if (host_pins_.has_value()) {
  1028. auto iter = host_pins_->find(host);
  1029. if (iter != host_pins_->end()) {
  1030. pkp_result->domain = host;
  1031. pkp_result->last_observed = key_pins_list_last_update_time_;
  1032. pkp_result->include_subdomains = iter->second.second;
  1033. const PinSet* pinset = iter->second.first;
  1034. if (!pinset->report_uri().empty()) {
  1035. pkp_result->report_uri = GURL(pinset->report_uri());
  1036. }
  1037. for (auto hash : pinset->static_spki_hashes()) {
  1038. // If the update is malformed, it's preferable to skip the hash than
  1039. // crash.
  1040. if (hash.size() == 32) {
  1041. AddHash(reinterpret_cast<const char*>(hash.data()),
  1042. &pkp_result->spki_hashes);
  1043. }
  1044. }
  1045. for (auto hash : pinset->bad_static_spki_hashes()) {
  1046. // If the update is malformed, it's preferable to skip the hash than
  1047. // crash.
  1048. if (hash.size() == 32) {
  1049. AddHash(reinterpret_cast<const char*>(hash.data()),
  1050. &pkp_result->bad_spki_hashes);
  1051. }
  1052. }
  1053. return true;
  1054. }
  1055. } else if (DecodeHSTSPreload(host, &result) && result.has_pins) {
  1056. if (result.pinset_id >= g_hsts_source->pinsets_count)
  1057. return false;
  1058. pkp_result->domain = host.substr(result.hostname_offset);
  1059. pkp_result->include_subdomains = result.pkp_include_subdomains;
  1060. pkp_result->last_observed = base::GetBuildTime();
  1061. const TransportSecurityStateSource::Pinset* pinset =
  1062. &g_hsts_source->pinsets[result.pinset_id];
  1063. if (pinset->report_uri != kNoReportURI)
  1064. pkp_result->report_uri = GURL(pinset->report_uri);
  1065. if (pinset->accepted_pins) {
  1066. const char* const* sha256_hash = pinset->accepted_pins;
  1067. while (*sha256_hash) {
  1068. AddHash(*sha256_hash, &pkp_result->spki_hashes);
  1069. sha256_hash++;
  1070. }
  1071. }
  1072. if (pinset->rejected_pins) {
  1073. const char* const* sha256_hash = pinset->rejected_pins;
  1074. while (*sha256_hash) {
  1075. AddHash(*sha256_hash, &pkp_result->bad_spki_hashes);
  1076. sha256_hash++;
  1077. }
  1078. }
  1079. return true;
  1080. }
  1081. return false;
  1082. }
  1083. bool TransportSecurityState::GetSTSState(const std::string& host,
  1084. STSState* result) {
  1085. return GetDynamicSTSState(host, result) || GetStaticSTSState(host, result);
  1086. }
  1087. bool TransportSecurityState::GetPKPState(const std::string& host,
  1088. PKPState* result) {
  1089. return GetDynamicPKPState(host, result) || GetStaticPKPState(host, result);
  1090. }
  1091. bool TransportSecurityState::GetDynamicSTSState(const std::string& host,
  1092. STSState* result) {
  1093. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  1094. const std::string canonicalized_host = CanonicalizeHost(host);
  1095. if (canonicalized_host.empty())
  1096. return false;
  1097. base::Time current_time(base::Time::Now());
  1098. for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) {
  1099. base::StringPiece host_sub_chunk =
  1100. base::StringPiece(canonicalized_host).substr(i);
  1101. auto j = enabled_sts_hosts_.find(HashHost(host_sub_chunk));
  1102. if (j == enabled_sts_hosts_.end())
  1103. continue;
  1104. // If the entry is invalid, drop it.
  1105. if (current_time > j->second.expiry) {
  1106. enabled_sts_hosts_.erase(j);
  1107. DirtyNotify();
  1108. continue;
  1109. }
  1110. // An entry matches if it is either an exact match, or if it is a prefix
  1111. // match and the includeSubDomains directive was included.
  1112. if (i == 0 || j->second.include_subdomains) {
  1113. absl::optional<std::string> dotted_name =
  1114. DnsDomainToString(host_sub_chunk);
  1115. if (!dotted_name)
  1116. return false;
  1117. *result = j->second;
  1118. result->domain = std::move(dotted_name).value();
  1119. return true;
  1120. }
  1121. }
  1122. return false;
  1123. }
  1124. bool TransportSecurityState::GetDynamicPKPState(const std::string& host,
  1125. PKPState* result) {
  1126. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  1127. const std::string canonicalized_host = CanonicalizeHost(host);
  1128. if (canonicalized_host.empty())
  1129. return false;
  1130. base::Time current_time(base::Time::Now());
  1131. for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) {
  1132. base::StringPiece host_sub_chunk =
  1133. base::StringPiece(canonicalized_host).substr(i);
  1134. auto j = enabled_pkp_hosts_.find(HashHost(host_sub_chunk));
  1135. if (j == enabled_pkp_hosts_.end())
  1136. continue;
  1137. // If the entry is invalid, drop it.
  1138. if (current_time > j->second.expiry) {
  1139. enabled_pkp_hosts_.erase(j);
  1140. DirtyNotify();
  1141. continue;
  1142. }
  1143. // If this is the most specific PKP match, add it to the result. Note: a PKP
  1144. // entry at a more specific domain overrides a less specific domain whether
  1145. // or not |include_subdomains| is set.
  1146. //
  1147. // TODO(davidben): This does not match the HSTS behavior. We no longer
  1148. // implement HPKP, so this logic is only used via AddHPKP(), reachable from
  1149. // Cronet.
  1150. if (i == 0 || j->second.include_subdomains) {
  1151. absl::optional<std::string> dotted_name =
  1152. DnsDomainToString(host_sub_chunk);
  1153. if (!dotted_name)
  1154. return false;
  1155. *result = j->second;
  1156. result->domain = std::move(dotted_name).value();
  1157. return true;
  1158. }
  1159. break;
  1160. }
  1161. return false;
  1162. }
  1163. bool TransportSecurityState::GetDynamicExpectCTState(
  1164. const std::string& host,
  1165. const NetworkIsolationKey& network_isolation_key,
  1166. ExpectCTState* result) {
  1167. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  1168. const std::string canonicalized_host = CanonicalizeHost(host);
  1169. if (canonicalized_host.empty())
  1170. return false;
  1171. base::Time current_time(base::Time::Now());
  1172. auto j = enabled_expect_ct_hosts_.find(CreateExpectCTStateIndex(
  1173. HashHost(canonicalized_host), network_isolation_key));
  1174. if (j == enabled_expect_ct_hosts_.end())
  1175. return false;
  1176. // If the entry is invalid, drop it.
  1177. if (current_time > j->second.expiry) {
  1178. enabled_expect_ct_hosts_.erase(j);
  1179. DirtyNotify();
  1180. return false;
  1181. }
  1182. *result = j->second;
  1183. return true;
  1184. }
  1185. void TransportSecurityState::AddOrUpdateEnabledSTSHosts(
  1186. const std::string& hashed_host,
  1187. const STSState& state) {
  1188. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  1189. DCHECK(state.ShouldUpgradeToSSL());
  1190. enabled_sts_hosts_[hashed_host] = state;
  1191. }
  1192. void TransportSecurityState::AddOrUpdateEnabledExpectCTHosts(
  1193. const std::string& hashed_host,
  1194. const NetworkIsolationKey& network_isolation_key,
  1195. const ExpectCTState& state) {
  1196. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  1197. DCHECK(state.enforce || !state.report_uri.is_empty());
  1198. enabled_expect_ct_hosts_[CreateExpectCTStateIndex(
  1199. hashed_host, network_isolation_key)] = state;
  1200. }
  1201. TransportSecurityState::STSState::STSState() = default;
  1202. TransportSecurityState::STSState::~STSState() = default;
  1203. bool TransportSecurityState::STSState::ShouldUpgradeToSSL() const {
  1204. return upgrade_mode == MODE_FORCE_HTTPS;
  1205. }
  1206. TransportSecurityState::STSStateIterator::STSStateIterator(
  1207. const TransportSecurityState& state)
  1208. : iterator_(state.enabled_sts_hosts_.begin()),
  1209. end_(state.enabled_sts_hosts_.end()) {
  1210. }
  1211. TransportSecurityState::STSStateIterator::~STSStateIterator() = default;
  1212. TransportSecurityState::PKPState::PKPState() = default;
  1213. TransportSecurityState::PKPState::PKPState(const PKPState& other) = default;
  1214. TransportSecurityState::PKPState::~PKPState() = default;
  1215. TransportSecurityState::ExpectCTState::ExpectCTState() = default;
  1216. TransportSecurityState::ExpectCTState::~ExpectCTState() = default;
  1217. TransportSecurityState::ExpectCTStateIndex::ExpectCTStateIndex(
  1218. const std::string& hashed_host,
  1219. const NetworkIsolationKey& network_isolation_key,
  1220. bool respect_network_isolation_keyn_key)
  1221. : hashed_host(hashed_host),
  1222. network_isolation_key(respect_network_isolation_keyn_key
  1223. ? network_isolation_key
  1224. : NetworkIsolationKey()) {}
  1225. TransportSecurityState::ExpectCTStateIterator::ExpectCTStateIterator(
  1226. const TransportSecurityState& state)
  1227. : iterator_(state.enabled_expect_ct_hosts_.begin()),
  1228. end_(state.enabled_expect_ct_hosts_.end()) {
  1229. state.AssertCalledOnValidThread();
  1230. }
  1231. TransportSecurityState::ExpectCTStateIterator::~ExpectCTStateIterator() =
  1232. default;
  1233. TransportSecurityState::PinSet::PinSet(
  1234. std::string name,
  1235. std::vector<std::vector<uint8_t>> static_spki_hashes,
  1236. std::vector<std::vector<uint8_t>> bad_static_spki_hashes,
  1237. std::string report_uri)
  1238. : name_(std::move(name)),
  1239. static_spki_hashes_(std::move(static_spki_hashes)),
  1240. bad_static_spki_hashes_(std::move(bad_static_spki_hashes)),
  1241. report_uri_(std::move(report_uri)) {}
  1242. TransportSecurityState::PinSet::PinSet(const PinSet& other) = default;
  1243. TransportSecurityState::PinSet::~PinSet() = default;
  1244. TransportSecurityState::PinSetInfo::PinSetInfo(std::string hostname,
  1245. std::string pinset_name,
  1246. bool include_subdomains)
  1247. : hostname_(std::move(hostname)),
  1248. pinset_name_(std::move(pinset_name)),
  1249. include_subdomains_(std::move(include_subdomains)) {}
  1250. bool TransportSecurityState::PKPState::CheckPublicKeyPins(
  1251. const HashValueVector& hashes,
  1252. std::string* failure_log) const {
  1253. // Validate that hashes is not empty. By the time this code is called (in
  1254. // production), that should never happen, but it's good to be defensive.
  1255. // And, hashes *can* be empty in some test scenarios.
  1256. if (hashes.empty()) {
  1257. failure_log->append(
  1258. "Rejecting empty public key chain for public-key-pinned domains: " +
  1259. domain);
  1260. return false;
  1261. }
  1262. if (HashesIntersect(bad_spki_hashes, hashes)) {
  1263. failure_log->append("Rejecting public key chain for domain " + domain +
  1264. ". Validated chain: " + HashesToBase64String(hashes) +
  1265. ", matches one or more bad hashes: " +
  1266. HashesToBase64String(bad_spki_hashes));
  1267. return false;
  1268. }
  1269. // If there are no pins, then any valid chain is acceptable.
  1270. if (spki_hashes.empty())
  1271. return true;
  1272. if (HashesIntersect(spki_hashes, hashes)) {
  1273. return true;
  1274. }
  1275. failure_log->append("Rejecting public key chain for domain " + domain +
  1276. ". Validated chain: " + HashesToBase64String(hashes) +
  1277. ", expected: " + HashesToBase64String(spki_hashes));
  1278. return false;
  1279. }
  1280. bool TransportSecurityState::PKPState::HasPublicKeyPins() const {
  1281. return spki_hashes.size() > 0 || bad_spki_hashes.size() > 0;
  1282. }
  1283. TransportSecurityState::ExpectCTStateIndex
  1284. TransportSecurityState::CreateExpectCTStateIndex(
  1285. const std::string& hashed_host,
  1286. const NetworkIsolationKey& network_isolation_key) {
  1287. return ExpectCTStateIndex(hashed_host, network_isolation_key,
  1288. key_expect_ct_by_nik_);
  1289. }
  1290. void TransportSecurityState::MaybePruneExpectCTState() {
  1291. if (!base::FeatureList::IsEnabled(features::kExpectCTPruning) ||
  1292. enabled_expect_ct_hosts_.size() <
  1293. static_cast<size_t>(features::kExpectCTPruneMax.Get())) {
  1294. return;
  1295. }
  1296. base::Time now = base::Time::Now();
  1297. if (now < earliest_next_prune_expect_ct_time_)
  1298. return;
  1299. earliest_next_prune_expect_ct_time_ =
  1300. now + base::Seconds(features::kExpectCTPruneDelaySecs.Get());
  1301. base::Time last_prunable_observation_time =
  1302. now - base::Days(features::kExpectCTSafeFromPruneDays.Get());
  1303. // Cache this locally, so don't have to repeatedly query the value.
  1304. size_t expect_ct_prune_min = features::kExpectCTPruneMin.Get();
  1305. // Entries that are eligible to be pruned based on the global (not per-NIK)
  1306. // entry limit.
  1307. std::vector<ExpectCTStateMap::iterator> prunable_expect_ct_entries;
  1308. // Clear expired entries first. If that's enough, maybe no valid entries have
  1309. // to be removed. Also populate |prunable_expect_ct_entries|.
  1310. for (auto expect_ct_iterator = enabled_expect_ct_hosts_.begin();
  1311. expect_ct_iterator != enabled_expect_ct_hosts_.end();) {
  1312. if (expect_ct_iterator->second.expiry < now) {
  1313. enabled_expect_ct_hosts_.erase(expect_ct_iterator++);
  1314. continue;
  1315. }
  1316. // If there are fewer than |expect_ct_prune_min| entries remaining, no need
  1317. // to delete anything else.
  1318. if (enabled_expect_ct_hosts_.size() <= expect_ct_prune_min)
  1319. return;
  1320. // Entries that are older than the prunable time window, are report-only, or
  1321. // have a transient NetworkIsolationKey, are considered prunable.
  1322. //
  1323. // If |key_expect_ct_by_nik_| is false, all entries have an empty NIK.
  1324. // IsTransient() returns true for the empty NIK, despite entries being saved
  1325. // to disk, so don't want to delete entries with empty NIKs.
  1326. if (expect_ct_iterator->second.last_observed <
  1327. last_prunable_observation_time ||
  1328. !expect_ct_iterator->second.enforce ||
  1329. (key_expect_ct_by_nik_ &&
  1330. expect_ct_iterator->first.network_isolation_key.IsTransient())) {
  1331. prunable_expect_ct_entries.push_back(expect_ct_iterator);
  1332. }
  1333. ++expect_ct_iterator;
  1334. }
  1335. // Number of entries that need to be removed to reach |expect_ct_prune_min|.
  1336. size_t num_entries_to_prune =
  1337. enabled_expect_ct_hosts_.size() - expect_ct_prune_min;
  1338. if (num_entries_to_prune < prunable_expect_ct_entries.size()) {
  1339. // There are more than enough prunable entries to reach kExpectCTPruneMin.
  1340. // Find the |num_entries_to_prune| most prunable entries, according to
  1341. // ExpectCTPruningSorter.
  1342. auto expect_ct_prune_end =
  1343. prunable_expect_ct_entries.begin() + num_entries_to_prune;
  1344. std::partial_sort(prunable_expect_ct_entries.begin(), expect_ct_prune_end,
  1345. prunable_expect_ct_entries.end(), ExpectCTPruningSorter);
  1346. } else {
  1347. // Otherwise, delete all prunable entries.
  1348. num_entries_to_prune = prunable_expect_ct_entries.size();
  1349. }
  1350. DCHECK_LE(num_entries_to_prune, prunable_expect_ct_entries.size());
  1351. for (size_t i = 0; i < num_entries_to_prune; ++i) {
  1352. enabled_expect_ct_hosts_.erase(prunable_expect_ct_entries[i]);
  1353. }
  1354. // If there are fewer than |kExpectCTPruneMin| entries remaining, or entries
  1355. // are not being keyed by NetworkIsolationKey, nothing left to do.
  1356. if (enabled_expect_ct_hosts_.size() <= expect_ct_prune_min ||
  1357. !key_expect_ct_by_nik_) {
  1358. return;
  1359. }
  1360. // Otherwise, cap the number of entries per NetworkIsolationKey to
  1361. // |kMaxEntriesPerNik|.
  1362. // Create a vector of all the ExpectCT entries for each NIK.
  1363. std::map<net::NetworkIsolationKey, std::vector<ExpectCTStateMap::iterator>>
  1364. nik_map;
  1365. for (auto expect_ct_iterator = enabled_expect_ct_hosts_.begin();
  1366. expect_ct_iterator != enabled_expect_ct_hosts_.end();
  1367. ++expect_ct_iterator) {
  1368. nik_map[expect_ct_iterator->first.network_isolation_key].push_back(
  1369. expect_ct_iterator);
  1370. }
  1371. // For each NIK with more than the maximum number of entries, remove the most
  1372. // prunable entries until it has exactly |kExpectCTMaxEntriesPerNik| entries.
  1373. size_t max_entries_per_nik = features::kExpectCTMaxEntriesPerNik.Get();
  1374. for (auto& nik_entries : nik_map) {
  1375. if (nik_entries.second.size() < max_entries_per_nik)
  1376. continue;
  1377. auto top_frame_origin_prune_end = nik_entries.second.begin() +
  1378. nik_entries.second.size() -
  1379. max_entries_per_nik;
  1380. std::partial_sort(nik_entries.second.begin(), top_frame_origin_prune_end,
  1381. nik_entries.second.end(), ExpectCTPruningSorter);
  1382. for (auto entry_to_prune = nik_entries.second.begin();
  1383. entry_to_prune != top_frame_origin_prune_end; ++entry_to_prune) {
  1384. enabled_expect_ct_hosts_.erase(*entry_to_prune);
  1385. }
  1386. }
  1387. }
  1388. bool TransportSecurityState::ExpectCTPruningSorter(
  1389. const ExpectCTStateMap::iterator& it1,
  1390. const ExpectCTStateMap::iterator& it2) {
  1391. // std::tie requires r-values, so have to put these on the stack to use
  1392. // std::tie.
  1393. bool is_not_transient1 = !it1->first.network_isolation_key.IsTransient();
  1394. bool is_not_transient2 = !it2->first.network_isolation_key.IsTransient();
  1395. return std::tie(is_not_transient1, it1->second.enforce,
  1396. it1->second.last_observed) <
  1397. std::tie(is_not_transient2, it2->second.enforce,
  1398. it2->second.last_observed);
  1399. }
  1400. bool TransportSecurityState::IsCTLogListTimely() const {
  1401. // Preloaded Expect-CT is enforced if the CT log list is timely. Note that
  1402. // unlike HSTS and HPKP, the date of the preloaded list itself (i.e.
  1403. // base::GetBuildTime()) is not directly consulted. Consulting the
  1404. // build time would allow sites that have subsequently disabled Expect-CT
  1405. // to opt-out. However, because as of June 2021, all unexpired certificates
  1406. // are already expected to comply with the policies expressed by Expect-CT,
  1407. // there's no need to offer an opt-out.
  1408. return (base::Time::Now() - ct_log_list_last_update_time_).InDays() <
  1409. 70 /* 10 weeks */;
  1410. }
  1411. bool TransportSecurityState::IsStaticPKPListTimely() const {
  1412. if (pins_list_always_timely_for_testing_) {
  1413. return true;
  1414. }
  1415. // If the list has not been updated via component updater, freshness depends
  1416. // on the compiled-in list freshness.
  1417. if (!host_pins_.has_value()) {
  1418. #if BUILDFLAG(INCLUDE_TRANSPORT_SECURITY_STATE_PRELOAD_LIST)
  1419. return (base::Time::Now() - kPinsListTimestamp).InDays() < 70;
  1420. #else
  1421. return false;
  1422. #endif
  1423. }
  1424. DCHECK(!key_pins_list_last_update_time_.is_null());
  1425. // Else, we use the last update time.
  1426. return (base::Time::Now() - key_pins_list_last_update_time_).InDays() <
  1427. 70 /* 10 weeks */;
  1428. }
  1429. } // namespace net