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 |