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 5 #ifndef NET_HTTP_TRANSPORT_SECURITY_STATE_H_ 6 #define NET_HTTP_TRANSPORT_SECURITY_STATE_H_ 7 8 #include <stdint.h> 9 10 #include <map> 11 #include <string> 12 13 #include "base/callback.h" 14 #include "base/feature_list.h" 15 #include "base/gtest_prod_util.h" 16 #include "base/macros.h" 17 #include "base/strings/string_piece.h" 18 #include "base/threading/thread_checker.h" 19 #include "base/time/time.h" 20 #include "net/base/expiring_cache.h" 21 #include "net/base/hash_value.h" 22 #include "net/base/net_export.h" 23 #include "net/base/network_isolation_key.h" 24 #include "net/cert/signed_certificate_timestamp_and_status.h" 25 #include "net/http/transport_security_state_source.h" 26 #include "url/gurl.h" 27 28 namespace net { 29 30 namespace ct { 31 enum class CTPolicyCompliance; 32 } 33 34 class HostPortPair; 35 class NetworkIsolationKey; 36 class SSLInfo; 37 class X509Certificate; 38 39 // Controls whether or not Certificate Transparency should be enforced for 40 // newly-issued certificates. 41 extern const NET_EXPORT_PRIVATE base::Feature kEnforceCTForNewCerts; 42 43 void NET_EXPORT_PRIVATE SetTransportSecurityStateSourceForTesting( 44 const TransportSecurityStateSource* source); 45 46 // Tracks which hosts have enabled strict transport security and/or public 47 // key pins. 48 // 49 // This object manages the in-memory store. Register a Delegate with 50 // |SetDelegate| to persist the state to disk. 51 // 52 // HTTP strict transport security (HSTS) is defined in 53 // http://tools.ietf.org/html/ietf-websec-strict-transport-sec. 54 class NET_EXPORT TransportSecurityState { 55 public: 56 class NET_EXPORT Delegate { 57 public: 58 // This function may not block and may be called with internal locks held. 59 // Thus it must not reenter the TransportSecurityState object. 60 virtual void StateIsDirty(TransportSecurityState* state) = 0; 61 // Same as StateIsDirty but instructs the Delegate to persist the data 62 // immediately and call |callback| when done. 63 virtual void WriteNow(TransportSecurityState* state, 64 base::OnceClosure callback) = 0; 65 66 protected: ~Delegate()67 virtual ~Delegate() {} 68 }; 69 70 class NET_EXPORT RequireCTDelegate { 71 public: 72 // Provides a capability for altering the default handling of Certificate 73 // Transparency information, allowing it to be always required for some 74 // hosts, for some hosts to be opted out of the default policy, or 75 // allowing the TransportSecurityState to apply the default security 76 // policies. 77 enum class CTRequirementLevel { 78 // The host is required to always supply Certificate Transparency 79 // information that complies with the CT policy. 80 REQUIRED, 81 82 // The host is explicitly not required to supply Certificate 83 // Transparency information that complies with the CT policy. 84 NOT_REQUIRED, 85 86 // The delegate makes no statements, positive or negative, about 87 // requiring the host to supply Certificate Transparency information, 88 // allowing the default behaviour to happen. 89 DEFAULT, 90 }; 91 92 // Called by the TransportSecurityState, allows the Delegate to override 93 // the default handling of Certificate Transparency requirements, if 94 // desired. 95 // |hostname| contains the host being contacted, serving the certificate 96 // |chain|, with the set of hashesh |hashes|. Note that |hashes| and 97 // |chain| are not guaranteed to be in the same order - that is, the first 98 // hash in |hashes| is NOT guaranteed to be for the leaf cert in |chain|. 99 virtual CTRequirementLevel IsCTRequiredForHost( 100 const std::string& hostname, 101 const X509Certificate* chain, 102 const HashValueVector& hashes) = 0; 103 104 protected: 105 virtual ~RequireCTDelegate() = default; 106 }; 107 108 // A STSState describes the strict transport security state (required 109 // upgrade to HTTPS). 110 class NET_EXPORT STSState { 111 public: 112 enum UpgradeMode { 113 // These numbers must match those in hsts_view.js, function modeToString. 114 MODE_FORCE_HTTPS = 0, 115 MODE_DEFAULT = 1, 116 }; 117 118 STSState(); 119 ~STSState(); 120 121 // The absolute time (UTC) when the |upgrade_mode| (and other state) was 122 // observed. 123 base::Time last_observed; 124 125 // The absolute time (UTC) when |upgrade_mode| (and other state) 126 // expires. 127 base::Time expiry; 128 129 UpgradeMode upgrade_mode; 130 131 // Are subdomains subject to this policy state? 132 bool include_subdomains; 133 134 // The domain which matched during a search for this STSState entry. 135 // Updated by |GetDynamicSTSState| and |GetStaticDomainState|. 136 std::string domain; 137 138 // ShouldUpgradeToSSL returns true iff HTTP requests should be internally 139 // redirected to HTTPS (also if WS should be upgraded to WSS). 140 bool ShouldUpgradeToSSL() const; 141 }; 142 143 class NET_EXPORT STSStateIterator { 144 public: 145 explicit STSStateIterator(const TransportSecurityState& state); 146 ~STSStateIterator(); 147 HasNext()148 bool HasNext() const { return iterator_ != end_; } Advance()149 void Advance() { ++iterator_; } hostname()150 const std::string& hostname() const { return iterator_->first; } domain_state()151 const STSState& domain_state() const { return iterator_->second; } 152 153 private: 154 std::map<std::string, STSState>::const_iterator iterator_; 155 std::map<std::string, STSState>::const_iterator end_; 156 }; 157 158 // PKPStatus describes the result of a pinning check. 159 enum class PKPStatus { 160 // Pinning was enabled and the necessary pins were not present. 161 VIOLATED, 162 163 // Pinning was not enabled, or pinning was enabled and the certificate 164 // satisfied the pins. 165 OK, 166 167 // Pinning was enabled and the certificate did not satisfy the pins, but the 168 // violation was ignored due to local policy, such as a local trust anchor. 169 BYPASSED, 170 }; 171 172 // A PKPState describes the public key pinning state. 173 class NET_EXPORT PKPState { 174 public: 175 PKPState(); 176 PKPState(const PKPState& other); 177 ~PKPState(); 178 179 // The absolute time (UTC) when the |spki_hashes| (and other state) were 180 // observed. 181 base::Time last_observed; 182 183 // The absolute time (UTC) when the |spki_hashes| expire. 184 base::Time expiry; 185 186 // Optional; hashes of pinned SubjectPublicKeyInfos. 187 HashValueVector spki_hashes; 188 189 // Optional; hashes of static known-bad SubjectPublicKeyInfos which MUST 190 // NOT intersect with the set of SPKIs in the TLS server's certificate 191 // chain. 192 HashValueVector bad_spki_hashes; 193 194 // Are subdomains subject to this policy state? 195 bool include_subdomains; 196 197 // The domain which matched during a search for this DomainState entry. 198 // Updated by |GetDynamicPKPState| and |GetStaticDomainState|. 199 std::string domain; 200 201 // An optional URI indicating where reports should be sent when this 202 // pin is violated, or empty when omitted. 203 GURL report_uri; 204 205 // Takes a set of SubjectPublicKeyInfo |hashes| and returns true if: 206 // 1) |bad_static_spki_hashes| does not intersect |hashes|; AND 207 // 2) Both |static_spki_hashes| and |dynamic_spki_hashes| are empty 208 // or at least one of them intersects |hashes|. 209 // 210 // |{dynamic,static}_spki_hashes| contain trustworthy public key hashes, 211 // any one of which is sufficient to validate the certificate chain in 212 // question. The public keys could be of a root CA, intermediate CA, or 213 // leaf certificate, depending on the security vs. disaster recovery 214 // tradeoff selected. (Pinning only to leaf certifiates increases 215 // security because you no longer trust any CAs, but it hampers disaster 216 // recovery because you can't just get a new certificate signed by the 217 // CA.) 218 // 219 // |bad_static_spki_hashes| contains public keys that we don't want to 220 // trust. 221 bool CheckPublicKeyPins(const HashValueVector& hashes, 222 std::string* failure_log) const; 223 224 // Returns true if any of the HashValueVectors |static_spki_hashes|, 225 // |bad_static_spki_hashes|, or |dynamic_spki_hashes| contains any 226 // items. 227 bool HasPublicKeyPins() const; 228 }; 229 230 // An ExpectCTState describes a site that expects valid Certificate 231 // Transparency information to be supplied on every connection to it. 232 class NET_EXPORT ExpectCTState { 233 public: 234 ExpectCTState(); 235 ~ExpectCTState(); 236 237 // The URI to which reports should be sent if valid CT info is not 238 // provided. 239 GURL report_uri; 240 // True if connections should be closed if they do not comply with the CT 241 // policy. If false, noncompliant connections will be allowed but reports 242 // will be sent about the violation. 243 bool enforce; 244 // The absolute time (UTC) when the Expect-CT state was last observed. 245 base::Time last_observed; 246 // The absolute time (UTC) when the Expect-CT state expires. 247 base::Time expiry; 248 }; 249 250 // Unlike other data, Expect-CT information is indexed by NetworkIsolationKey 251 // in addition to domain hash, to prevent leaking user IDs across different 252 // first party contexts. Public only because ExpectCTStateIterator is public 253 // and depends on it. 254 struct ExpectCTStateIndex { 255 // Creates an ExpectCTStateIndex. Uses an empty NetworkIsolationKey instead 256 // of the passed in one, depending on |respect_network_isolation_key|. 257 // The value of features::kPartitionExpectCTStateByNetworkIsolationKey is 258 // cached on creation of the TransportSecurityState, and then passed in to 259 // this method whenever an ExpectCTStateIndex() is created, to avoid 260 // constantly querying the field trial. 261 ExpectCTStateIndex(const std::string& hashed_host, 262 const NetworkIsolationKey& network_isolation_key, 263 bool respect_network_isolation_key); 264 265 bool operator<(const ExpectCTStateIndex& other) const { 266 return std::tie(hashed_host, network_isolation_key) < 267 std::tie(other.hashed_host, other.network_isolation_key); 268 } 269 270 std::string hashed_host; 271 NetworkIsolationKey network_isolation_key; 272 }; 273 274 class NET_EXPORT ExpectCTStateIterator { 275 public: 276 explicit ExpectCTStateIterator(const TransportSecurityState& state); 277 ~ExpectCTStateIterator(); 278 HasNext()279 bool HasNext() const { return iterator_ != end_; } Advance()280 void Advance() { ++iterator_; } hostname()281 const std::string& hostname() const { return iterator_->first.hashed_host; } network_isolation_key()282 const NetworkIsolationKey& network_isolation_key() const { 283 return iterator_->first.network_isolation_key; 284 } domain_state()285 const ExpectCTState& domain_state() const { return iterator_->second; } 286 287 private: 288 std::map<ExpectCTStateIndex, ExpectCTState>::const_iterator iterator_; 289 std::map<ExpectCTStateIndex, ExpectCTState>::const_iterator end_; 290 }; 291 292 // An interface for asynchronously sending HPKP violation reports. 293 class NET_EXPORT ReportSenderInterface { 294 public: 295 // Sends the given serialized |report| to |report_uri| with 296 // Content-Type header as specified in 297 // |content_type|. |content_type| should be non-empty. 298 // |success_callback| is called iff an HTTP 200 response is received. 299 // |error_callback| is called in all other cases. Error callback's 300 // |net_error| can be net::OK if the upload was successful but the server 301 // returned a non-HTTP 200 |http_response_code|. In all other cases, 302 // error callback's |http_response_code| is -1. 303 virtual void Send(const GURL& report_uri, 304 base::StringPiece content_type, 305 base::StringPiece report, 306 const NetworkIsolationKey& network_isolation_key, 307 base::OnceCallback<void()> success_callback, 308 base::OnceCallback<void(const GURL&, 309 int /* net_error */, 310 int /* http_response_code */)> 311 error_callback) = 0; 312 313 protected: ~ReportSenderInterface()314 virtual ~ReportSenderInterface() {} 315 }; 316 317 // An interface for building and asynchronously sending reports when a 318 // site expects valid Certificate Transparency information but it 319 // wasn't supplied. 320 class NET_EXPORT ExpectCTReporter { 321 public: 322 // Called when the host in |host_port_pair| has opted in to have 323 // reports about Expect CT policy violations sent to |report_uri|, 324 // and such a violation has occurred. 325 virtual void OnExpectCTFailed( 326 const net::HostPortPair& host_port_pair, 327 const GURL& report_uri, 328 base::Time expiration, 329 const X509Certificate* validated_certificate_chain, 330 const X509Certificate* served_certificate_chain, 331 const SignedCertificateTimestampAndStatusList& 332 signed_certificate_timestamps, 333 const NetworkIsolationKey& network_isolation_key) = 0; 334 335 protected: ~ExpectCTReporter()336 virtual ~ExpectCTReporter() {} 337 }; 338 339 // Indicates whether or not a public key pin check should send a 340 // report if a violation is detected. 341 enum PublicKeyPinReportStatus { ENABLE_PIN_REPORTS, DISABLE_PIN_REPORTS }; 342 343 // Indicates whether or not an Expect-CT check should send a report if a 344 // violation is detected. 345 enum ExpectCTReportStatus { 346 ENABLE_EXPECT_CT_REPORTS, 347 DISABLE_EXPECT_CT_REPORTS 348 }; 349 350 // Indicates whether a connection met CT requirements. 351 enum CTRequirementsStatus { 352 // CT was not required for the connection. 353 CT_NOT_REQUIRED, 354 // CT was required for the connection and valid Certificate Transparency 355 // information was provided. 356 CT_REQUIREMENTS_MET, 357 // CT was required for the connection but valid CT info was not provided. 358 CT_REQUIREMENTS_NOT_MET, 359 }; 360 361 // Feature that controls whether Expect-CT HTTP headers are parsed, processed, 362 // and stored. 363 static const base::Feature kDynamicExpectCTFeature; 364 365 TransportSecurityState(); 366 367 // Creates a TransportSecurityState object that will skip the check to force 368 // HTTPS from static entries for the given set of hosts. All hostnames in the 369 // bypass list must consist of a single label, i.e. they must be a TLD. 370 explicit TransportSecurityState( 371 std::vector<std::string> hsts_host_bypass_list); 372 373 ~TransportSecurityState(); 374 375 // These functions search for static and dynamic STS and PKP states, and 376 // invoke the functions of the same name on them. These functions are the 377 // primary public interface; direct access to STS and PKP states is best 378 // left to tests. The caller needs to handle the optional pinning override 379 // when is_issued_by_known_root is false. 380 bool ShouldSSLErrorsBeFatal(const std::string& host); 381 bool ShouldUpgradeToSSL(const std::string& host); 382 PKPStatus CheckPublicKeyPins( 383 const HostPortPair& host_port_pair, 384 bool is_issued_by_known_root, 385 const HashValueVector& hashes, 386 const X509Certificate* served_certificate_chain, 387 const X509Certificate* validated_certificate_chain, 388 const PublicKeyPinReportStatus report_status, 389 const NetworkIsolationKey& network_isolation_key, 390 std::string* failure_log); 391 bool HasPublicKeyPins(const std::string& host); 392 393 // Returns CT_REQUIREMENTS_NOT_MET if a connection violates CT policy 394 // requirements: that is, if a connection to |host|, using the validated 395 // certificate |validated_certificate_chain|, is expected to be accompanied 396 // with valid Certificate Transparency information that complies with the 397 // connection's CTPolicyEnforcer and |policy_compliance| indicates that 398 // the connection does not comply. 399 // 400 // The behavior may be further be altered by setting a RequireCTDelegate 401 // via |SetRequireCTDelegate()|. 402 // 403 // This method checks Expect-CT state for |host| if |issued_by_known_root| is 404 // true. If Expect-CT is configured for |host| and the connection is not 405 // compliant and |report_status| is ENABLE_EXPECT_CT_REPORTS, then a report 406 // will be sent. 407 CTRequirementsStatus CheckCTRequirements( 408 const net::HostPortPair& host_port_pair, 409 bool is_issued_by_known_root, 410 const HashValueVector& public_key_hashes, 411 const X509Certificate* validated_certificate_chain, 412 const X509Certificate* served_certificate_chain, 413 const SignedCertificateTimestampAndStatusList& 414 signed_certificate_timestamps, 415 const ExpectCTReportStatus report_status, 416 ct::CTPolicyCompliance policy_compliance, 417 const NetworkIsolationKey& network_isolation_key); 418 419 // Assign a |Delegate| for persisting the transport security state. If 420 // |NULL|, state will not be persisted. The caller retains 421 // ownership of |delegate|. 422 // Note: This is only used for serializing/deserializing the 423 // TransportSecurityState. 424 void SetDelegate(Delegate* delegate); 425 426 void SetReportSender(ReportSenderInterface* report_sender); 427 428 void SetExpectCTReporter(ExpectCTReporter* expect_ct_reporter); 429 430 // Assigns a delegate responsible for determining whether or not a 431 // connection to a given host should require Certificate Transparency 432 // information that complies with the CT policy provided by a 433 // CTPolicyEnforcer. 434 // If nullptr, no delegate will be consulted. 435 // The caller retains ownership of the |delegate|, and must persist for 436 // the lifetime of this object or until called with nullptr, whichever 437 // occurs first. 438 void SetRequireCTDelegate(RequireCTDelegate* delegate); 439 440 // Clears all dynamic data (e.g. HSTS and HPKP data). 441 // 442 // Does NOT persist changes using the Delegate, as this function is only 443 // used to clear any dynamic data prior to re-loading it from a file. 444 // Note: This is only used for serializing/deserializing the 445 // TransportSecurityState. 446 void ClearDynamicData(); 447 448 // Inserts |state| into |enabled_sts_hosts_| under the key |hashed_host|. 449 // |hashed_host| is already in the internal representation. 450 // Note: This is only used for serializing/deserializing the 451 // TransportSecurityState. 452 void AddOrUpdateEnabledSTSHosts(const std::string& hashed_host, 453 const STSState& state); 454 455 // Inserts |state| into |enabled_expect_ct_hosts_| under the key 456 // |hashed_host|. |hashed_host| is already in the internal representation. 457 // Note: This is only used for serializing/deserializing the 458 // TransportSecurityState. 459 void AddOrUpdateEnabledExpectCTHosts( 460 const std::string& hashed_host, 461 const NetworkIsolationKey& network_isolation_key, 462 const ExpectCTState& state); 463 464 // Deletes all dynamic data (e.g. HSTS or HPKP data) created between a time 465 // period [|start_time|, |end_time|). 466 // 467 // If any entries are deleted, the new state will be persisted through 468 // the Delegate (if any). Calls |callback| when data is persisted to disk. 469 void DeleteAllDynamicDataBetween(base::Time start_time, 470 base::Time end_time, 471 base::OnceClosure callback); 472 473 // Deletes any dynamic data stored for |host| (e.g. HSTS or HPKP data). 474 // If |host| doesn't have an exact entry then no action is taken. Does 475 // not delete static (i.e. preloaded) data. Returns true iff an entry 476 // was deleted. 477 // 478 // If an entry is deleted, the new state will be persisted through 479 // the Delegate (if any). 480 bool DeleteDynamicDataForHost(const std::string& host); 481 482 // Returns true and updates |*result| if |host| has dynamic or static 483 // HSTS/HPKP (respectively) state. If multiple entries match |host|, dynamic 484 // state is preferred over static state and other than that the most specific 485 // match determines the return value (both is in deviation of RFC6797, cf. 486 // https://crbug.com/821811). 487 // 488 // Note that these methods are not const because they opportunistically remove 489 // entries that have expired. 490 bool GetSTSState(const std::string& host, STSState* result); 491 bool GetPKPState(const std::string& host, PKPState* result); 492 493 // Returns true and updates |*sts_result| and/or |*pkp_result| if there is 494 // static (built-in) state for |host|. If multiple entries match |host|, 495 // the most specific match determines the return value. 496 bool GetStaticDomainState(const std::string& host, 497 STSState* sts_result, 498 PKPState* pkp_result) const; 499 500 // Returns true and updates |*result| iff |host| has dynamic 501 // HSTS/HPKP/Expect-CT (respectively) state. If multiple entries match |host|, 502 // the most specific match determines the return value. 503 // 504 // Note that these methods are not const because they opportunistically remove 505 // entries that have expired. 506 bool GetDynamicSTSState(const std::string& host, STSState* result); 507 bool GetDynamicPKPState(const std::string& host, PKPState* result); 508 bool GetDynamicExpectCTState(const std::string& host, 509 const NetworkIsolationKey& network_isolation_key, 510 ExpectCTState* result); 511 512 // Processes an HSTS header value from the host, adding entries to 513 // dynamic state if necessary. 514 bool AddHSTSHeader(const std::string& host, const std::string& value); 515 516 // Adds explicitly-specified data as if it was processed from an 517 // HSTS header (used for net-internals and unit tests). 518 void AddHSTS(const std::string& host, 519 const base::Time& expiry, 520 bool include_subdomains); 521 522 // Adds explicitly-specified data as if it was processed from an HPKP header. 523 // Note: dynamic PKP data is not persisted. 524 void AddHPKP(const std::string& host, 525 const base::Time& expiry, 526 bool include_subdomains, 527 const HashValueVector& hashes, 528 const GURL& report_uri); 529 530 // Adds explicitly-specified data as if it was processed from an Expect-CT 531 // header. 532 // Note: This method will persist the Expect-CT data if a Delegate is present. 533 // Make sure that the delegate is nullptr if the persistence is not 534 // desired. See |SetDelegate| method for more details. 535 void AddExpectCT(const std::string& host, 536 const base::Time& expiry, 537 bool enforce, 538 const GURL& report_uri, 539 const NetworkIsolationKey& network_isolation_key); 540 541 // Enables or disables public key pinning bypass for local trust anchors. 542 // Disabling the bypass for local trust anchors is highly discouraged. 543 // This method is used by Cronet only and *** MUST NOT *** be used by any 544 // other consumer. For more information see "How does key pinning interact 545 // with local proxies and filters?" at 546 // https://www.chromium.org/Home/chromium-security/security-faq 547 void SetEnablePublicKeyPinningBypassForLocalTrustAnchors(bool value); 548 549 // Parses |value| as a Expect CT header value. If valid and served on a 550 // CT-compliant connection, adds an entry to the dynamic state. If valid but 551 // not served on a CT-compliant connection, a report is sent to alert the site 552 // owner of the misconfiguration (provided that a reporter has been set via 553 // SetExpectCTReporter). 554 // 555 // The header can also have the value "preload", indicating that the site 556 // wants to opt-in to the static report-only version of Expect-CT. If the 557 // given host is present on the preload list and the build is timely and the 558 // connection is not CT-compliant, then a report will be sent. 559 void ProcessExpectCTHeader(const std::string& value, 560 const HostPortPair& host_port_pair, 561 const SSLInfo& ssl_info, 562 const NetworkIsolationKey& network_isolation_key); 563 AssertCalledOnValidThread()564 void AssertCalledOnValidThread() const { 565 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); 566 } 567 568 // For unit tests only. Forces CheckCTRequirements() to unconditionally 569 // check compliance. 570 static void SetRequireCTForTesting(bool required); 571 572 // For unit tests only. Clears the caches that deduplicate sent PKP and 573 // Expect-CT reports. 574 void ClearReportCachesForTesting(); 575 576 // For unit tests only. EnableStaticPinsForTesting()577 void EnableStaticPinsForTesting() { enable_static_pins_ = true; } has_dynamic_pkp_state()578 bool has_dynamic_pkp_state() const { return !enabled_pkp_hosts_.empty(); } 579 580 // The number of cached ExpectCTState entries. 581 size_t num_expect_ct_entries() const; 582 583 private: 584 friend class TransportSecurityStateTest; 585 friend class TransportSecurityStateStaticFuzzer; 586 FRIEND_TEST_ALL_PREFIXES(HttpSecurityHeadersTest, NoClobberPins); 587 FRIEND_TEST_ALL_PREFIXES(URLRequestTestHTTP, PreloadExpectCTHeader); 588 589 typedef std::map<std::string, STSState> STSStateMap; 590 typedef std::map<std::string, PKPState> PKPStateMap; 591 typedef std::map<ExpectCTStateIndex, ExpectCTState> ExpectCTStateMap; 592 typedef ExpiringCache<std::string, 593 bool, 594 base::TimeTicks, 595 std::less<base::TimeTicks>> 596 ReportCache; 597 598 // IsBuildTimely returns true if the current build is new enough ensure that 599 // built in security information (i.e. HSTS preloading and pinning 600 // information) is timely. 601 static bool IsBuildTimely(); 602 603 // Helper method for actually checking pins. 604 PKPStatus CheckPublicKeyPinsImpl( 605 const HostPortPair& host_port_pair, 606 bool is_issued_by_known_root, 607 const HashValueVector& hashes, 608 const X509Certificate* served_certificate_chain, 609 const X509Certificate* validated_certificate_chain, 610 const PublicKeyPinReportStatus report_status, 611 const NetworkIsolationKey& network_isolation_key, 612 std::string* failure_log); 613 614 // If a Delegate is present, notify it that the internal state has 615 // changed. 616 void DirtyNotify(); 617 618 // Adds HSTS, HPKP, and Expect-CT state for |host|. The new state supercedes 619 // any previous state for the |host|, including static entries. 620 // 621 // The new state for |host| is persisted using the Delegate (if any). 622 void AddHSTSInternal(const std::string& host, 623 STSState::UpgradeMode upgrade_mode, 624 const base::Time& expiry, 625 bool include_subdomains); 626 void AddHPKPInternal(const std::string& host, 627 const base::Time& last_observed, 628 const base::Time& expiry, 629 bool include_subdomains, 630 const HashValueVector& hashes, 631 const GURL& report_uri); 632 void AddExpectCTInternal(const std::string& host, 633 const base::Time& last_observed, 634 const base::Time& expiry, 635 bool enforce, 636 const GURL& report_uri, 637 const NetworkIsolationKey& network_isolation_key); 638 639 // Returns true if a request to |host_port_pair| with the given 640 // SubjectPublicKeyInfo |hashes| satisfies the pins in |pkp_state|, 641 // and false otherwise. If a violation is found and reporting is 642 // configured (i.e. there is a report URI in |pkp_state| and 643 // |report_status| says to), this method sends an HPKP violation 644 // report containing |served_certificate_chain| and 645 // |validated_certificate_chain|. 646 PKPStatus CheckPinsAndMaybeSendReport( 647 const HostPortPair& host_port_pair, 648 bool is_issued_by_known_root, 649 const TransportSecurityState::PKPState& pkp_state, 650 const HashValueVector& hashes, 651 const X509Certificate* served_certificate_chain, 652 const X509Certificate* validated_certificate_chain, 653 const TransportSecurityState::PublicKeyPinReportStatus report_status, 654 const net::NetworkIsolationKey& network_isolation_key, 655 std::string* failure_log); 656 657 // Returns true and updates |*expect_ct_result| iff there is a static 658 // (built-in) state for |host| with expect_ct=true. 659 bool GetStaticExpectCTState(const std::string& host, 660 ExpectCTState* expect_ct_result) const; 661 662 void MaybeNotifyExpectCTFailed( 663 const HostPortPair& host_port_pair, 664 const GURL& report_uri, 665 base::Time expiration, 666 const X509Certificate* validated_certificate_chain, 667 const X509Certificate* served_certificate_chain, 668 const SignedCertificateTimestampAndStatusList& 669 signed_certificate_timestamps, 670 const NetworkIsolationKey& network_isolation_key); 671 672 // Convenience method to create ExpectCTStateIndex, taking into account 673 // |key_expect_ct_by_nik_|. 674 ExpectCTStateIndex CreateExpectCTStateIndex( 675 const std::string& hashed_host, 676 const NetworkIsolationKey& network_isolation_key); 677 678 // Checks if Expect-CT entries should be pruned, based on number of them and 679 // when entries were last pruned, and then performs pruning if necessary. 680 void MaybePruneExpectCTState(); 681 682 // Sort ExpectCTState based on retention priority, with earlier entries to be 683 // removed first. Transient entries put in the front, then report-only 684 // entries, then entries are sorted by age, oldest first. 685 static bool ExpectCTPruningSorter(const ExpectCTStateMap::iterator& it1, 686 const ExpectCTStateMap::iterator& it2); 687 688 // The sets of hosts that have enabled TransportSecurity. |domain| will always 689 // be empty for a STSState, PKPState, or ExpectCTState in these maps; the 690 // domain comes from the map keys instead. In addition, |upgrade_mode| in the 691 // STSState is never MODE_DEFAULT and |HasPublicKeyPins| in the PKPState 692 // always returns true. 693 STSStateMap enabled_sts_hosts_; 694 PKPStateMap enabled_pkp_hosts_; 695 ExpectCTStateMap enabled_expect_ct_hosts_; 696 697 Delegate* delegate_ = nullptr; 698 699 ReportSenderInterface* report_sender_ = nullptr; 700 701 // True if static pins should be used. 702 bool enable_static_pins_; 703 704 // True if static expect-CT state should be used. 705 bool enable_static_expect_ct_; 706 707 // True if public key pinning bypass is enabled for local trust anchors. 708 bool enable_pkp_bypass_for_local_trust_anchors_; 709 710 ExpectCTReporter* expect_ct_reporter_ = nullptr; 711 712 RequireCTDelegate* require_ct_delegate_ = nullptr; 713 714 // Keeps track of reports that have been sent recently for 715 // rate-limiting. 716 ReportCache sent_hpkp_reports_cache_; 717 ReportCache sent_expect_ct_reports_cache_; 718 719 // Whether Expect-CT data should keyed by a NetworkIsolationKey. When false, 720 // ExpectCTStateIndex is always created with an empty NetworkIsolationKey. 721 // Populated based on features::kPartitionExpectCTStateByNetworkIsolationKey 722 // on construction of the TransportSecurityStateObject to avoid repeatedly 723 // querying the feature. 724 bool key_expect_ct_by_nik_; 725 726 // The earliest possible time for the next pruning of Expect-CT state. 727 base::Time earliest_next_prune_expect_ct_time_; 728 729 std::set<std::string> hsts_host_bypass_list_; 730 731 THREAD_CHECKER(thread_checker_); 732 733 DISALLOW_COPY_AND_ASSIGN(TransportSecurityState); 734 }; 735 736 } // namespace net 737 738 #endif // NET_HTTP_TRANSPORT_SECURITY_STATE_H_ 739