1 // Copyright 2012 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef NET_HTTP_TRANSPORT_SECURITY_STATE_H_ 6 #define NET_HTTP_TRANSPORT_SECURITY_STATE_H_ 7 8 #include <stdint.h> 9 10 #include <array> 11 #include <map> 12 #include <set> 13 #include <string> 14 15 #include "base/feature_list.h" 16 #include "base/functional/callback.h" 17 #include "base/gtest_prod_util.h" 18 #include "base/memory/raw_ptr.h" 19 #include "base/strings/string_piece.h" 20 #include "base/threading/thread_checker.h" 21 #include "base/time/time.h" 22 #include "base/values.h" 23 #include "crypto/sha2.h" 24 #include "net/base/expiring_cache.h" 25 #include "net/base/hash_value.h" 26 #include "net/base/net_export.h" 27 #include "net/base/network_anonymization_key.h" 28 #include "net/cert/signed_certificate_timestamp_and_status.h" 29 #include "net/http/transport_security_state_source.h" 30 #include "net/log/net_log_with_source.h" 31 #include "third_party/abseil-cpp/absl/types/optional.h" 32 #include "url/gurl.h" 33 34 namespace net { 35 36 namespace ct { 37 enum class CTPolicyCompliance; 38 } 39 40 class HostPortPair; 41 class NetworkAnonymizationKey; 42 class X509Certificate; 43 44 // Feature that controls whether Certificate Transparency is enforced. This 45 // feature is default enabled and meant only as an emergency killswitch. It 46 // will not enable enforcement in platforms that otherwise have it disabled. 47 NET_EXPORT BASE_DECLARE_FEATURE(kCertificateTransparencyEnforcement); 48 49 void NET_EXPORT_PRIVATE SetTransportSecurityStateSourceForTesting( 50 const TransportSecurityStateSource* source); 51 52 // Tracks which hosts have enabled strict transport security and/or public 53 // key pins. 54 // 55 // This object manages the in-memory store. Register a Delegate with 56 // |SetDelegate| to persist the state to disk. 57 // 58 // HTTP strict transport security (HSTS) is defined in 59 // http://tools.ietf.org/html/ietf-websec-strict-transport-sec. 60 class NET_EXPORT TransportSecurityState { 61 public: 62 using HashedHost = std::array<uint8_t, crypto::kSHA256Length>; 63 64 class NET_EXPORT Delegate { 65 public: 66 // This function may not block and may be called with internal locks held. 67 // Thus it must not reenter the TransportSecurityState object. 68 virtual void StateIsDirty(TransportSecurityState* state) = 0; 69 // Same as StateIsDirty but instructs the Delegate to persist the data 70 // immediately and call |callback| when done. 71 virtual void WriteNow(TransportSecurityState* state, 72 base::OnceClosure callback) = 0; 73 74 protected: 75 virtual ~Delegate() = default; 76 }; 77 78 class NET_EXPORT RequireCTDelegate { 79 public: 80 // Provides a capability for altering the default handling of Certificate 81 // Transparency information, allowing it to be always required for some 82 // hosts, for some hosts to be opted out of the default policy, or 83 // allowing the TransportSecurityState to apply the default security 84 // policies. 85 enum class CTRequirementLevel { 86 // The host is required to always supply Certificate Transparency 87 // information that complies with the CT policy. 88 REQUIRED, 89 90 // The host is explicitly not required to supply Certificate 91 // Transparency information that complies with the CT policy. 92 NOT_REQUIRED, 93 94 // The delegate makes no statements, positive or negative, about 95 // requiring the host to supply Certificate Transparency information, 96 // allowing the default behaviour to happen. 97 DEFAULT, 98 }; 99 100 // Called by the TransportSecurityState, allows the Delegate to override 101 // the default handling of Certificate Transparency requirements, if 102 // desired. 103 // |hostname| contains the host being contacted, serving the certificate 104 // |chain|, with the set of hashesh |hashes|. Note that |hashes| and 105 // |chain| are not guaranteed to be in the same order - that is, the first 106 // hash in |hashes| is NOT guaranteed to be for the leaf cert in |chain|. 107 virtual CTRequirementLevel IsCTRequiredForHost( 108 const std::string& hostname, 109 const X509Certificate* chain, 110 const HashValueVector& hashes) = 0; 111 112 protected: 113 virtual ~RequireCTDelegate() = default; 114 }; 115 116 // A STSState describes the strict transport security state (required 117 // upgrade to HTTPS). 118 class NET_EXPORT STSState { 119 public: 120 enum UpgradeMode { 121 // These numbers must match those in hsts_view.js, function modeToString. 122 MODE_FORCE_HTTPS = 0, 123 MODE_DEFAULT = 1, 124 }; 125 126 STSState(); 127 ~STSState(); 128 129 // The absolute time (UTC) when the |upgrade_mode| (and other state) was 130 // observed. 131 base::Time last_observed; 132 133 // The absolute time (UTC) when |upgrade_mode| (and other state) 134 // expires. 135 base::Time expiry; 136 137 UpgradeMode upgrade_mode = MODE_DEFAULT; 138 139 // Are subdomains subject to this policy state? 140 bool include_subdomains = false; 141 142 // The domain which matched during a search for this STSState entry. 143 // Updated by |GetDynamicSTSState| and |GetStaticDomainState|. 144 std::string domain; 145 146 // ShouldUpgradeToSSL returns true iff HTTP requests should be internally 147 // redirected to HTTPS (also if WS should be upgraded to WSS). 148 bool ShouldUpgradeToSSL() const; 149 }; 150 151 class NET_EXPORT STSStateIterator { 152 public: 153 explicit STSStateIterator(const TransportSecurityState& state); 154 ~STSStateIterator(); 155 HasNext()156 bool HasNext() const { return iterator_ != end_; } Advance()157 void Advance() { ++iterator_; } hostname()158 const HashedHost& hostname() const { return iterator_->first; } domain_state()159 const STSState& domain_state() const { return iterator_->second; } 160 161 private: 162 std::map<HashedHost, STSState>::const_iterator iterator_; 163 std::map<HashedHost, STSState>::const_iterator end_; 164 }; 165 166 // PKPStatus describes the result of a pinning check. 167 enum class PKPStatus { 168 // Pinning was enabled and the necessary pins were not present. 169 VIOLATED, 170 171 // Pinning was not enabled, or pinning was enabled and the certificate 172 // satisfied the pins. 173 OK, 174 175 // Pinning was enabled and the certificate did not satisfy the pins, but the 176 // violation was ignored due to local policy, such as a local trust anchor. 177 BYPASSED, 178 }; 179 180 // A PKPState describes the public key pinning state. 181 class NET_EXPORT PKPState { 182 public: 183 PKPState(); 184 PKPState(const PKPState& other); 185 ~PKPState(); 186 187 // The absolute time (UTC) when the |spki_hashes| (and other state) were 188 // observed. 189 base::Time last_observed; 190 191 // The absolute time (UTC) when the |spki_hashes| expire. 192 base::Time expiry; 193 194 // Optional; hashes of pinned SubjectPublicKeyInfos. 195 HashValueVector spki_hashes; 196 197 // Optional; hashes of static known-bad SubjectPublicKeyInfos which MUST 198 // NOT intersect with the set of SPKIs in the TLS server's certificate 199 // chain. 200 HashValueVector bad_spki_hashes; 201 202 // Are subdomains subject to this policy state? 203 bool include_subdomains = false; 204 205 // The domain which matched during a search for this DomainState entry. 206 // Updated by |GetDynamicPKPState| and |GetStaticDomainState|. 207 std::string domain; 208 209 // An optional URI indicating where reports should be sent when this 210 // pin is violated, or empty when omitted. 211 GURL report_uri; 212 213 // Takes a set of SubjectPublicKeyInfo |hashes| and returns true if: 214 // 1) |bad_static_spki_hashes| does not intersect |hashes|; AND 215 // 2) Both |static_spki_hashes| and |dynamic_spki_hashes| are empty 216 // or at least one of them intersects |hashes|. 217 // 218 // |{dynamic,static}_spki_hashes| contain trustworthy public key hashes, 219 // any one of which is sufficient to validate the certificate chain in 220 // question. The public keys could be of a root CA, intermediate CA, or 221 // leaf certificate, depending on the security vs. disaster recovery 222 // tradeoff selected. (Pinning only to leaf certifiates increases 223 // security because you no longer trust any CAs, but it hampers disaster 224 // recovery because you can't just get a new certificate signed by the 225 // CA.) 226 // 227 // |bad_static_spki_hashes| contains public keys that we don't want to 228 // trust. 229 bool CheckPublicKeyPins(const HashValueVector& hashes, 230 std::string* failure_log) const; 231 232 // Returns true if any of the HashValueVectors |static_spki_hashes|, 233 // |bad_static_spki_hashes|, or |dynamic_spki_hashes| contains any 234 // items. 235 bool HasPublicKeyPins() const; 236 }; 237 238 // An interface for asynchronously sending HPKP violation reports. 239 class NET_EXPORT ReportSenderInterface { 240 public: 241 // Sends the given serialized |report| to |report_uri| with 242 // Content-Type header as specified in 243 // |content_type|. |content_type| should be non-empty. 244 // |success_callback| is called iff an HTTP 200 response is received. 245 // |error_callback| is called in all other cases. Error callback's 246 // |net_error| can be net::OK if the upload was successful but the server 247 // returned a non-HTTP 200 |http_response_code|. In all other cases, 248 // error callback's |http_response_code| is -1. 249 virtual void Send(const GURL& report_uri, 250 base::StringPiece content_type, 251 base::StringPiece report, 252 const NetworkAnonymizationKey& network_anonymization_key, 253 base::OnceCallback<void()> success_callback, 254 base::OnceCallback<void(const GURL&, 255 int /* net_error */, 256 int /* http_response_code */)> 257 error_callback) = 0; 258 259 protected: 260 virtual ~ReportSenderInterface() = default; 261 }; 262 263 class NET_EXPORT PinSet { 264 public: 265 PinSet(std::string name, 266 std::vector<std::vector<uint8_t>> static_spki_hashes, 267 std::vector<std::vector<uint8_t>> bad_static_spki_hashes, 268 std::string report_uri); 269 PinSet(const PinSet& other); 270 ~PinSet(); 271 name()272 const std::string& name() const { return name_; } static_spki_hashes()273 const std::vector<std::vector<uint8_t>>& static_spki_hashes() const { 274 return static_spki_hashes_; 275 } bad_static_spki_hashes()276 const std::vector<std::vector<uint8_t>>& bad_static_spki_hashes() const { 277 return bad_static_spki_hashes_; 278 } report_uri()279 const std::string& report_uri() const { return report_uri_; } 280 281 private: 282 std::string name_; 283 std::vector<std::vector<uint8_t>> static_spki_hashes_; 284 std::vector<std::vector<uint8_t>> bad_static_spki_hashes_; 285 std::string report_uri_; 286 }; 287 288 struct NET_EXPORT PinSetInfo { 289 std::string hostname_; 290 std::string pinset_name_; 291 bool include_subdomains_; 292 293 PinSetInfo(std::string hostname, 294 std::string pinset_name, 295 bool include_subdomains); 296 }; 297 298 // Indicates whether or not a public key pin check should send a 299 // report if a violation is detected. 300 enum PublicKeyPinReportStatus { ENABLE_PIN_REPORTS, DISABLE_PIN_REPORTS }; 301 302 // Indicates whether a connection met CT requirements. 303 enum CTRequirementsStatus { 304 // CT was not required for the connection. 305 CT_NOT_REQUIRED, 306 // CT was required for the connection and valid Certificate Transparency 307 // information was provided. 308 CT_REQUIREMENTS_MET, 309 // CT was required for the connection but valid CT info was not provided. 310 CT_REQUIREMENTS_NOT_MET, 311 }; 312 313 TransportSecurityState(); 314 315 // Creates a TransportSecurityState object that will skip the check to force 316 // HTTPS from static entries for the given set of hosts. All hostnames in the 317 // bypass list must consist of a single label, i.e. they must be a TLD. 318 explicit TransportSecurityState( 319 std::vector<std::string> hsts_host_bypass_list); 320 321 TransportSecurityState(const TransportSecurityState&) = delete; 322 TransportSecurityState& operator=(const TransportSecurityState&) = delete; 323 324 ~TransportSecurityState(); 325 326 // These functions search for static and dynamic STS and PKP states, and 327 // invoke the functions of the same name on them. These functions are the 328 // primary public interface; direct access to STS and PKP states is best 329 // left to tests. The caller needs to handle the optional pinning override 330 // when is_issued_by_known_root is false. 331 bool ShouldSSLErrorsBeFatal(const std::string& host); 332 bool ShouldUpgradeToSSL(const std::string& host, 333 const NetLogWithSource& net_log = NetLogWithSource()); 334 PKPStatus CheckPublicKeyPins( 335 const HostPortPair& host_port_pair, 336 bool is_issued_by_known_root, 337 const HashValueVector& hashes, 338 const X509Certificate* served_certificate_chain, 339 const X509Certificate* validated_certificate_chain, 340 const PublicKeyPinReportStatus report_status, 341 const NetworkAnonymizationKey& network_anonymization_key, 342 std::string* failure_log); 343 bool HasPublicKeyPins(const std::string& host); 344 345 // Returns CT_REQUIREMENTS_NOT_MET if a connection violates CT policy 346 // requirements: that is, if a connection to |host|, using the validated 347 // certificate |validated_certificate_chain|, is expected to be accompanied 348 // with valid Certificate Transparency information that complies with the 349 // connection's CTPolicyEnforcer and |policy_compliance| indicates that 350 // the connection does not comply. 351 // 352 // The behavior may be further be altered by setting a RequireCTDelegate 353 // via |SetRequireCTDelegate()|. 354 CTRequirementsStatus CheckCTRequirements( 355 const net::HostPortPair& host_port_pair, 356 bool is_issued_by_known_root, 357 const HashValueVector& public_key_hashes, 358 const X509Certificate* validated_certificate_chain, 359 const X509Certificate* served_certificate_chain, 360 const SignedCertificateTimestampAndStatusList& 361 signed_certificate_timestamps, 362 ct::CTPolicyCompliance policy_compliance); 363 364 // Assign a |Delegate| for persisting the transport security state. If 365 // |NULL|, state will not be persisted. The caller retains 366 // ownership of |delegate|. 367 // Note: This is only used for serializing/deserializing the 368 // TransportSecurityState. 369 void SetDelegate(Delegate* delegate); 370 371 void SetReportSender(ReportSenderInterface* report_sender); 372 373 // Assigns a delegate responsible for determining whether or not a 374 // connection to a given host should require Certificate Transparency 375 // information that complies with the CT policy provided by a 376 // CTPolicyEnforcer. 377 // If nullptr, no delegate will be consulted. 378 // The caller retains ownership of the |delegate|, and must persist for 379 // the lifetime of this object or until called with nullptr, whichever 380 // occurs first. 381 void SetRequireCTDelegate(RequireCTDelegate* delegate); 382 383 // If |emergency_disable| is set to true, will stop requiring CT 384 // compliance on any further requests regardless of host or certificate 385 // status. SetCTEmergencyDisabled(bool emergency_disable)386 void SetCTEmergencyDisabled(bool emergency_disable) { 387 ct_emergency_disable_ = emergency_disable; 388 } 389 is_ct_emergency_disabled_for_testing()390 bool is_ct_emergency_disabled_for_testing() const { 391 return ct_emergency_disable_; 392 } 393 394 // |pinsets| should include all known pinsets, |host_pins| the information 395 // related to each hostname's pin, and |update_time| the time at which this 396 // list was known to be up to date. 397 void UpdatePinList(const std::vector<PinSet>& pinsets, 398 const std::vector<PinSetInfo>& host_pins, 399 base::Time update_time); 400 401 // Clears all dynamic data (e.g. HSTS and HPKP data). 402 // 403 // Does NOT persist changes using the Delegate, as this function is only 404 // used to clear any dynamic data prior to re-loading it from a file. 405 // Note: This is only used for serializing/deserializing the 406 // TransportSecurityState. 407 void ClearDynamicData(); 408 409 // Inserts |state| into |enabled_sts_hosts_| under the key |hashed_host|. 410 // |hashed_host| is already in the internal representation. 411 // Note: This is only used for serializing/deserializing the 412 // TransportSecurityState. 413 void AddOrUpdateEnabledSTSHosts(const HashedHost& hashed_host, 414 const STSState& state); 415 416 // Deletes all dynamic data (e.g. HSTS or HPKP data) created between a time 417 // period [|start_time|, |end_time|). 418 // 419 // If any entries are deleted, the new state will be persisted through 420 // the Delegate (if any). Calls |callback| when data is persisted to disk. 421 void DeleteAllDynamicDataBetween(base::Time start_time, 422 base::Time end_time, 423 base::OnceClosure callback); 424 425 // Deletes any dynamic data stored for |host| (e.g. HSTS or HPKP data). 426 // If |host| doesn't have an exact entry then no action is taken. Does 427 // not delete static (i.e. preloaded) data. Returns true iff an entry 428 // was deleted. 429 // 430 // If an entry is deleted, the new state will be persisted through 431 // the Delegate (if any). 432 bool DeleteDynamicDataForHost(const std::string& host); 433 434 // Returns true and updates |*result| if |host| has dynamic or static 435 // HSTS/HPKP (respectively) state. If multiple entries match |host|, dynamic 436 // state is preferred over static state and other than that the most specific 437 // match determines the return value (both is in deviation of RFC6797, cf. 438 // https://crbug.com/821811). 439 // 440 // Note that these methods are not const because they opportunistically remove 441 // entries that have expired. 442 bool GetSTSState(const std::string& host, STSState* sts_result); 443 bool GetPKPState(const std::string& host, PKPState* pkp_result); 444 445 // Returns true and updates |*result| iff |host| has static HSTS/HPKP 446 // (respectively) state. If multiple entries match |host|, the most specific 447 // match determines the return value. 448 bool GetStaticSTSState(const std::string& host, STSState* sts_result) const; 449 bool GetStaticPKPState(const std::string& host, PKPState* pkp_result) const; 450 451 // Returns true and updates |*result| iff |host| has dynamic 452 // HSTS/HPKP (respectively) state. If multiple entries match |host|, 453 // the most specific match determines the return value. 454 // 455 // Note that these methods are not const because they opportunistically remove 456 // entries that have expired. 457 bool GetDynamicSTSState(const std::string& host, STSState* result); 458 bool GetDynamicPKPState(const std::string& host, PKPState* result); 459 460 // Processes an HSTS header value from the host, adding entries to 461 // dynamic state if necessary. 462 bool AddHSTSHeader(const std::string& host, const std::string& value); 463 464 // Adds explicitly-specified data as if it was processed from an 465 // HSTS header (used for net-internals and unit tests). 466 void AddHSTS(const std::string& host, 467 const base::Time& expiry, 468 bool include_subdomains); 469 470 // Adds explicitly-specified data as if it was processed from an HPKP header. 471 // Note: dynamic PKP data is not persisted. 472 void AddHPKP(const std::string& host, 473 const base::Time& expiry, 474 bool include_subdomains, 475 const HashValueVector& hashes, 476 const GURL& report_uri); 477 478 // Enables or disables public key pinning bypass for local trust anchors. 479 // Disabling the bypass for local trust anchors is highly discouraged. 480 // This method is used by Cronet only and *** MUST NOT *** be used by any 481 // other consumer. For more information see "How does key pinning interact 482 // with local proxies and filters?" at 483 // https://www.chromium.org/Home/chromium-security/security-faq 484 void SetEnablePublicKeyPinningBypassForLocalTrustAnchors(bool value); 485 AssertCalledOnValidThread()486 void AssertCalledOnValidThread() const { 487 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); 488 } 489 490 // For unit tests only. Forces CheckCTRequirements() to unconditionally 491 // check compliance. 492 static void SetRequireCTForTesting(bool required); 493 494 // For unit tests only. Clears the caches that deduplicate sent PKP reports. 495 void ClearReportCachesForTesting(); 496 497 // For unit tests only. EnableStaticPinsForTesting()498 void EnableStaticPinsForTesting() { enable_static_pins_ = true; } has_dynamic_pkp_state()499 bool has_dynamic_pkp_state() const { return !enabled_pkp_hosts_.empty(); } 500 501 // Sets whether pinning list timestamp freshness should be ignored for 502 // testing. SetPinningListAlwaysTimelyForTesting(bool always_timely)503 void SetPinningListAlwaysTimelyForTesting(bool always_timely) { 504 pins_list_always_timely_for_testing_ = always_timely; 505 } 506 507 // The number of cached STSState entries. 508 size_t num_sts_entries() const; 509 510 private: 511 friend class TransportSecurityStateTest; 512 friend class TransportSecurityStateStaticFuzzer; 513 FRIEND_TEST_ALL_PREFIXES(HttpSecurityHeadersTest, NoClobberPins); 514 515 typedef std::map<HashedHost, STSState> STSStateMap; 516 typedef std::map<HashedHost, PKPState> PKPStateMap; 517 typedef ExpiringCache<std::string, bool, base::TimeTicks, std::less<>> 518 ReportCache; 519 520 base::Value::Dict NetLogUpgradeToSSLParam(const std::string& host); 521 522 // IsBuildTimely returns true if the current build is new enough ensure that 523 // built in security information (i.e. HSTS preloading and pinning 524 // information) is timely. 525 static bool IsBuildTimely(); 526 527 // Helper method for actually checking pins. 528 PKPStatus CheckPublicKeyPinsImpl( 529 const HostPortPair& host_port_pair, 530 bool is_issued_by_known_root, 531 const HashValueVector& hashes, 532 const X509Certificate* served_certificate_chain, 533 const X509Certificate* validated_certificate_chain, 534 const PublicKeyPinReportStatus report_status, 535 const NetworkAnonymizationKey& network_anonymization_key, 536 std::string* failure_log); 537 538 // If a Delegate is present, notify it that the internal state has 539 // changed. 540 void DirtyNotify(); 541 542 // Adds HSTS and HPKP state for |host|. The new state supercedes 543 // any previous state for the |host|, including static entries. 544 // 545 // The new state for |host| is persisted using the Delegate (if any). 546 void AddHSTSInternal(const std::string& host, 547 STSState::UpgradeMode upgrade_mode, 548 const base::Time& expiry, 549 bool include_subdomains); 550 void AddHPKPInternal(const std::string& host, 551 const base::Time& last_observed, 552 const base::Time& expiry, 553 bool include_subdomains, 554 const HashValueVector& hashes, 555 const GURL& report_uri); 556 557 // Returns true if a request to |host_port_pair| with the given 558 // SubjectPublicKeyInfo |hashes| satisfies the pins in |pkp_state|, 559 // and false otherwise. If a violation is found and reporting is 560 // configured (i.e. there is a report URI in |pkp_state| and 561 // |report_status| says to), this method sends an HPKP violation 562 // report containing |served_certificate_chain| and 563 // |validated_certificate_chain|. 564 PKPStatus CheckPinsAndMaybeSendReport( 565 const HostPortPair& host_port_pair, 566 bool is_issued_by_known_root, 567 const TransportSecurityState::PKPState& pkp_state, 568 const HashValueVector& hashes, 569 const X509Certificate* served_certificate_chain, 570 const X509Certificate* validated_certificate_chain, 571 const TransportSecurityState::PublicKeyPinReportStatus report_status, 572 const net::NetworkAnonymizationKey& network_anonymization_key, 573 std::string* failure_log); 574 575 // Returns true if the static key pinning list has been updated in the last 10 576 // weeks. 577 bool IsStaticPKPListTimely() const; 578 579 // The sets of hosts that have enabled TransportSecurity. |domain| will always 580 // be empty for a STSState or PKPState in these maps; the domain comes from 581 // the map keys instead. In addition, |upgrade_mode| in the STSState is never 582 // MODE_DEFAULT and |HasPublicKeyPins| in the PKPState always returns true. 583 STSStateMap enabled_sts_hosts_; 584 PKPStateMap enabled_pkp_hosts_; 585 586 raw_ptr<Delegate> delegate_ = nullptr; 587 588 raw_ptr<ReportSenderInterface> report_sender_ = nullptr; 589 590 // True if static pins should be used. 591 bool enable_static_pins_ = true; 592 593 // True if public key pinning bypass is enabled for local trust anchors. 594 bool enable_pkp_bypass_for_local_trust_anchors_ = true; 595 596 raw_ptr<RequireCTDelegate> require_ct_delegate_ = nullptr; 597 598 // Keeps track of reports that have been sent recently for 599 // rate-limiting. 600 ReportCache sent_hpkp_reports_cache_; 601 602 std::set<std::string> hsts_host_bypass_list_; 603 604 bool ct_emergency_disable_ = false; 605 606 // The values in host_pins_ maps are references to PinSet objects in the 607 // pinsets_ vector. 608 absl::optional< 609 std::map<std::string, std::pair<const PinSet*, bool>, std::less<>>> 610 host_pins_; 611 base::Time key_pins_list_last_update_time_; 612 std::vector<PinSet> pinsets_; 613 614 bool pins_list_always_timely_for_testing_ = false; 615 616 THREAD_CHECKER(thread_checker_); 617 }; 618 619 } // namespace net 620 621 #endif // NET_HTTP_TRANSPORT_SECURITY_STATE_H_ 622