Chromium Code Reviews| 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 <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/base64.h" | 10 #include "base/base64.h" |
| 11 #include "base/build_time.h" | 11 #include "base/build_time.h" |
| 12 #include "base/json/json_writer.h" | 12 #include "base/json/json_writer.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
| 15 #include "base/metrics/histogram_macros.h" | 15 #include "base/metrics/histogram_macros.h" |
| 16 #include "base/metrics/sparse_histogram.h" | 16 #include "base/metrics/sparse_histogram.h" |
| 17 #include "base/sha1.h" | 17 #include "base/sha1.h" |
| 18 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
| 19 #include "base/strings/string_util.h" | 19 #include "base/strings/string_util.h" |
| 20 #include "base/strings/stringprintf.h" | 20 #include "base/strings/stringprintf.h" |
| 21 #include "base/strings/utf_string_conversions.h" | 21 #include "base/strings/utf_string_conversions.h" |
| 22 #include "base/values.h" | 22 #include "base/values.h" |
| 23 #include "crypto/sha2.h" | 23 #include "crypto/sha2.h" |
| 24 #include "net/base/host_port_pair.h" | 24 #include "net/base/host_port_pair.h" |
| 25 #include "net/cert/ct_policy_status.h" | |
| 25 #include "net/cert/x509_cert_types.h" | 26 #include "net/cert/x509_cert_types.h" |
| 26 #include "net/cert/x509_certificate.h" | 27 #include "net/cert/x509_certificate.h" |
| 27 #include "net/dns/dns_util.h" | 28 #include "net/dns/dns_util.h" |
| 28 #include "net/http/http_security_headers.h" | 29 #include "net/http/http_security_headers.h" |
| 29 #include "net/ssl/ssl_info.h" | 30 #include "net/ssl/ssl_info.h" |
| 30 #include "url/gurl.h" | 31 #include "url/gurl.h" |
| 31 | 32 |
| 32 namespace net { | 33 namespace net { |
| 33 | 34 |
| 34 namespace { | 35 namespace { |
| (...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 682 DCHECK(CalledOnValidThread()); | 683 DCHECK(CalledOnValidThread()); |
| 683 delegate_ = delegate; | 684 delegate_ = delegate; |
| 684 } | 685 } |
| 685 | 686 |
| 686 void TransportSecurityState::SetReportSender( | 687 void TransportSecurityState::SetReportSender( |
| 687 TransportSecurityState::ReportSender* report_sender) { | 688 TransportSecurityState::ReportSender* report_sender) { |
| 688 DCHECK(CalledOnValidThread()); | 689 DCHECK(CalledOnValidThread()); |
| 689 report_sender_ = report_sender; | 690 report_sender_ = report_sender; |
| 690 } | 691 } |
| 691 | 692 |
| 693 void TransportSecurityState::SetExpectCTReporter( | |
| 694 ExpectCTReporter* expect_ct_reporter) { | |
| 695 DCHECK(CalledOnValidThread()); | |
| 696 expect_ct_reporter_ = expect_ct_reporter; | |
| 697 } | |
| 698 | |
| 692 void TransportSecurityState::AddHSTSInternal( | 699 void TransportSecurityState::AddHSTSInternal( |
| 693 const std::string& host, | 700 const std::string& host, |
| 694 TransportSecurityState::STSState::UpgradeMode upgrade_mode, | 701 TransportSecurityState::STSState::UpgradeMode upgrade_mode, |
| 695 const base::Time& expiry, | 702 const base::Time& expiry, |
| 696 bool include_subdomains) { | 703 bool include_subdomains) { |
| 697 DCHECK(CalledOnValidThread()); | 704 DCHECK(CalledOnValidThread()); |
| 698 | 705 |
| 699 STSState sts_state; | 706 STSState sts_state; |
| 700 sts_state.last_observed = base::Time::Now(); | 707 sts_state.last_observed = base::Time::Now(); |
| 701 sts_state.include_subdomains = include_subdomains; | 708 sts_state.include_subdomains = include_subdomains; |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 813 return false; | 820 return false; |
| 814 sent_reports_cache_.Put( | 821 sent_reports_cache_.Put( |
| 815 report_cache_key, true, base::TimeTicks::Now(), | 822 report_cache_key, true, base::TimeTicks::Now(), |
| 816 base::TimeTicks::Now() + | 823 base::TimeTicks::Now() + |
| 817 base::TimeDelta::FromMinutes(kTimeToRememberHPKPReportsMins)); | 824 base::TimeDelta::FromMinutes(kTimeToRememberHPKPReportsMins)); |
| 818 | 825 |
| 819 report_sender_->Send(pkp_state.report_uri, serialized_report); | 826 report_sender_->Send(pkp_state.report_uri, serialized_report); |
| 820 return false; | 827 return false; |
| 821 } | 828 } |
| 822 | 829 |
| 830 bool TransportSecurityState::GetStaticExpectCTState( | |
| 831 const std::string& host, | |
| 832 ExpectCTState* expect_ct_state) const { | |
| 833 DCHECK(CalledOnValidThread()); | |
| 834 | |
| 835 if (!IsBuildTimely()) | |
| 836 return false; | |
| 837 | |
| 838 PreloadResult result; | |
| 839 if (!DecodeHSTSPreload(host, &result)) | |
| 840 return false; | |
| 841 | |
| 842 if (!enable_static_expect_ct_ || !result.expect_ct) | |
| 843 return false; | |
| 844 | |
| 845 expect_ct_state->domain = host.substr(result.hostname_offset); | |
| 846 expect_ct_state->report_uri = | |
| 847 GURL(kExpectCTReportURIs[result.expect_ct_report_uri_id]); | |
| 848 return true; | |
| 849 } | |
| 850 | |
| 823 bool TransportSecurityState::DeleteDynamicDataForHost(const std::string& host) { | 851 bool TransportSecurityState::DeleteDynamicDataForHost(const std::string& host) { |
| 824 DCHECK(CalledOnValidThread()); | 852 DCHECK(CalledOnValidThread()); |
| 825 | 853 |
| 826 const std::string canonicalized_host = CanonicalizeHost(host); | 854 const std::string canonicalized_host = CanonicalizeHost(host); |
| 827 if (canonicalized_host.empty()) | 855 if (canonicalized_host.empty()) |
| 828 return false; | 856 return false; |
| 829 | 857 |
| 830 const std::string hashed_host = HashHost(canonicalized_host); | 858 const std::string hashed_host = HashHost(canonicalized_host); |
| 831 bool deleted = false; | 859 bool deleted = false; |
| 832 STSStateMap::iterator sts_interator = enabled_sts_hosts_.find(hashed_host); | 860 STSStateMap::iterator sts_interator = enabled_sts_hosts_.find(hashed_host); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 986 if (!ssl_info.is_issued_by_known_root) | 1014 if (!ssl_info.is_issued_by_known_root) |
| 987 return true; | 1015 return true; |
| 988 | 1016 |
| 989 CheckPinsAndMaybeSendReport( | 1017 CheckPinsAndMaybeSendReport( |
| 990 host_port_pair, pkp_state, ssl_info.public_key_hashes, | 1018 host_port_pair, pkp_state, ssl_info.public_key_hashes, |
| 991 ssl_info.unverified_cert.get(), ssl_info.cert.get(), ENABLE_PIN_REPORTS, | 1019 ssl_info.unverified_cert.get(), ssl_info.cert.get(), ENABLE_PIN_REPORTS, |
| 992 &unused_failure_log); | 1020 &unused_failure_log); |
| 993 return true; | 1021 return true; |
| 994 } | 1022 } |
| 995 | 1023 |
| 1024 void TransportSecurityState::ProcessExpectCTHeader( | |
| 1025 const std::string& value, | |
| 1026 const HostPortPair& host_port_pair, | |
| 1027 const SSLInfo& ssl_info) { | |
| 1028 DCHECK(CalledOnValidThread()); | |
| 1029 | |
| 1030 ExpectCTState state; | |
| 1031 if (!expect_ct_reporter_ || value != "preload" || !IsBuildTimely() || | |
|
Eran Messeri
2016/03/04 11:05:37
Nit: very long condition, I suggest breaking it do
estark
2016/03/08 02:36:06
Done.
| |
| 1032 !ssl_info.is_issued_by_known_root || | |
| 1033 !ssl_info.ct_compliance_details_available || | |
| 1034 ssl_info.ct_cert_policy_compliance == | |
| 1035 ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS || | |
| 1036 !GetStaticExpectCTState(host_port_pair.host(), &state)) { | |
| 1037 return; | |
| 1038 } | |
| 1039 | |
| 1040 expect_ct_reporter_->OnExpectCTFailed(host_port_pair, state.report_uri, | |
| 1041 ssl_info); | |
| 1042 } | |
| 1043 | |
| 996 // static | 1044 // static |
| 997 void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) { | 1045 void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) { |
| 998 PreloadResult result; | 1046 PreloadResult result; |
| 999 if (!DecodeHSTSPreload(host, &result) || | 1047 if (!DecodeHSTSPreload(host, &result) || |
| 1000 !result.has_pins) { | 1048 !result.has_pins) { |
| 1001 return; | 1049 return; |
| 1002 } | 1050 } |
| 1003 | 1051 |
| 1004 DCHECK(result.domain_id != DOMAIN_NOT_PINNED); | 1052 DCHECK(result.domain_id != DOMAIN_NOT_PINNED); |
| 1005 | 1053 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1103 | 1151 |
| 1104 if (!result.has_pins) | 1152 if (!result.has_pins) |
| 1105 return false; | 1153 return false; |
| 1106 | 1154 |
| 1107 if (result.pinset_id >= arraysize(kPinsets)) | 1155 if (result.pinset_id >= arraysize(kPinsets)) |
| 1108 return false; | 1156 return false; |
| 1109 | 1157 |
| 1110 return kPinsets[result.pinset_id].accepted_pins == kGoogleAcceptableCerts; | 1158 return kPinsets[result.pinset_id].accepted_pins == kGoogleAcceptableCerts; |
| 1111 } | 1159 } |
| 1112 | 1160 |
| 1113 bool TransportSecurityState::GetStaticExpectCTState( | |
| 1114 const std::string& host, | |
| 1115 ExpectCTState* expect_ct_state) const { | |
| 1116 DCHECK(CalledOnValidThread()); | |
| 1117 | |
| 1118 if (!IsBuildTimely()) | |
| 1119 return false; | |
| 1120 | |
| 1121 PreloadResult result; | |
| 1122 if (!DecodeHSTSPreload(host, &result)) | |
| 1123 return false; | |
| 1124 | |
| 1125 if (!enable_static_expect_ct_ || !result.expect_ct) | |
| 1126 return false; | |
| 1127 | |
| 1128 expect_ct_state->domain = host.substr(result.hostname_offset); | |
| 1129 expect_ct_state->report_uri = | |
| 1130 GURL(kExpectCTReportURIs[result.expect_ct_report_uri_id]); | |
| 1131 return true; | |
| 1132 } | |
| 1133 | |
| 1134 bool TransportSecurityState::GetDynamicSTSState(const std::string& host, | 1161 bool TransportSecurityState::GetDynamicSTSState(const std::string& host, |
| 1135 STSState* result) { | 1162 STSState* result) { |
| 1136 DCHECK(CalledOnValidThread()); | 1163 DCHECK(CalledOnValidThread()); |
| 1137 | 1164 |
| 1138 const std::string canonicalized_host = CanonicalizeHost(host); | 1165 const std::string canonicalized_host = CanonicalizeHost(host); |
| 1139 if (canonicalized_host.empty()) | 1166 if (canonicalized_host.empty()) |
| 1140 return false; | 1167 return false; |
| 1141 | 1168 |
| 1142 base::Time current_time(base::Time::Now()); | 1169 base::Time current_time(base::Time::Now()); |
| 1143 | 1170 |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1309 TransportSecurityState::PKPStateIterator::PKPStateIterator( | 1336 TransportSecurityState::PKPStateIterator::PKPStateIterator( |
| 1310 const TransportSecurityState& state) | 1337 const TransportSecurityState& state) |
| 1311 : iterator_(state.enabled_pkp_hosts_.begin()), | 1338 : iterator_(state.enabled_pkp_hosts_.begin()), |
| 1312 end_(state.enabled_pkp_hosts_.end()) { | 1339 end_(state.enabled_pkp_hosts_.end()) { |
| 1313 } | 1340 } |
| 1314 | 1341 |
| 1315 TransportSecurityState::PKPStateIterator::~PKPStateIterator() { | 1342 TransportSecurityState::PKPStateIterator::~PKPStateIterator() { |
| 1316 } | 1343 } |
| 1317 | 1344 |
| 1318 } // namespace | 1345 } // namespace |
| OLD | NEW |