OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/quic/crypto/proof_verifier_chromium.h" | 5 #include "net/quic/crypto/proof_verifier_chromium.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/callback_helpers.h" | 9 #include "base/callback_helpers.h" |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 SSLConfigService::GetCRLSet().get(), | 229 SSLConfigService::GetCRLSet().get(), |
230 &verify_details_->cert_verify_result, | 230 &verify_details_->cert_verify_result, |
231 base::Bind(&ProofVerifierChromium::Job::OnIOComplete, | 231 base::Bind(&ProofVerifierChromium::Job::OnIOComplete, |
232 base::Unretained(this)), | 232 base::Unretained(this)), |
233 net_log_); | 233 net_log_); |
234 } | 234 } |
235 | 235 |
236 int ProofVerifierChromium::Job::DoVerifyCertComplete(int result) { | 236 int ProofVerifierChromium::Job::DoVerifyCertComplete(int result) { |
237 verifier_.reset(); | 237 verifier_.reset(); |
238 | 238 |
239 #if defined(OFFICIAL_BUILD) && !defined(OS_ANDROID) && !defined(OS_IOS) | |
240 // TODO(wtc): The following code was copied from ssl_client_socket_nss.cc. | |
241 // Convert it to a new function that can be called by both files. These | |
242 // variables simulate the arguments to the new function. | |
243 const CertVerifyResult& cert_verify_result = | 239 const CertVerifyResult& cert_verify_result = |
244 verify_details_->cert_verify_result; | 240 verify_details_->cert_verify_result; |
245 bool sni_available = true; | |
246 const std::string& host = hostname_; | |
247 TransportSecurityState* transport_security_state = transport_security_state_; | |
248 std::string* pinning_failure_log = &verify_details_->pinning_failure_log; | |
249 | |
250 // Take care of any mandates for public key pinning. | |
251 // | |
252 // Pinning is only enabled for official builds to make sure that others don't | |
253 // end up with pins that cannot be easily updated. | |
254 // | |
255 // TODO(agl): We might have an issue here where a request for foo.example.com | |
256 // merges into a SPDY connection to www.example.com, and gets a different | |
257 // certificate. | |
258 | |
259 // Perform pin validation if, and only if, all these conditions obtain: | |
260 // | |
261 // * a TransportSecurityState object is available; | |
262 // * the server's certificate chain is valid (or suffers from only a minor | |
263 // error); | |
264 // * the server's certificate chain chains up to a known root (i.e. not a | |
265 // user-installed trust anchor); and | |
266 // * the build is recent (very old builds should fail open so that users | |
267 // have some chance to recover). | |
268 // | |
269 const CertStatus cert_status = cert_verify_result.cert_status; | 241 const CertStatus cert_status = cert_verify_result.cert_status; |
270 if (transport_security_state && | 242 if (transport_security_state_ && |
271 (result == OK || | 243 (result == OK || |
272 (IsCertificateError(result) && IsCertStatusMinorError(cert_status))) && | 244 (IsCertificateError(result) && IsCertStatusMinorError(cert_status))) && |
273 cert_verify_result.is_issued_by_known_root && | 245 !transport_security_state_->CheckPublicKeyPins( |
274 TransportSecurityState::IsBuildTimely()) { | 246 hostname_, |
275 if (transport_security_state->HasPublicKeyPins(host, sni_available)) { | 247 true, /* sni_available */ |
276 if (!transport_security_state->CheckPublicKeyPins( | 248 cert_verify_result.is_issued_by_known_root, |
277 host, | 249 cert_verify_result.public_key_hashes, |
278 sni_available, | 250 &verify_details_->pinning_failure_log)) { |
279 cert_verify_result.public_key_hashes, | 251 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; |
280 pinning_failure_log)) { | |
281 LOG(ERROR) << *pinning_failure_log; | |
282 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; | |
283 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", false); | |
284 TransportSecurityState::ReportUMAOnPinFailure(host); | |
285 } else { | |
286 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", true); | |
287 } | |
288 } | |
289 } | 252 } |
290 #endif | |
291 | 253 |
292 if (result != OK) { | 254 if (result != OK) { |
293 std::string error_string = ErrorToString(result); | 255 std::string error_string = ErrorToString(result); |
294 error_details_ = StringPrintf("Failed to verify certificate chain: %s", | 256 error_details_ = StringPrintf("Failed to verify certificate chain: %s", |
295 error_string.c_str()); | 257 error_string.c_str()); |
296 DLOG(WARNING) << error_details_; | 258 DLOG(WARNING) << error_details_; |
297 } | 259 } |
298 | 260 |
299 // Exit DoLoop and return the result to the caller to VerifyProof. | 261 // Exit DoLoop and return the result to the caller to VerifyProof. |
300 DCHECK_EQ(STATE_NONE, next_state_); | 262 DCHECK_EQ(STATE_NONE, next_state_); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 } | 377 } |
416 return status; | 378 return status; |
417 } | 379 } |
418 | 380 |
419 void ProofVerifierChromium::OnJobComplete(Job* job) { | 381 void ProofVerifierChromium::OnJobComplete(Job* job) { |
420 active_jobs_.erase(job); | 382 active_jobs_.erase(job); |
421 delete job; | 383 delete job; |
422 } | 384 } |
423 | 385 |
424 } // namespace net | 386 } // namespace net |
OLD | NEW |