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 HostPortPair& host_port_pair, | |
910 const std::string& value, | |
911 const SSLInfo& ssl_info) { | |
912 DCHECK(CalledOnValidThread()); | |
913 | |
914 base::Time now = base::Time::Now(); | |
915 HashValueVector spki_hashes; | |
916 GURL report_uri; | |
917 std::string unused_failure_log; | |
918 | |
919 if (!ParseHPKPReportOnlyHeader(value, &spki_hashes, &report_uri) || | |
920 !report_uri.is_valid() || report_uri.is_empty()) | |
921 return false; | |
922 | |
923 PKPState pkp_state; | |
924 pkp_state.last_observed = now; | |
925 pkp_state.include_subdomains = false; | |
926 pkp_state.spki_hashes = spki_hashes; | |
927 pkp_state.report_uri = report_uri; | |
928 pkp_state.domain = DNSDomainToString(CanonicalizeHost(host_port_pair.host())); | |
929 | |
930 // Do not perform pin validation if the cert chains up to a known | |
931 // root. | |
932 if (!ssl_info.is_issued_by_known_root) | |
Ryan Sleevi
2015/07/30 01:52:16
I guess I'm a little nervous to see this check spr
estark
2015/07/31 00:49:44
Yeah, I agree that it would be have been easy to f
| |
933 return true; | |
934 | |
935 CheckPinsAndMaybeSendReport( | |
936 host_port_pair, pkp_state, ssl_info.public_key_hashes, | |
937 ssl_info.unverified_cert.get(), ssl_info.cert.get(), ENABLE_PIN_REPORTS, | |
938 report_sender_, &unused_failure_log); | |
939 return true; | |
940 } | |
941 | |
876 // static | 942 // static |
877 bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host) { | 943 bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host) { |
878 PreloadResult result; | 944 PreloadResult result; |
879 return DecodeHSTSPreload(host, &result) && result.has_pins && | 945 return DecodeHSTSPreload(host, &result) && result.has_pins && |
880 kPinsets[result.pinset_id].accepted_pins == kGoogleAcceptableCerts; | 946 kPinsets[result.pinset_id].accepted_pins == kGoogleAcceptableCerts; |
881 } | 947 } |
882 | 948 |
883 // static | 949 // static |
884 void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) { | 950 void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) { |
885 PreloadResult result; | 951 PreloadResult result; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
920 PKPState pkp_state; | 986 PKPState pkp_state; |
921 STSState unused; | 987 STSState unused; |
922 | 988 |
923 if (!GetDynamicPKPState(host_port_pair.host(), &pkp_state) && | 989 if (!GetDynamicPKPState(host_port_pair.host(), &pkp_state) && |
924 !GetStaticDomainState(host_port_pair.host(), &unused, &pkp_state)) { | 990 !GetStaticDomainState(host_port_pair.host(), &unused, &pkp_state)) { |
925 // HasPublicKeyPins should have returned true in order for this method | 991 // 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. | 992 // to have been called, so if we fall through to here, it's an error. |
927 return false; | 993 return false; |
928 } | 994 } |
929 | 995 |
930 if (pkp_state.CheckPublicKeyPins(hashes, failure_log)) | 996 return CheckPinsAndMaybeSendReport( |
931 return true; | 997 host_port_pair, pkp_state, hashes, served_certificate_chain, |
932 | 998 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 } | 999 } |
951 | 1000 |
952 bool TransportSecurityState::GetStaticDomainState(const std::string& host, | 1001 bool TransportSecurityState::GetStaticDomainState(const std::string& host, |
953 STSState* sts_state, | 1002 STSState* sts_state, |
954 PKPState* pkp_state) const { | 1003 PKPState* pkp_state) const { |
955 DCHECK(CalledOnValidThread()); | 1004 DCHECK(CalledOnValidThread()); |
956 | 1005 |
957 sts_state->upgrade_mode = STSState::MODE_FORCE_HTTPS; | 1006 sts_state->upgrade_mode = STSState::MODE_FORCE_HTTPS; |
958 sts_state->include_subdomains = false; | 1007 sts_state->include_subdomains = false; |
959 pkp_state->include_subdomains = false; | 1008 pkp_state->include_subdomains = false; |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1175 TransportSecurityState::PKPStateIterator::PKPStateIterator( | 1224 TransportSecurityState::PKPStateIterator::PKPStateIterator( |
1176 const TransportSecurityState& state) | 1225 const TransportSecurityState& state) |
1177 : iterator_(state.enabled_pkp_hosts_.begin()), | 1226 : iterator_(state.enabled_pkp_hosts_.begin()), |
1178 end_(state.enabled_pkp_hosts_.end()) { | 1227 end_(state.enabled_pkp_hosts_.end()) { |
1179 } | 1228 } |
1180 | 1229 |
1181 TransportSecurityState::PKPStateIterator::~PKPStateIterator() { | 1230 TransportSecurityState::PKPStateIterator::~PKPStateIterator() { |
1182 } | 1231 } |
1183 | 1232 |
1184 } // namespace | 1233 } // namespace |
OLD | NEW |