| 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 #if defined(USE_OPENSSL) | 7 #if defined(USE_OPENSSL) |
| 8 #include <openssl/ecdsa.h> | 8 #include <openssl/ecdsa.h> |
| 9 #include <openssl/ssl.h> | 9 #include <openssl/ssl.h> |
| 10 #else // !defined(USE_OPENSSL) | 10 #else // !defined(USE_OPENSSL) |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 report.Set("known-pins", known_pin_list.Pass()); | 128 report.Set("known-pins", known_pin_list.Pass()); |
| 129 | 129 |
| 130 if (!base::JSONWriter::Write(report, serialized_report)) { | 130 if (!base::JSONWriter::Write(report, serialized_report)) { |
| 131 LOG(ERROR) << "Failed to serialize HPKP violation report."; | 131 LOG(ERROR) << "Failed to serialize HPKP violation report."; |
| 132 return false; | 132 return false; |
| 133 } | 133 } |
| 134 | 134 |
| 135 return true; | 135 return true; |
| 136 } | 136 } |
| 137 | 137 |
| 138 bool CheckPinsAndMaybeSendReport( |
| 139 const HostPortPair& host_port_pair, |
| 140 const TransportSecurityState::PKPState& pkp_state, |
| 141 const HashValueVector& hashes, |
| 142 const X509Certificate* served_certificate_chain, |
| 143 const X509Certificate* validated_certificate_chain, |
| 144 const TransportSecurityState::PublicKeyPinReportStatus report_status, |
| 145 TransportSecurityState::ReportSender* report_sender, |
| 146 std::string* failure_log) { |
| 147 if (pkp_state.CheckPublicKeyPins(hashes, failure_log)) |
| 148 return true; |
| 149 |
| 150 if (!report_sender || |
| 151 report_status != TransportSecurityState::ENABLE_PIN_REPORTS || |
| 152 pkp_state.report_uri.is_empty()) { |
| 153 return false; |
| 154 } |
| 155 |
| 156 DCHECK(pkp_state.report_uri.is_valid()); |
| 157 |
| 158 std::string serialized_report; |
| 159 |
| 160 if (!GetHPKPReport(host_port_pair, pkp_state, served_certificate_chain, |
| 161 validated_certificate_chain, &serialized_report)) { |
| 162 return false; |
| 163 } |
| 164 |
| 165 report_sender->Send(pkp_state.report_uri, serialized_report); |
| 166 |
| 167 return false; |
| 168 } |
| 169 |
| 138 std::string HashesToBase64String(const HashValueVector& hashes) { | 170 std::string HashesToBase64String(const HashValueVector& hashes) { |
| 139 std::string str; | 171 std::string str; |
| 140 for (size_t i = 0; i != hashes.size(); ++i) { | 172 for (size_t i = 0; i != hashes.size(); ++i) { |
| 141 if (i != 0) | 173 if (i != 0) |
| 142 str += ","; | 174 str += ","; |
| 143 str += hashes[i].ToString(); | 175 str += hashes[i].ToString(); |
| 144 } | 176 } |
| 145 return str; | 177 return str; |
| 146 } | 178 } |
| 147 | 179 |
| (...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 866 void TransportSecurityState::AddHPKP(const std::string& host, | 898 void TransportSecurityState::AddHPKP(const std::string& host, |
| 867 const base::Time& expiry, | 899 const base::Time& expiry, |
| 868 bool include_subdomains, | 900 bool include_subdomains, |
| 869 const HashValueVector& hashes, | 901 const HashValueVector& hashes, |
| 870 const GURL& report_uri) { | 902 const GURL& report_uri) { |
| 871 DCHECK(CalledOnValidThread()); | 903 DCHECK(CalledOnValidThread()); |
| 872 AddHPKPInternal(host, base::Time::Now(), expiry, include_subdomains, hashes, | 904 AddHPKPInternal(host, base::Time::Now(), expiry, include_subdomains, hashes, |
| 873 report_uri); | 905 report_uri); |
| 874 } | 906 } |
| 875 | 907 |
| 908 bool TransportSecurityState::ProcessHPKPReportOnlyHeader( |
| 909 const std::string& value, |
| 910 const HostPortPair& host_port_pair, |
| 911 const SSLInfo& ssl_info) { |
| 912 DCHECK(CalledOnValidThread()); |
| 913 |
| 914 base::Time now = base::Time::Now(); |
| 915 bool include_subdomains; |
| 916 HashValueVector spki_hashes; |
| 917 GURL report_uri; |
| 918 std::string unused_failure_log; |
| 919 |
| 920 if (!ParseHPKPReportOnlyHeader(value, &include_subdomains, &spki_hashes, |
| 921 &report_uri) || |
| 922 !report_uri.is_valid() || report_uri.is_empty()) |
| 923 return false; |
| 924 |
| 925 PKPState pkp_state; |
| 926 pkp_state.last_observed = now; |
| 927 pkp_state.expiry = now; |
| 928 pkp_state.include_subdomains = include_subdomains; |
| 929 pkp_state.spki_hashes = spki_hashes; |
| 930 pkp_state.report_uri = report_uri; |
| 931 pkp_state.domain = DNSDomainToString(CanonicalizeHost(host_port_pair.host())); |
| 932 |
| 933 // Only perform pin validation if the cert chains up to a known root. |
| 934 if (!ssl_info.is_issued_by_known_root) |
| 935 return true; |
| 936 |
| 937 CheckPinsAndMaybeSendReport( |
| 938 host_port_pair, pkp_state, ssl_info.public_key_hashes, |
| 939 ssl_info.unverified_cert.get(), ssl_info.cert.get(), ENABLE_PIN_REPORTS, |
| 940 report_sender_, &unused_failure_log); |
| 941 return true; |
| 942 } |
| 943 |
| 876 // static | 944 // static |
| 877 bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host) { | 945 bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host) { |
| 878 PreloadResult result; | 946 PreloadResult result; |
| 879 return DecodeHSTSPreload(host, &result) && result.has_pins && | 947 return DecodeHSTSPreload(host, &result) && result.has_pins && |
| 880 kPinsets[result.pinset_id].accepted_pins == kGoogleAcceptableCerts; | 948 kPinsets[result.pinset_id].accepted_pins == kGoogleAcceptableCerts; |
| 881 } | 949 } |
| 882 | 950 |
| 883 // static | 951 // static |
| 884 void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) { | 952 void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) { |
| 885 PreloadResult result; | 953 PreloadResult result; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 920 PKPState pkp_state; | 988 PKPState pkp_state; |
| 921 STSState unused; | 989 STSState unused; |
| 922 | 990 |
| 923 if (!GetDynamicPKPState(host_port_pair.host(), &pkp_state) && | 991 if (!GetDynamicPKPState(host_port_pair.host(), &pkp_state) && |
| 924 !GetStaticDomainState(host_port_pair.host(), &unused, &pkp_state)) { | 992 !GetStaticDomainState(host_port_pair.host(), &unused, &pkp_state)) { |
| 925 // HasPublicKeyPins should have returned true in order for this method | 993 // HasPublicKeyPins should have returned true in order for this method |
| 926 // to have been called, so if we fall through to here, it's an error. | 994 // to have been called, so if we fall through to here, it's an error. |
| 927 return false; | 995 return false; |
| 928 } | 996 } |
| 929 | 997 |
| 930 if (pkp_state.CheckPublicKeyPins(hashes, failure_log)) | 998 return CheckPinsAndMaybeSendReport( |
| 931 return true; | 999 host_port_pair, pkp_state, hashes, served_certificate_chain, |
| 932 | 1000 validated_certificate_chain, report_status, report_sender_, failure_log); |
| 933 if (!report_sender_ || report_status != ENABLE_PIN_REPORTS || | |
| 934 pkp_state.report_uri.is_empty()) { | |
| 935 return false; | |
| 936 } | |
| 937 | |
| 938 DCHECK(pkp_state.report_uri.is_valid()); | |
| 939 | |
| 940 std::string serialized_report; | |
| 941 | |
| 942 if (!GetHPKPReport(host_port_pair, pkp_state, served_certificate_chain, | |
| 943 validated_certificate_chain, &serialized_report)) { | |
| 944 return false; | |
| 945 } | |
| 946 | |
| 947 report_sender_->Send(pkp_state.report_uri, serialized_report); | |
| 948 | |
| 949 return false; | |
| 950 } | 1001 } |
| 951 | 1002 |
| 952 bool TransportSecurityState::GetStaticDomainState(const std::string& host, | 1003 bool TransportSecurityState::GetStaticDomainState(const std::string& host, |
| 953 STSState* sts_state, | 1004 STSState* sts_state, |
| 954 PKPState* pkp_state) const { | 1005 PKPState* pkp_state) const { |
| 955 DCHECK(CalledOnValidThread()); | 1006 DCHECK(CalledOnValidThread()); |
| 956 | 1007 |
| 957 sts_state->upgrade_mode = STSState::MODE_FORCE_HTTPS; | 1008 sts_state->upgrade_mode = STSState::MODE_FORCE_HTTPS; |
| 958 sts_state->include_subdomains = false; | 1009 sts_state->include_subdomains = false; |
| 959 pkp_state->include_subdomains = false; | 1010 pkp_state->include_subdomains = false; |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1175 TransportSecurityState::PKPStateIterator::PKPStateIterator( | 1226 TransportSecurityState::PKPStateIterator::PKPStateIterator( |
| 1176 const TransportSecurityState& state) | 1227 const TransportSecurityState& state) |
| 1177 : iterator_(state.enabled_pkp_hosts_.begin()), | 1228 : iterator_(state.enabled_pkp_hosts_.begin()), |
| 1178 end_(state.enabled_pkp_hosts_.end()) { | 1229 end_(state.enabled_pkp_hosts_.end()) { |
| 1179 } | 1230 } |
| 1180 | 1231 |
| 1181 TransportSecurityState::PKPStateIterator::~PKPStateIterator() { | 1232 TransportSecurityState::PKPStateIterator::~PKPStateIterator() { |
| 1182 } | 1233 } |
| 1183 | 1234 |
| 1184 } // namespace | 1235 } // namespace |
| OLD | NEW |