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 #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 // Do not perform pin validation if the cert chains up to a known | |
| 934 // root. | |
|
davidben
2015/07/31 19:45:07
I think you want "Do not" -> "Only"
estark
2015/07/31 20:37:33
Done.
| |
| 935 if (!ssl_info.is_issued_by_known_root) | |
| 936 return true; | |
| 937 | |
| 938 CheckPinsAndMaybeSendReport( | |
| 939 host_port_pair, pkp_state, ssl_info.public_key_hashes, | |
| 940 ssl_info.unverified_cert.get(), ssl_info.cert.get(), ENABLE_PIN_REPORTS, | |
| 941 report_sender_, &unused_failure_log); | |
| 942 return true; | |
| 943 } | |
| 944 | |
| 876 // static | 945 // static |
| 877 bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host) { | 946 bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host) { |
| 878 PreloadResult result; | 947 PreloadResult result; |
| 879 return DecodeHSTSPreload(host, &result) && result.has_pins && | 948 return DecodeHSTSPreload(host, &result) && result.has_pins && |
| 880 kPinsets[result.pinset_id].accepted_pins == kGoogleAcceptableCerts; | 949 kPinsets[result.pinset_id].accepted_pins == kGoogleAcceptableCerts; |
| 881 } | 950 } |
| 882 | 951 |
| 883 // static | 952 // static |
| 884 void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) { | 953 void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) { |
| 885 PreloadResult result; | 954 PreloadResult result; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 920 PKPState pkp_state; | 989 PKPState pkp_state; |
| 921 STSState unused; | 990 STSState unused; |
| 922 | 991 |
| 923 if (!GetDynamicPKPState(host_port_pair.host(), &pkp_state) && | 992 if (!GetDynamicPKPState(host_port_pair.host(), &pkp_state) && |
| 924 !GetStaticDomainState(host_port_pair.host(), &unused, &pkp_state)) { | 993 !GetStaticDomainState(host_port_pair.host(), &unused, &pkp_state)) { |
| 925 // HasPublicKeyPins should have returned true in order for this method | 994 // 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. | 995 // to have been called, so if we fall through to here, it's an error. |
| 927 return false; | 996 return false; |
| 928 } | 997 } |
| 929 | 998 |
| 930 if (pkp_state.CheckPublicKeyPins(hashes, failure_log)) | 999 return CheckPinsAndMaybeSendReport( |
| 931 return true; | 1000 host_port_pair, pkp_state, hashes, served_certificate_chain, |
| 932 | 1001 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 } | 1002 } |
| 951 | 1003 |
| 952 bool TransportSecurityState::GetStaticDomainState(const std::string& host, | 1004 bool TransportSecurityState::GetStaticDomainState(const std::string& host, |
| 953 STSState* sts_state, | 1005 STSState* sts_state, |
| 954 PKPState* pkp_state) const { | 1006 PKPState* pkp_state) const { |
| 955 DCHECK(CalledOnValidThread()); | 1007 DCHECK(CalledOnValidThread()); |
| 956 | 1008 |
| 957 sts_state->upgrade_mode = STSState::MODE_FORCE_HTTPS; | 1009 sts_state->upgrade_mode = STSState::MODE_FORCE_HTTPS; |
| 958 sts_state->include_subdomains = false; | 1010 sts_state->include_subdomains = false; |
| 959 pkp_state->include_subdomains = false; | 1011 pkp_state->include_subdomains = false; |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1175 TransportSecurityState::PKPStateIterator::PKPStateIterator( | 1227 TransportSecurityState::PKPStateIterator::PKPStateIterator( |
| 1176 const TransportSecurityState& state) | 1228 const TransportSecurityState& state) |
| 1177 : iterator_(state.enabled_pkp_hosts_.begin()), | 1229 : iterator_(state.enabled_pkp_hosts_.begin()), |
| 1178 end_(state.enabled_pkp_hosts_.end()) { | 1230 end_(state.enabled_pkp_hosts_.end()) { |
| 1179 } | 1231 } |
| 1180 | 1232 |
| 1181 TransportSecurityState::PKPStateIterator::~PKPStateIterator() { | 1233 TransportSecurityState::PKPStateIterator::~PKPStateIterator() { |
| 1182 } | 1234 } |
| 1183 | 1235 |
| 1184 } // namespace | 1236 } // namespace |
| OLD | NEW |