| 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/socket/ssl_client_socket_impl.h" | 5 #include "net/socket/ssl_client_socket_impl.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <openssl/bio.h> | 8 #include <openssl/bio.h> |
| 9 #include <openssl/bytestring.h> | 9 #include <openssl/bytestring.h> |
| 10 #include <openssl/err.h> | 10 #include <openssl/err.h> |
| (...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 session_pending_(false), | 523 session_pending_(false), |
| 524 certificate_verified_(false), | 524 certificate_verified_(false), |
| 525 ssl_failure_state_(SSL_FAILURE_NONE), | 525 ssl_failure_state_(SSL_FAILURE_NONE), |
| 526 signature_result_(kNoPendingResult), | 526 signature_result_(kNoPendingResult), |
| 527 transport_security_state_(context.transport_security_state), | 527 transport_security_state_(context.transport_security_state), |
| 528 policy_enforcer_(context.ct_policy_enforcer), | 528 policy_enforcer_(context.ct_policy_enforcer), |
| 529 pkp_bypassed_(false), | 529 pkp_bypassed_(false), |
| 530 net_log_(transport_->socket()->NetLog()), | 530 net_log_(transport_->socket()->NetLog()), |
| 531 weak_factory_(this) { | 531 weak_factory_(this) { |
| 532 DCHECK(cert_verifier_); | 532 DCHECK(cert_verifier_); |
| 533 DCHECK(transport_security_state_); |
| 534 DCHECK(policy_enforcer_); |
| 533 } | 535 } |
| 534 | 536 |
| 535 SSLClientSocketImpl::~SSLClientSocketImpl() { | 537 SSLClientSocketImpl::~SSLClientSocketImpl() { |
| 536 Disconnect(); | 538 Disconnect(); |
| 537 } | 539 } |
| 538 | 540 |
| 539 #if !defined(OS_NACL) | 541 #if !defined(OS_NACL) |
| 540 void SSLClientSocketImpl::SetSSLKeyLogFile( | 542 void SSLClientSocketImpl::SetSSLKeyLogFile( |
| 541 const base::FilePath& ssl_keylog_file, | 543 const base::FilePath& ssl_keylog_file, |
| 542 const scoped_refptr<base::SequencedTaskRunner>& task_runner) { | 544 const scoped_refptr<base::SequencedTaskRunner>& task_runner) { |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 if (rv != 1) { | 622 if (rv != 1) { |
| 621 int ssl_error = SSL_get_error(ssl_, rv); | 623 int ssl_error = SSL_get_error(ssl_, rv); |
| 622 LOG(ERROR) << "Failed to export keying material;" | 624 LOG(ERROR) << "Failed to export keying material;" |
| 623 << " returned " << rv << ", SSL error code " << ssl_error; | 625 << " returned " << rv << ", SSL error code " << ssl_error; |
| 624 return MapOpenSSLError(ssl_error, err_tracer); | 626 return MapOpenSSLError(ssl_error, err_tracer); |
| 625 } | 627 } |
| 626 return OK; | 628 return OK; |
| 627 } | 629 } |
| 628 | 630 |
| 629 int SSLClientSocketImpl::Connect(const CompletionCallback& callback) { | 631 int SSLClientSocketImpl::Connect(const CompletionCallback& callback) { |
| 630 // It is an error to create an SSLClientSocket whose context has no | |
| 631 // TransportSecurityState. | |
| 632 DCHECK(transport_security_state_); | |
| 633 | |
| 634 // Although StreamSocket does allow calling Connect() after Disconnect(), | 632 // Although StreamSocket does allow calling Connect() after Disconnect(), |
| 635 // this has never worked for layered sockets. CHECK to detect any consumers | 633 // this has never worked for layered sockets. CHECK to detect any consumers |
| 636 // reconnecting an SSL socket. | 634 // reconnecting an SSL socket. |
| 637 // | 635 // |
| 638 // TODO(davidben,mmenke): Remove this API feature. See | 636 // TODO(davidben,mmenke): Remove this API feature. See |
| 639 // https://crbug.com/499289. | 637 // https://crbug.com/499289. |
| 640 CHECK(!disconnected_); | 638 CHECK(!disconnected_); |
| 641 | 639 |
| 642 net_log_.BeginEvent(NetLog::TYPE_SSL_CONNECT); | 640 net_log_.BeginEvent(NetLog::TYPE_SSL_CONNECT); |
| 643 | 641 |
| (...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1339 base::TimeDelta verify_time = | 1337 base::TimeDelta verify_time = |
| 1340 base::TimeTicks::Now() - start_cert_verification_time_; | 1338 base::TimeTicks::Now() - start_cert_verification_time_; |
| 1341 if (result == OK) { | 1339 if (result == OK) { |
| 1342 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTime", verify_time); | 1340 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTime", verify_time); |
| 1343 } else { | 1341 } else { |
| 1344 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTimeError", verify_time); | 1342 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTimeError", verify_time); |
| 1345 } | 1343 } |
| 1346 } | 1344 } |
| 1347 | 1345 |
| 1348 const CertStatus cert_status = server_cert_verify_result_.cert_status; | 1346 const CertStatus cert_status = server_cert_verify_result_.cert_status; |
| 1349 if (transport_security_state_ && | 1347 if ((result == OK || |
| 1350 (result == OK || | |
| 1351 (IsCertificateError(result) && IsCertStatusMinorError(cert_status))) && | 1348 (IsCertificateError(result) && IsCertStatusMinorError(cert_status))) && |
| 1352 !transport_security_state_->CheckPublicKeyPins( | 1349 !transport_security_state_->CheckPublicKeyPins( |
| 1353 host_and_port_, server_cert_verify_result_.is_issued_by_known_root, | 1350 host_and_port_, server_cert_verify_result_.is_issued_by_known_root, |
| 1354 server_cert_verify_result_.public_key_hashes, server_cert_.get(), | 1351 server_cert_verify_result_.public_key_hashes, server_cert_.get(), |
| 1355 server_cert_verify_result_.verified_cert.get(), | 1352 server_cert_verify_result_.verified_cert.get(), |
| 1356 TransportSecurityState::ENABLE_PIN_REPORTS, &pinning_failure_log_)) { | 1353 TransportSecurityState::ENABLE_PIN_REPORTS, &pinning_failure_log_)) { |
| 1357 if (server_cert_verify_result_.is_issued_by_known_root) | 1354 if (server_cert_verify_result_.is_issued_by_known_root) |
| 1358 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; | 1355 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; |
| 1359 else | 1356 else |
| 1360 pkp_bypassed_ = true; | 1357 pkp_bypassed_ = true; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1391 server_cert_chain_->Reset(SSL_get_peer_cert_chain(ssl_)); | 1388 server_cert_chain_->Reset(SSL_get_peer_cert_chain(ssl_)); |
| 1392 server_cert_ = server_cert_chain_->AsOSChain(); | 1389 server_cert_ = server_cert_chain_->AsOSChain(); |
| 1393 if (server_cert_.get()) { | 1390 if (server_cert_.get()) { |
| 1394 net_log_.AddEvent(NetLog::TYPE_SSL_CERTIFICATES_RECEIVED, | 1391 net_log_.AddEvent(NetLog::TYPE_SSL_CERTIFICATES_RECEIVED, |
| 1395 base::Bind(&NetLogX509CertificateCallback, | 1392 base::Bind(&NetLogX509CertificateCallback, |
| 1396 base::Unretained(server_cert_.get()))); | 1393 base::Unretained(server_cert_.get()))); |
| 1397 } | 1394 } |
| 1398 } | 1395 } |
| 1399 | 1396 |
| 1400 void SSLClientSocketImpl::VerifyCT() { | 1397 void SSLClientSocketImpl::VerifyCT() { |
| 1401 if (!cert_transparency_verifier_) | |
| 1402 return; | |
| 1403 | |
| 1404 const uint8_t* ocsp_response_raw; | 1398 const uint8_t* ocsp_response_raw; |
| 1405 size_t ocsp_response_len; | 1399 size_t ocsp_response_len; |
| 1406 SSL_get0_ocsp_response(ssl_, &ocsp_response_raw, &ocsp_response_len); | 1400 SSL_get0_ocsp_response(ssl_, &ocsp_response_raw, &ocsp_response_len); |
| 1407 std::string ocsp_response; | 1401 std::string ocsp_response; |
| 1408 if (ocsp_response_len > 0) { | 1402 if (ocsp_response_len > 0) { |
| 1409 ocsp_response.assign(reinterpret_cast<const char*>(ocsp_response_raw), | 1403 ocsp_response.assign(reinterpret_cast<const char*>(ocsp_response_raw), |
| 1410 ocsp_response_len); | 1404 ocsp_response_len); |
| 1411 } | 1405 } |
| 1412 | 1406 |
| 1413 const uint8_t* sct_list_raw; | 1407 const uint8_t* sct_list_raw; |
| 1414 size_t sct_list_len; | 1408 size_t sct_list_len; |
| 1415 SSL_get0_signed_cert_timestamp_list(ssl_, &sct_list_raw, &sct_list_len); | 1409 SSL_get0_signed_cert_timestamp_list(ssl_, &sct_list_raw, &sct_list_len); |
| 1416 std::string sct_list; | 1410 std::string sct_list; |
| 1417 if (sct_list_len > 0) | 1411 if (sct_list_len > 0) |
| 1418 sct_list.assign(reinterpret_cast<const char*>(sct_list_raw), sct_list_len); | 1412 sct_list.assign(reinterpret_cast<const char*>(sct_list_raw), sct_list_len); |
| 1419 | 1413 |
| 1420 // Note that this is a completely synchronous operation: The CT Log Verifier | 1414 // Note that this is a completely synchronous operation: The CT Log Verifier |
| 1421 // gets all the data it needs for SCT verification and does not do any | 1415 // gets all the data it needs for SCT verification and does not do any |
| 1422 // external communication. | 1416 // external communication. |
| 1423 cert_transparency_verifier_->Verify( | 1417 cert_transparency_verifier_->Verify( |
| 1424 server_cert_verify_result_.verified_cert.get(), ocsp_response, sct_list, | 1418 server_cert_verify_result_.verified_cert.get(), ocsp_response, sct_list, |
| 1425 &ct_verify_result_, net_log_); | 1419 &ct_verify_result_, net_log_); |
| 1426 | 1420 |
| 1427 ct_verify_result_.ct_policies_applied = (policy_enforcer_ != nullptr); | 1421 ct_verify_result_.ct_policies_applied = (policy_enforcer_ != nullptr); |
| 1428 ct_verify_result_.ev_policy_compliance = | 1422 ct_verify_result_.ev_policy_compliance = |
| 1429 ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY; | 1423 ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY; |
| 1430 if (policy_enforcer_) { | 1424 if ((server_cert_verify_result_.cert_status & CERT_STATUS_IS_EV)) { |
| 1431 if ((server_cert_verify_result_.cert_status & CERT_STATUS_IS_EV)) { | 1425 scoped_refptr<ct::EVCertsWhitelist> ev_whitelist = |
| 1432 scoped_refptr<ct::EVCertsWhitelist> ev_whitelist = | 1426 SSLConfigService::GetEVCertsWhitelist(); |
| 1433 SSLConfigService::GetEVCertsWhitelist(); | 1427 ct::EVPolicyCompliance ev_policy_compliance = |
| 1434 ct::EVPolicyCompliance ev_policy_compliance = | 1428 policy_enforcer_->DoesConformToCTEVPolicy( |
| 1435 policy_enforcer_->DoesConformToCTEVPolicy( | 1429 server_cert_verify_result_.verified_cert.get(), ev_whitelist.get(), |
| 1436 server_cert_verify_result_.verified_cert.get(), | 1430 ct_verify_result_.verified_scts, net_log_); |
| 1437 ev_whitelist.get(), ct_verify_result_.verified_scts, net_log_); | 1431 ct_verify_result_.ev_policy_compliance = ev_policy_compliance; |
| 1438 ct_verify_result_.ev_policy_compliance = ev_policy_compliance; | 1432 if (ev_policy_compliance != |
| 1439 if (ev_policy_compliance != | 1433 ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY && |
| 1440 ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY && | 1434 ev_policy_compliance != |
| 1441 ev_policy_compliance != | 1435 ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_WHITELIST && |
| 1442 ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_WHITELIST && | 1436 ev_policy_compliance != |
| 1443 ev_policy_compliance != | 1437 ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS) { |
| 1444 ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS) { | 1438 // TODO(eranm): Log via the BoundNetLog, see crbug.com/437766 |
| 1445 // TODO(eranm): Log via the BoundNetLog, see crbug.com/437766 | 1439 VLOG(1) << "EV certificate for " |
| 1446 VLOG(1) << "EV certificate for " | 1440 << server_cert_verify_result_.verified_cert->subject() |
| 1447 << server_cert_verify_result_.verified_cert->subject() | 1441 .GetDisplayName() |
| 1448 .GetDisplayName() | 1442 << " does not conform to CT policy, removing EV status."; |
| 1449 << " does not conform to CT policy, removing EV status."; | 1443 server_cert_verify_result_.cert_status |= |
| 1450 server_cert_verify_result_.cert_status |= | 1444 CERT_STATUS_CT_COMPLIANCE_FAILED; |
| 1451 CERT_STATUS_CT_COMPLIANCE_FAILED; | 1445 server_cert_verify_result_.cert_status &= ~CERT_STATUS_IS_EV; |
| 1452 server_cert_verify_result_.cert_status &= ~CERT_STATUS_IS_EV; | |
| 1453 } | |
| 1454 } | 1446 } |
| 1455 ct_verify_result_.cert_policy_compliance = | |
| 1456 policy_enforcer_->DoesConformToCertPolicy( | |
| 1457 server_cert_verify_result_.verified_cert.get(), | |
| 1458 ct_verify_result_.verified_scts, net_log_); | |
| 1459 } | 1447 } |
| 1448 ct_verify_result_.cert_policy_compliance = |
| 1449 policy_enforcer_->DoesConformToCertPolicy( |
| 1450 server_cert_verify_result_.verified_cert.get(), |
| 1451 ct_verify_result_.verified_scts, net_log_); |
| 1460 } | 1452 } |
| 1461 | 1453 |
| 1462 void SSLClientSocketImpl::OnHandshakeIOComplete(int result) { | 1454 void SSLClientSocketImpl::OnHandshakeIOComplete(int result) { |
| 1463 int rv = DoHandshakeLoop(result); | 1455 int rv = DoHandshakeLoop(result); |
| 1464 if (rv != ERR_IO_PENDING) { | 1456 if (rv != ERR_IO_PENDING) { |
| 1465 LogConnectEndEvent(rv); | 1457 LogConnectEndEvent(rv); |
| 1466 DoConnectCallback(rv); | 1458 DoConnectCallback(rv); |
| 1467 } | 1459 } |
| 1468 } | 1460 } |
| 1469 | 1461 |
| (...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2337 if (rv != OK) { | 2329 if (rv != OK) { |
| 2338 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv); | 2330 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv); |
| 2339 return; | 2331 return; |
| 2340 } | 2332 } |
| 2341 | 2333 |
| 2342 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, | 2334 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, |
| 2343 base::Bind(&NetLogSSLInfoCallback, base::Unretained(this))); | 2335 base::Bind(&NetLogSSLInfoCallback, base::Unretained(this))); |
| 2344 } | 2336 } |
| 2345 | 2337 |
| 2346 } // namespace net | 2338 } // namespace net |
| OLD | NEW |