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