OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef NET_HTTP_TRANSPORT_SECURITY_STATE_H_ | 5 #ifndef NET_HTTP_TRANSPORT_SECURITY_STATE_H_ |
6 #define NET_HTTP_TRANSPORT_SECURITY_STATE_H_ | 6 #define NET_HTTP_TRANSPORT_SECURITY_STATE_H_ |
7 | 7 |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <map> | 10 #include <map> |
11 #include <string> | 11 #include <string> |
12 | 12 |
13 #include "base/callback.h" | 13 #include "base/callback.h" |
| 14 #include "base/feature_list.h" |
14 #include "base/gtest_prod_util.h" | 15 #include "base/gtest_prod_util.h" |
15 #include "base/macros.h" | 16 #include "base/macros.h" |
16 #include "base/strings/string_piece.h" | 17 #include "base/strings/string_piece.h" |
17 #include "base/threading/non_thread_safe.h" | 18 #include "base/threading/non_thread_safe.h" |
18 #include "base/time/time.h" | 19 #include "base/time/time.h" |
19 #include "net/base/expiring_cache.h" | 20 #include "net/base/expiring_cache.h" |
20 #include "net/base/hash_value.h" | 21 #include "net/base/hash_value.h" |
21 #include "net/base/net_export.h" | 22 #include "net/base/net_export.h" |
22 #include "net/http/transport_security_state_source.h" | 23 #include "net/http/transport_security_state_source.h" |
23 #include "url/gurl.h" | 24 #include "url/gurl.h" |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 class NET_EXPORT ExpectCTState { | 229 class NET_EXPORT ExpectCTState { |
229 public: | 230 public: |
230 ExpectCTState(); | 231 ExpectCTState(); |
231 ~ExpectCTState(); | 232 ~ExpectCTState(); |
232 | 233 |
233 // The domain which matched during a search for this DomainState entry. | 234 // The domain which matched during a search for this DomainState entry. |
234 std::string domain; | 235 std::string domain; |
235 // The URI to which reports should be sent if valid CT info is not | 236 // The URI to which reports should be sent if valid CT info is not |
236 // provided. | 237 // provided. |
237 GURL report_uri; | 238 GURL report_uri; |
| 239 // True if connections should be closed if they do not comply with the CT |
| 240 // policy. If false, noncompliant connections will be allowed but reports |
| 241 // will be sent about the violation. |
| 242 bool enforce; |
| 243 // The absolute time (UTC) when the Expect-CT state was last observed. |
| 244 base::Time last_observed; |
| 245 // The absolute time (UTC) when the Expect-CT state expires. |
| 246 base::Time expiry; |
| 247 }; |
| 248 |
| 249 class NET_EXPORT ExpectCTStateIterator { |
| 250 public: |
| 251 explicit ExpectCTStateIterator(const TransportSecurityState& state); |
| 252 ~ExpectCTStateIterator(); |
| 253 |
| 254 bool HasNext() const { return iterator_ != end_; } |
| 255 void Advance() { ++iterator_; } |
| 256 const std::string& hostname() const { return iterator_->first; } |
| 257 const ExpectCTState& domain_state() const { return iterator_->second; } |
| 258 |
| 259 private: |
| 260 std::map<std::string, ExpectCTState>::const_iterator iterator_; |
| 261 std::map<std::string, ExpectCTState>::const_iterator end_; |
238 }; | 262 }; |
239 | 263 |
240 // An ExpectStapleState describes a site that expects valid OCSP information | 264 // An ExpectStapleState describes a site that expects valid OCSP information |
241 // to be stapled to its certificate on every connection. | 265 // to be stapled to its certificate on every connection. |
242 class NET_EXPORT ExpectStapleState { | 266 class NET_EXPORT ExpectStapleState { |
243 public: | 267 public: |
244 ExpectStapleState(); | 268 ExpectStapleState(); |
245 ~ExpectStapleState(); | 269 ~ExpectStapleState(); |
246 | 270 |
247 // The domain which matched during a search for this Expect-Staple entry | 271 // The domain which matched during a search for this Expect-Staple entry |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 const net::SSLInfo& ssl_info) = 0; | 310 const net::SSLInfo& ssl_info) = 0; |
287 | 311 |
288 protected: | 312 protected: |
289 virtual ~ExpectCTReporter() {} | 313 virtual ~ExpectCTReporter() {} |
290 }; | 314 }; |
291 | 315 |
292 // Indicates whether or not a public key pin check should send a | 316 // Indicates whether or not a public key pin check should send a |
293 // report if a violation is detected. | 317 // report if a violation is detected. |
294 enum PublicKeyPinReportStatus { ENABLE_PIN_REPORTS, DISABLE_PIN_REPORTS }; | 318 enum PublicKeyPinReportStatus { ENABLE_PIN_REPORTS, DISABLE_PIN_REPORTS }; |
295 | 319 |
| 320 // Feature that controls whether Expect-CT HTTP headers are parsed, processed, |
| 321 // and stored. |
| 322 static const base::Feature kDynamicExpectCTFeature; |
| 323 |
296 TransportSecurityState(); | 324 TransportSecurityState(); |
297 ~TransportSecurityState(); | 325 ~TransportSecurityState(); |
298 | 326 |
299 // These functions search for static and dynamic STS and PKP states, and | 327 // These functions search for static and dynamic STS and PKP states, and |
300 // invoke the functions of the same name on them. These functions are the | 328 // invoke the functions of the same name on them. These functions are the |
301 // primary public interface; direct access to STS and PKP states is best | 329 // primary public interface; direct access to STS and PKP states is best |
302 // left to tests. The caller needs to handle the optional pinning override | 330 // left to tests. The caller needs to handle the optional pinning override |
303 // when is_issued_by_known_root is false. | 331 // when is_issued_by_known_root is false. |
304 bool ShouldSSLErrorsBeFatal(const std::string& host); | 332 bool ShouldSSLErrorsBeFatal(const std::string& host); |
305 bool ShouldUpgradeToSSL(const std::string& host); | 333 bool ShouldUpgradeToSSL(const std::string& host); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 void AddOrUpdateEnabledSTSHosts(const std::string& hashed_host, | 403 void AddOrUpdateEnabledSTSHosts(const std::string& hashed_host, |
376 const STSState& state); | 404 const STSState& state); |
377 | 405 |
378 // Inserts |state| into |enabled_pkp_hosts_| under the key |hashed_host|. | 406 // Inserts |state| into |enabled_pkp_hosts_| under the key |hashed_host|. |
379 // |hashed_host| is already in the internal representation. | 407 // |hashed_host| is already in the internal representation. |
380 // Note: This is only used for serializing/deserializing the | 408 // Note: This is only used for serializing/deserializing the |
381 // TransportSecurityState. | 409 // TransportSecurityState. |
382 void AddOrUpdateEnabledPKPHosts(const std::string& hashed_host, | 410 void AddOrUpdateEnabledPKPHosts(const std::string& hashed_host, |
383 const PKPState& state); | 411 const PKPState& state); |
384 | 412 |
| 413 // Inserts |state| into |enabled_expect_ct_hosts_| under the key |
| 414 // |hashed_host|. |hashed_host| is already in the internal representation. |
| 415 // Note: This is only used for serializing/deserializing the |
| 416 // TransportSecurityState. |
| 417 void AddOrUpdateEnabledExpectCTHosts(const std::string& hashed_host, |
| 418 const ExpectCTState& state); |
| 419 |
385 // Deletes all dynamic data (e.g. HSTS or HPKP data) created since a given | 420 // Deletes all dynamic data (e.g. HSTS or HPKP data) created since a given |
386 // time. | 421 // time. |
387 // | 422 // |
388 // If any entries are deleted, the new state will be persisted through | 423 // If any entries are deleted, the new state will be persisted through |
389 // the Delegate (if any). | 424 // the Delegate (if any). |
390 void DeleteAllDynamicDataSince(const base::Time& time); | 425 void DeleteAllDynamicDataSince(const base::Time& time); |
391 | 426 |
392 // Deletes any dynamic data stored for |host| (e.g. HSTS or HPKP data). | 427 // Deletes any dynamic data stored for |host| (e.g. HSTS or HPKP data). |
393 // If |host| doesn't have an exact entry then no action is taken. Does | 428 // If |host| doesn't have an exact entry then no action is taken. Does |
394 // not delete static (i.e. preloaded) data. Returns true iff an entry | 429 // not delete static (i.e. preloaded) data. Returns true iff an entry |
395 // was deleted. | 430 // was deleted. |
396 // | 431 // |
397 // If an entry is deleted, the new state will be persisted through | 432 // If an entry is deleted, the new state will be persisted through |
398 // the Delegate (if any). | 433 // the Delegate (if any). |
399 bool DeleteDynamicDataForHost(const std::string& host); | 434 bool DeleteDynamicDataForHost(const std::string& host); |
400 | 435 |
401 // Returns true and updates |*sts_result| and |*pkp_result| iff there is a | 436 // Returns true and updates |*sts_result| and |*pkp_result| iff there is a |
402 // static (built-in) state for |host|. If multiple entries match |host|, | 437 // static (built-in) state for |host|. If multiple entries match |host|, |
403 // the most specific match determines the return value. | 438 // the most specific match determines the return value. |
404 bool GetStaticDomainState(const std::string& host, | 439 bool GetStaticDomainState(const std::string& host, |
405 STSState* sts_result, | 440 STSState* sts_result, |
406 PKPState* pkp_result) const; | 441 PKPState* pkp_result) const; |
407 | 442 |
408 // Returns true iff there is static (built-in) state for |host| that | 443 // Returns true iff there is static (built-in) state for |host| that |
409 // references the Google pins. | 444 // references the Google pins. |
410 // TODO(rch): Remove this temporary gross layering violation once QUIC 32 is | 445 // TODO(rch): Remove this temporary gross layering violation once QUIC 32 is |
411 // deployed. | 446 // deployed. |
412 bool IsGooglePinnedHost(const std::string& host) const; | 447 bool IsGooglePinnedHost(const std::string& host) const; |
413 | 448 |
414 // Returns true and updates |*result| iff |host| has HSTS (respectively, HPKP) | 449 // Returns true and updates |*result| iff |host| has HSTS/HPKP/Expect-CT |
415 // state. If multiple HSTS (respectively, HPKP) entries match |host|, the | 450 // (respectively) state. If multiple entries match |host|, the most specific |
416 // most specific match determines the HSTS (respectively, HPKP) return value. | 451 // match determines the return value. |
417 // | 452 // |
418 // Note that these methods are not const because they opportunistically remove | 453 // Note that these methods are not const because they opportunistically remove |
419 // entries that have expired. | 454 // entries that have expired. |
420 bool GetDynamicSTSState(const std::string& host, STSState* result); | 455 bool GetDynamicSTSState(const std::string& host, STSState* result); |
421 bool GetDynamicPKPState(const std::string& host, PKPState* result); | 456 bool GetDynamicPKPState(const std::string& host, PKPState* result); |
| 457 bool GetDynamicExpectCTState(const std::string& host, ExpectCTState* result); |
422 | 458 |
423 // Processes an HSTS header value from the host, adding entries to | 459 // Processes an HSTS header value from the host, adding entries to |
424 // dynamic state if necessary. | 460 // dynamic state if necessary. |
425 bool AddHSTSHeader(const std::string& host, const std::string& value); | 461 bool AddHSTSHeader(const std::string& host, const std::string& value); |
426 | 462 |
427 // Processes an HPKP header value from the host, adding entries to | 463 // Processes an HPKP header value from the host, adding entries to |
428 // dynamic state if necessary. ssl_info is used to check that | 464 // dynamic state if necessary. ssl_info is used to check that |
429 // the specified pins overlap with the certificate chain. | 465 // the specified pins overlap with the certificate chain. |
430 bool AddHPKPHeader(const std::string& host, const std::string& value, | 466 bool AddHPKPHeader(const std::string& host, const std::string& value, |
431 const SSLInfo& ssl_info); | 467 const SSLInfo& ssl_info); |
432 | 468 |
433 // Adds explicitly-specified data as if it was processed from an | 469 // Adds explicitly-specified data as if it was processed from an |
434 // HSTS header (used for net-internals and unit tests). | 470 // HSTS header (used for net-internals and unit tests). |
435 void AddHSTS(const std::string& host, | 471 void AddHSTS(const std::string& host, |
436 const base::Time& expiry, | 472 const base::Time& expiry, |
437 bool include_subdomains); | 473 bool include_subdomains); |
438 | 474 |
439 // Adds explicitly-specified data as if it was processed from an HPKP header. | 475 // Adds explicitly-specified data as if it was processed from an HPKP header. |
440 // Note: This method will persist the HPKP if a Delegate is present. Make sure | 476 // Note: This method will persist the HPKP if a Delegate is present. Make sure |
441 // that the delegate is nullptr if the persistence is not desired. | 477 // that the delegate is nullptr if the persistence is not desired. |
442 // See |SetDelegate| method for more details. | 478 // See |SetDelegate| method for more details. |
443 void AddHPKP(const std::string& host, | 479 void AddHPKP(const std::string& host, |
444 const base::Time& expiry, | 480 const base::Time& expiry, |
445 bool include_subdomains, | 481 bool include_subdomains, |
446 const HashValueVector& hashes, | 482 const HashValueVector& hashes, |
447 const GURL& report_uri); | 483 const GURL& report_uri); |
448 | 484 |
| 485 // Adds explicitly-specified data as if it was processed from an Expect-CT |
| 486 // header. |
| 487 // Note: This method will persist the Expect-CT data if a Delegate is present. |
| 488 // Make sure that the delegate is nullptr if the persistence is not |
| 489 // desired. See |SetDelegate| method for more details. |
| 490 void AddExpectCT(const std::string& host, |
| 491 const base::Time& expiry, |
| 492 bool enforce, |
| 493 const GURL& report_uri); |
| 494 |
449 // Enables or disables public key pinning bypass for local trust anchors. | 495 // Enables or disables public key pinning bypass for local trust anchors. |
450 // Disabling the bypass for local trust anchors is highly discouraged. | 496 // Disabling the bypass for local trust anchors is highly discouraged. |
451 // This method is used by Cronet only and *** MUST NOT *** be used by any | 497 // This method is used by Cronet only and *** MUST NOT *** be used by any |
452 // other consumer. For more information see "How does key pinning interact | 498 // other consumer. For more information see "How does key pinning interact |
453 // with local proxies and filters?" at | 499 // with local proxies and filters?" at |
454 // https://www.chromium.org/Home/chromium-security/security-faq | 500 // https://www.chromium.org/Home/chromium-security/security-faq |
455 void SetEnablePublicKeyPinningBypassForLocalTrustAnchors(bool value); | 501 void SetEnablePublicKeyPinningBypassForLocalTrustAnchors(bool value); |
456 | 502 |
457 // Parses |value| as a Public-Key-Pins-Report-Only header value and | 503 // Parses |value| as a Public-Key-Pins-Report-Only header value and |
458 // sends a HPKP report for |host_port_pair| if |ssl_info| violates the | 504 // sends a HPKP report for |host_port_pair| if |ssl_info| violates the |
(...skipping 23 matching lines...) Expand all Loading... |
482 private: | 528 private: |
483 friend class TransportSecurityStateTest; | 529 friend class TransportSecurityStateTest; |
484 friend class TransportSecurityStateStaticFuzzer; | 530 friend class TransportSecurityStateStaticFuzzer; |
485 FRIEND_TEST_ALL_PREFIXES(HttpSecurityHeadersTest, UpdateDynamicPKPOnly); | 531 FRIEND_TEST_ALL_PREFIXES(HttpSecurityHeadersTest, UpdateDynamicPKPOnly); |
486 FRIEND_TEST_ALL_PREFIXES(HttpSecurityHeadersTest, UpdateDynamicPKPMaxAge0); | 532 FRIEND_TEST_ALL_PREFIXES(HttpSecurityHeadersTest, UpdateDynamicPKPMaxAge0); |
487 FRIEND_TEST_ALL_PREFIXES(HttpSecurityHeadersTest, NoClobberPins); | 533 FRIEND_TEST_ALL_PREFIXES(HttpSecurityHeadersTest, NoClobberPins); |
488 FRIEND_TEST_ALL_PREFIXES(URLRequestTestHTTP, ExpectCTHeader); | 534 FRIEND_TEST_ALL_PREFIXES(URLRequestTestHTTP, ExpectCTHeader); |
489 | 535 |
490 typedef std::map<std::string, STSState> STSStateMap; | 536 typedef std::map<std::string, STSState> STSStateMap; |
491 typedef std::map<std::string, PKPState> PKPStateMap; | 537 typedef std::map<std::string, PKPState> PKPStateMap; |
| 538 typedef std::map<std::string, ExpectCTState> ExpectCTStateMap; |
492 | 539 |
493 // Send an UMA report on pin validation failure, if the host is in a | 540 // Send an UMA report on pin validation failure, if the host is in a |
494 // statically-defined list of domains. | 541 // statically-defined list of domains. |
495 // | 542 // |
496 // TODO(palmer): This doesn't really belong here, and should be moved into | 543 // TODO(palmer): This doesn't really belong here, and should be moved into |
497 // the exactly one call site. This requires unifying |struct HSTSPreload| | 544 // the exactly one call site. This requires unifying |struct HSTSPreload| |
498 // (an implementation detail of this class) with a more generic | 545 // (an implementation detail of this class) with a more generic |
499 // representation of first-class DomainStates, and exposing the preloads | 546 // representation of first-class DomainStates, and exposing the preloads |
500 // to the caller with |GetStaticDomainState|. | 547 // to the caller with |GetStaticDomainState|. |
501 static void ReportUMAOnPinFailure(const std::string& host); | 548 static void ReportUMAOnPinFailure(const std::string& host); |
(...skipping 24 matching lines...) Expand all Loading... |
526 bool include_subdomains); | 573 bool include_subdomains); |
527 | 574 |
528 // Adds HPKP state to |host|. | 575 // Adds HPKP state to |host|. |
529 void AddHPKPInternal(const std::string& host, | 576 void AddHPKPInternal(const std::string& host, |
530 const base::Time& last_observed, | 577 const base::Time& last_observed, |
531 const base::Time& expiry, | 578 const base::Time& expiry, |
532 bool include_subdomains, | 579 bool include_subdomains, |
533 const HashValueVector& hashes, | 580 const HashValueVector& hashes, |
534 const GURL& report_uri); | 581 const GURL& report_uri); |
535 | 582 |
| 583 // Adds Expect-CT state to |host|. |
| 584 void AddExpectCTInternal(const std::string& host, |
| 585 const base::Time& last_observed, |
| 586 const base::Time& expiry, |
| 587 bool enforce, |
| 588 const GURL& report_uri); |
| 589 |
536 // Enable TransportSecurity for |host|. |state| supercedes any previous | 590 // Enable TransportSecurity for |host|. |state| supercedes any previous |
537 // state for the |host|, including static entries. | 591 // state for the |host|, including static entries. |
538 // | 592 // |
539 // The new state for |host| is persisted using the Delegate (if any). | 593 // The new state for |host| is persisted using the Delegate (if any). |
540 void EnableSTSHost(const std::string& host, const STSState& state); | 594 void EnableSTSHost(const std::string& host, const STSState& state); |
541 void EnablePKPHost(const std::string& host, const PKPState& state); | 595 void EnablePKPHost(const std::string& host, const PKPState& state); |
| 596 void EnableExpectCTHost(const std::string& host, const ExpectCTState& state); |
542 | 597 |
543 // Returns true if a request to |host_port_pair| with the given | 598 // Returns true if a request to |host_port_pair| with the given |
544 // SubjectPublicKeyInfo |hashes| satisfies the pins in |pkp_state|, | 599 // SubjectPublicKeyInfo |hashes| satisfies the pins in |pkp_state|, |
545 // and false otherwise. If a violation is found and reporting is | 600 // and false otherwise. If a violation is found and reporting is |
546 // configured (i.e. there is a report URI in |pkp_state| and | 601 // configured (i.e. there is a report URI in |pkp_state| and |
547 // |report_status| says to), this method sends an HPKP violation | 602 // |report_status| says to), this method sends an HPKP violation |
548 // report containing |served_certificate_chain| and | 603 // report containing |served_certificate_chain| and |
549 // |validated_certificate_chain|. | 604 // |validated_certificate_chain|. |
550 PKPStatus CheckPinsAndMaybeSendReport( | 605 PKPStatus CheckPinsAndMaybeSendReport( |
551 const HostPortPair& host_port_pair, | 606 const HostPortPair& host_port_pair, |
(...skipping 12 matching lines...) Expand all Loading... |
564 | 619 |
565 // Returns true and updates |*expect_staple_result| iff there is a static | 620 // Returns true and updates |*expect_staple_result| iff there is a static |
566 // (built-in) state for |host| with expect_staple=true, or if |host| is a | 621 // (built-in) state for |host| with expect_staple=true, or if |host| is a |
567 // subdomain of another domain with expect_staple=true and | 622 // subdomain of another domain with expect_staple=true and |
568 // include_subdomains_for_expect_staple=true. | 623 // include_subdomains_for_expect_staple=true. |
569 bool GetStaticExpectStapleState( | 624 bool GetStaticExpectStapleState( |
570 const std::string& host, | 625 const std::string& host, |
571 ExpectStapleState* expect_staple_result) const; | 626 ExpectStapleState* expect_staple_result) const; |
572 | 627 |
573 // The sets of hosts that have enabled TransportSecurity. |domain| will always | 628 // The sets of hosts that have enabled TransportSecurity. |domain| will always |
574 // be empty for a STSState or PKPState in these maps; the domain | 629 // be empty for a STSState, PKPState, or ExpectCTState in these maps; the |
575 // comes from the map keys instead. In addition, |upgrade_mode| in the | 630 // domain comes from the map keys instead. In addition, |upgrade_mode| in the |
576 // STSState is never MODE_DEFAULT and |HasPublicKeyPins| in the PKPState | 631 // STSState is never MODE_DEFAULT and |HasPublicKeyPins| in the PKPState |
577 // always returns true. | 632 // always returns true. |
578 STSStateMap enabled_sts_hosts_; | 633 STSStateMap enabled_sts_hosts_; |
579 PKPStateMap enabled_pkp_hosts_; | 634 PKPStateMap enabled_pkp_hosts_; |
| 635 ExpectCTStateMap enabled_expect_ct_hosts_; |
580 | 636 |
581 Delegate* delegate_ = nullptr; | 637 Delegate* delegate_ = nullptr; |
582 | 638 |
583 ReportSenderInterface* report_sender_ = nullptr; | 639 ReportSenderInterface* report_sender_ = nullptr; |
584 | 640 |
585 // True if static pins should be used. | 641 // True if static pins should be used. |
586 bool enable_static_pins_; | 642 bool enable_static_pins_; |
587 | 643 |
588 // True if static expect-CT state should be used. | 644 // True if static expect-CT state should be used. |
589 bool enable_static_expect_ct_; | 645 bool enable_static_expect_ct_; |
(...skipping 12 matching lines...) Expand all Loading... |
602 // rate-limiting. | 658 // rate-limiting. |
603 ExpiringCache<std::string, bool, base::TimeTicks, std::less<base::TimeTicks>> | 659 ExpiringCache<std::string, bool, base::TimeTicks, std::less<base::TimeTicks>> |
604 sent_reports_cache_; | 660 sent_reports_cache_; |
605 | 661 |
606 DISALLOW_COPY_AND_ASSIGN(TransportSecurityState); | 662 DISALLOW_COPY_AND_ASSIGN(TransportSecurityState); |
607 }; | 663 }; |
608 | 664 |
609 } // namespace net | 665 } // namespace net |
610 | 666 |
611 #endif // NET_HTTP_TRANSPORT_SECURITY_STATE_H_ | 667 #endif // NET_HTTP_TRANSPORT_SECURITY_STATE_H_ |
OLD | NEW |