| 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 #include "net/http/transport_security_state.h" | 5 #include "net/http/transport_security_state.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 #include "net/cert/x509_cert_types.h" | 28 #include "net/cert/x509_cert_types.h" |
| 29 #include "net/cert/x509_certificate.h" | 29 #include "net/cert/x509_certificate.h" |
| 30 #include "net/dns/dns_util.h" | 30 #include "net/dns/dns_util.h" |
| 31 #include "net/http/http_security_headers.h" | 31 #include "net/http/http_security_headers.h" |
| 32 #include "net/ssl/ssl_info.h" | 32 #include "net/ssl/ssl_info.h" |
| 33 | 33 |
| 34 namespace net { | 34 namespace net { |
| 35 | 35 |
| 36 namespace { | 36 namespace { |
| 37 | 37 |
| 38 #include "net/http/transport_security_state_ct_policies.inc" |
| 38 #include "net/http/transport_security_state_static.h" | 39 #include "net/http/transport_security_state_static.h" |
| 39 | 40 |
| 40 const size_t kMaxHPKPReportCacheEntries = 50; | 41 const size_t kMaxHPKPReportCacheEntries = 50; |
| 41 const int kTimeToRememberHPKPReportsMins = 60; | 42 const int kTimeToRememberHPKPReportsMins = 60; |
| 42 const size_t kReportCacheKeyLength = 16; | 43 const size_t kReportCacheKeyLength = 16; |
| 43 | 44 |
| 44 // Override for ShouldRequireCT() for unit tests. Possible values: | 45 // Override for ShouldRequireCT() for unit tests. Possible values: |
| 45 // -1: Unless a delegate says otherwise, do not require CT. | 46 // -1: Unless a delegate says otherwise, do not require CT. |
| 46 // 0: Use the default implementation (e.g. production) | 47 // 0: Use the default implementation (e.g. production) |
| 47 // 1: Unless a delegate says otherwise, require CT. | 48 // 1: Unless a delegate says otherwise, require CT. |
| 48 int g_ct_required_for_testing = 0; | 49 int g_ct_required_for_testing = 0; |
| 49 | 50 |
| 51 // LessThan comparator for use with std::binary_search() in determining |
| 52 // whether a SHA-256 HashValue appears within a sorted array of |
| 53 // SHA256HashValues. |
| 54 struct SHA256ToHashValueComparator { |
| 55 bool operator()(const SHA256HashValue& lhs, const HashValue& rhs) const { |
| 56 DCHECK(rhs.tag == HASH_VALUE_SHA256); |
| 57 return memcmp(lhs.data, rhs.data(), rhs.size()) < 0; |
| 58 } |
| 59 |
| 60 bool operator()(const HashValue& lhs, const SHA256HashValue& rhs) const { |
| 61 DCHECK(lhs.tag == HASH_VALUE_SHA256); |
| 62 return memcmp(lhs.data(), rhs.data, lhs.size()) < 0; |
| 63 } |
| 64 }; |
| 65 |
| 50 void RecordUMAForHPKPReportFailure(const GURL& report_uri, int net_error) { | 66 void RecordUMAForHPKPReportFailure(const GURL& report_uri, int net_error) { |
| 51 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.PublicKeyPinReportSendingFailure", | 67 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.PublicKeyPinReportSendingFailure", |
| 52 net_error); | 68 net_error); |
| 53 } | 69 } |
| 54 | 70 |
| 55 std::string TimeToISO8601(const base::Time& t) { | 71 std::string TimeToISO8601(const base::Time& t) { |
| 56 base::Time::Exploded exploded; | 72 base::Time::Exploded exploded; |
| 57 t.UTCExplode(&exploded); | 73 t.UTCExplode(&exploded); |
| 58 return base::StringPrintf( | 74 return base::StringPrintf( |
| 59 "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", exploded.year, exploded.month, | 75 "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", exploded.year, exploded.month, |
| (...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 715 CTRequirementLevel ct_required = CTRequirementLevel::DEFAULT; | 731 CTRequirementLevel ct_required = CTRequirementLevel::DEFAULT; |
| 716 if (require_ct_delegate_) | 732 if (require_ct_delegate_) |
| 717 ct_required = require_ct_delegate_->IsCTRequiredForHost(hostname); | 733 ct_required = require_ct_delegate_->IsCTRequiredForHost(hostname); |
| 718 if (ct_required != CTRequirementLevel::DEFAULT) | 734 if (ct_required != CTRequirementLevel::DEFAULT) |
| 719 return ct_required == CTRequirementLevel::REQUIRED; | 735 return ct_required == CTRequirementLevel::REQUIRED; |
| 720 | 736 |
| 721 // Allow unittests to override the default result. | 737 // Allow unittests to override the default result. |
| 722 if (g_ct_required_for_testing) | 738 if (g_ct_required_for_testing) |
| 723 return g_ct_required_for_testing == 1; | 739 return g_ct_required_for_testing == 1; |
| 724 | 740 |
| 725 return false; | 741 bool default_response = false; |
| 742 const base::Time epoch = base::Time::UnixEpoch(); |
| 743 for (const auto& restricted_ca : kCTRequiredPolicies) { |
| 744 if (epoch + restricted_ca.effective_date > |
| 745 validated_certificate_chain->valid_stat()) { |
| 746 // The candidate cert is not be subject to the CT policy, because it |
| 747 // was issued before the effective CT date. |
| 748 continue; |
| 749 } |
| 750 |
| 751 for (const auto& hash : public_key_hashes) { |
| 752 if (hash.tag != HASH_VALUE_SHA256) |
| 753 continue; |
| 754 |
| 755 // Determine if |hash| is in the set of roots of |restricted_ca|. |
| 756 if (!std::binary_search(restricted_ca.roots, |
| 757 restricted_ca.roots + restricted_ca.roots_length, |
| 758 hash, SHA256ToHashValueComparator())) { |
| 759 continue; |
| 760 } |
| 761 |
| 762 // Found a match, indicating this certificate is potentially |
| 763 // restricted. Determine if any of the hashes are on the exclusion |
| 764 // list as exempt from the CT requirement. |
| 765 for (const auto& sub_ca_hash : public_key_hashes) { |
| 766 if (sub_ca_hash.tag != HASH_VALUE_SHA256) |
| 767 continue; |
| 768 if (std::binary_search( |
| 769 restricted_ca.exceptions, |
| 770 restricted_ca.exceptions + restricted_ca.exceptions_length, |
| 771 sub_ca_hash, SHA256ToHashValueComparator())) { |
| 772 // Found an excluded sub-CA; CT is not required. |
| 773 return default_response; |
| 774 } |
| 775 } |
| 776 |
| 777 // No exception found. This certificate must conform to the CT policy. |
| 778 return true; |
| 779 } |
| 780 } |
| 781 |
| 782 return default_response; |
| 726 } | 783 } |
| 727 | 784 |
| 728 void TransportSecurityState::SetDelegate( | 785 void TransportSecurityState::SetDelegate( |
| 729 TransportSecurityState::Delegate* delegate) { | 786 TransportSecurityState::Delegate* delegate) { |
| 730 DCHECK(CalledOnValidThread()); | 787 DCHECK(CalledOnValidThread()); |
| 731 delegate_ = delegate; | 788 delegate_ = delegate; |
| 732 } | 789 } |
| 733 | 790 |
| 734 void TransportSecurityState::SetReportSender( | 791 void TransportSecurityState::SetReportSender( |
| 735 TransportSecurityState::ReportSenderInterface* report_sender) { | 792 TransportSecurityState::ReportSenderInterface* report_sender) { |
| (...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1436 TransportSecurityState::PKPStateIterator::PKPStateIterator( | 1493 TransportSecurityState::PKPStateIterator::PKPStateIterator( |
| 1437 const TransportSecurityState& state) | 1494 const TransportSecurityState& state) |
| 1438 : iterator_(state.enabled_pkp_hosts_.begin()), | 1495 : iterator_(state.enabled_pkp_hosts_.begin()), |
| 1439 end_(state.enabled_pkp_hosts_.end()) { | 1496 end_(state.enabled_pkp_hosts_.end()) { |
| 1440 } | 1497 } |
| 1441 | 1498 |
| 1442 TransportSecurityState::PKPStateIterator::~PKPStateIterator() { | 1499 TransportSecurityState::PKPStateIterator::~PKPStateIterator() { |
| 1443 } | 1500 } |
| 1444 | 1501 |
| 1445 } // namespace | 1502 } // namespace |
| OLD | NEW |