| 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 1309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1320 if (!start_cert_verification_time_.is_null()) { | 1320 if (!start_cert_verification_time_.is_null()) { |
| 1321 base::TimeDelta verify_time = | 1321 base::TimeDelta verify_time = |
| 1322 base::TimeTicks::Now() - start_cert_verification_time_; | 1322 base::TimeTicks::Now() - start_cert_verification_time_; |
| 1323 if (result == OK) { | 1323 if (result == OK) { |
| 1324 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTime", verify_time); | 1324 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTime", verify_time); |
| 1325 } else { | 1325 } else { |
| 1326 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTimeError", verify_time); | 1326 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTimeError", verify_time); |
| 1327 } | 1327 } |
| 1328 } | 1328 } |
| 1329 | 1329 |
| 1330 // If the connection was good, check HPKP and CT status simultaneously, |
| 1331 // but prefer to treat the HPKP error as more serious, if there was one. |
| 1330 const CertStatus cert_status = server_cert_verify_result_.cert_status; | 1332 const CertStatus cert_status = server_cert_verify_result_.cert_status; |
| 1331 if (transport_security_state_ && | 1333 if ((result == OK || |
| 1332 (result == OK || | |
| 1333 (IsCertificateError(result) && IsCertStatusMinorError(cert_status)))) { | 1334 (IsCertificateError(result) && IsCertStatusMinorError(cert_status)))) { |
| 1335 int ct_result = VerifyCT(); |
| 1334 TransportSecurityState::PKPStatus pin_validity = | 1336 TransportSecurityState::PKPStatus pin_validity = |
| 1335 transport_security_state_->CheckPublicKeyPins( | 1337 transport_security_state_->CheckPublicKeyPins( |
| 1336 host_and_port_, server_cert_verify_result_.is_issued_by_known_root, | 1338 host_and_port_, server_cert_verify_result_.is_issued_by_known_root, |
| 1337 server_cert_verify_result_.public_key_hashes, server_cert_.get(), | 1339 server_cert_verify_result_.public_key_hashes, server_cert_.get(), |
| 1338 server_cert_verify_result_.verified_cert.get(), | 1340 server_cert_verify_result_.verified_cert.get(), |
| 1339 TransportSecurityState::ENABLE_PIN_REPORTS, &pinning_failure_log_); | 1341 TransportSecurityState::ENABLE_PIN_REPORTS, &pinning_failure_log_); |
| 1340 switch (pin_validity) { | 1342 switch (pin_validity) { |
| 1341 case TransportSecurityState::PKPStatus::VIOLATED: | 1343 case TransportSecurityState::PKPStatus::VIOLATED: |
| 1342 server_cert_verify_result_.cert_status |= | 1344 server_cert_verify_result_.cert_status |= |
| 1343 CERT_STATUS_PINNED_KEY_MISSING; | 1345 CERT_STATUS_PINNED_KEY_MISSING; |
| 1344 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; | 1346 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; |
| 1345 break; | 1347 break; |
| 1346 case TransportSecurityState::PKPStatus::BYPASSED: | 1348 case TransportSecurityState::PKPStatus::BYPASSED: |
| 1347 pkp_bypassed_ = true; | 1349 pkp_bypassed_ = true; |
| 1348 // Fall through. | 1350 // Fall through. |
| 1349 case TransportSecurityState::PKPStatus::OK: | 1351 case TransportSecurityState::PKPStatus::OK: |
| 1350 // Do nothing. | 1352 // Do nothing. |
| 1351 break; | 1353 break; |
| 1352 } | 1354 } |
| 1355 if (result != ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN && ct_result != OK) |
| 1356 result = ct_result; |
| 1353 } | 1357 } |
| 1354 | 1358 |
| 1355 if (result == OK) { | 1359 if (result == OK) { |
| 1356 // Only check Certificate Transparency if there were no other errors with | |
| 1357 // the connection. | |
| 1358 VerifyCT(); | |
| 1359 | |
| 1360 DCHECK(!certificate_verified_); | 1360 DCHECK(!certificate_verified_); |
| 1361 certificate_verified_ = true; | 1361 certificate_verified_ = true; |
| 1362 MaybeCacheSession(); | 1362 MaybeCacheSession(); |
| 1363 } | 1363 } |
| 1364 | 1364 |
| 1365 completed_connect_ = true; | 1365 completed_connect_ = true; |
| 1366 // Exit DoHandshakeLoop and return the result to the caller to Connect. | 1366 // Exit DoHandshakeLoop and return the result to the caller to Connect. |
| 1367 DCHECK_EQ(STATE_NONE, next_handshake_state_); | 1367 DCHECK_EQ(STATE_NONE, next_handshake_state_); |
| 1368 return result; | 1368 return result; |
| 1369 } | 1369 } |
| 1370 | 1370 |
| 1371 void SSLClientSocketImpl::DoConnectCallback(int rv) { | 1371 void SSLClientSocketImpl::DoConnectCallback(int rv) { |
| 1372 if (!user_connect_callback_.is_null()) { | 1372 if (!user_connect_callback_.is_null()) { |
| 1373 CompletionCallback c = user_connect_callback_; | 1373 CompletionCallback c = user_connect_callback_; |
| 1374 user_connect_callback_.Reset(); | 1374 user_connect_callback_.Reset(); |
| 1375 c.Run(rv > OK ? OK : rv); | 1375 c.Run(rv > OK ? OK : rv); |
| 1376 } | 1376 } |
| 1377 } | 1377 } |
| 1378 | 1378 |
| 1379 void SSLClientSocketImpl::UpdateServerCert() { | 1379 void SSLClientSocketImpl::UpdateServerCert() { |
| 1380 server_cert_chain_->Reset(SSL_get_peer_cert_chain(ssl_)); | 1380 server_cert_chain_->Reset(SSL_get_peer_cert_chain(ssl_)); |
| 1381 server_cert_ = server_cert_chain_->AsOSChain(); | 1381 server_cert_ = server_cert_chain_->AsOSChain(); |
| 1382 if (server_cert_.get()) { | 1382 if (server_cert_.get()) { |
| 1383 net_log_.AddEvent(NetLog::TYPE_SSL_CERTIFICATES_RECEIVED, | 1383 net_log_.AddEvent(NetLog::TYPE_SSL_CERTIFICATES_RECEIVED, |
| 1384 base::Bind(&NetLogX509CertificateCallback, | 1384 base::Bind(&NetLogX509CertificateCallback, |
| 1385 base::Unretained(server_cert_.get()))); | 1385 base::Unretained(server_cert_.get()))); |
| 1386 } | 1386 } |
| 1387 } | 1387 } |
| 1388 | 1388 |
| 1389 void SSLClientSocketImpl::VerifyCT() { | |
| 1390 const uint8_t* ocsp_response_raw; | |
| 1391 size_t ocsp_response_len; | |
| 1392 SSL_get0_ocsp_response(ssl_, &ocsp_response_raw, &ocsp_response_len); | |
| 1393 std::string ocsp_response; | |
| 1394 if (ocsp_response_len > 0) { | |
| 1395 ocsp_response.assign(reinterpret_cast<const char*>(ocsp_response_raw), | |
| 1396 ocsp_response_len); | |
| 1397 } | |
| 1398 | |
| 1399 const uint8_t* sct_list_raw; | |
| 1400 size_t sct_list_len; | |
| 1401 SSL_get0_signed_cert_timestamp_list(ssl_, &sct_list_raw, &sct_list_len); | |
| 1402 std::string sct_list; | |
| 1403 if (sct_list_len > 0) | |
| 1404 sct_list.assign(reinterpret_cast<const char*>(sct_list_raw), sct_list_len); | |
| 1405 | |
| 1406 // Note that this is a completely synchronous operation: The CT Log Verifier | |
| 1407 // gets all the data it needs for SCT verification and does not do any | |
| 1408 // external communication. | |
| 1409 cert_transparency_verifier_->Verify( | |
| 1410 server_cert_verify_result_.verified_cert.get(), ocsp_response, sct_list, | |
| 1411 &ct_verify_result_, net_log_); | |
| 1412 | |
| 1413 ct_verify_result_.ct_policies_applied = true; | |
| 1414 ct_verify_result_.ev_policy_compliance = | |
| 1415 ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY; | |
| 1416 if (server_cert_verify_result_.cert_status & CERT_STATUS_IS_EV) { | |
| 1417 scoped_refptr<ct::EVCertsWhitelist> ev_whitelist = | |
| 1418 SSLConfigService::GetEVCertsWhitelist(); | |
| 1419 ct::EVPolicyCompliance ev_policy_compliance = | |
| 1420 policy_enforcer_->DoesConformToCTEVPolicy( | |
| 1421 server_cert_verify_result_.verified_cert.get(), ev_whitelist.get(), | |
| 1422 ct_verify_result_.verified_scts, net_log_); | |
| 1423 ct_verify_result_.ev_policy_compliance = ev_policy_compliance; | |
| 1424 if (ev_policy_compliance != | |
| 1425 ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY && | |
| 1426 ev_policy_compliance != | |
| 1427 ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_WHITELIST && | |
| 1428 ev_policy_compliance != | |
| 1429 ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS) { | |
| 1430 server_cert_verify_result_.cert_status |= | |
| 1431 CERT_STATUS_CT_COMPLIANCE_FAILED; | |
| 1432 server_cert_verify_result_.cert_status &= ~CERT_STATUS_IS_EV; | |
| 1433 } | |
| 1434 } | |
| 1435 ct_verify_result_.cert_policy_compliance = | |
| 1436 policy_enforcer_->DoesConformToCertPolicy( | |
| 1437 server_cert_verify_result_.verified_cert.get(), | |
| 1438 ct_verify_result_.verified_scts, net_log_); | |
| 1439 } | |
| 1440 | |
| 1441 void SSLClientSocketImpl::OnHandshakeIOComplete(int result) { | 1389 void SSLClientSocketImpl::OnHandshakeIOComplete(int result) { |
| 1442 int rv = DoHandshakeLoop(result); | 1390 int rv = DoHandshakeLoop(result); |
| 1443 if (rv != ERR_IO_PENDING) { | 1391 if (rv != ERR_IO_PENDING) { |
| 1444 LogConnectEndEvent(rv); | 1392 LogConnectEndEvent(rv); |
| 1445 DoConnectCallback(rv); | 1393 DoConnectCallback(rv); |
| 1446 } | 1394 } |
| 1447 } | 1395 } |
| 1448 | 1396 |
| 1449 void SSLClientSocketImpl::OnSendComplete(int result) { | 1397 void SSLClientSocketImpl::OnSendComplete(int result) { |
| 1450 if (next_handshake_state_ == STATE_HANDSHAKE) { | 1398 if (next_handshake_state_ == STATE_HANDSHAKE) { |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1819 } else { | 1767 } else { |
| 1820 bytes_read = result; | 1768 bytes_read = result; |
| 1821 } | 1769 } |
| 1822 DCHECK_GE(recv_buffer_->RemainingCapacity(), bytes_read); | 1770 DCHECK_GE(recv_buffer_->RemainingCapacity(), bytes_read); |
| 1823 int ret = BIO_zero_copy_get_write_buf_done(transport_bio_, bytes_read); | 1771 int ret = BIO_zero_copy_get_write_buf_done(transport_bio_, bytes_read); |
| 1824 DCHECK_EQ(1, ret); | 1772 DCHECK_EQ(1, ret); |
| 1825 transport_recv_busy_ = false; | 1773 transport_recv_busy_ = false; |
| 1826 return result; | 1774 return result; |
| 1827 } | 1775 } |
| 1828 | 1776 |
| 1777 int SSLClientSocketImpl::VerifyCT() { |
| 1778 const uint8_t* ocsp_response_raw; |
| 1779 size_t ocsp_response_len; |
| 1780 SSL_get0_ocsp_response(ssl_, &ocsp_response_raw, &ocsp_response_len); |
| 1781 std::string ocsp_response; |
| 1782 if (ocsp_response_len > 0) { |
| 1783 ocsp_response.assign(reinterpret_cast<const char*>(ocsp_response_raw), |
| 1784 ocsp_response_len); |
| 1785 } |
| 1786 |
| 1787 const uint8_t* sct_list_raw; |
| 1788 size_t sct_list_len; |
| 1789 SSL_get0_signed_cert_timestamp_list(ssl_, &sct_list_raw, &sct_list_len); |
| 1790 std::string sct_list; |
| 1791 if (sct_list_len > 0) |
| 1792 sct_list.assign(reinterpret_cast<const char*>(sct_list_raw), sct_list_len); |
| 1793 |
| 1794 // Note that this is a completely synchronous operation: The CT Log Verifier |
| 1795 // gets all the data it needs for SCT verification and does not do any |
| 1796 // external communication. |
| 1797 cert_transparency_verifier_->Verify( |
| 1798 server_cert_verify_result_.verified_cert.get(), ocsp_response, sct_list, |
| 1799 &ct_verify_result_, net_log_); |
| 1800 |
| 1801 ct_verify_result_.ct_policies_applied = true; |
| 1802 ct_verify_result_.ev_policy_compliance = |
| 1803 ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY; |
| 1804 if (server_cert_verify_result_.cert_status & CERT_STATUS_IS_EV) { |
| 1805 scoped_refptr<ct::EVCertsWhitelist> ev_whitelist = |
| 1806 SSLConfigService::GetEVCertsWhitelist(); |
| 1807 ct::EVPolicyCompliance ev_policy_compliance = |
| 1808 policy_enforcer_->DoesConformToCTEVPolicy( |
| 1809 server_cert_verify_result_.verified_cert.get(), ev_whitelist.get(), |
| 1810 ct_verify_result_.verified_scts, net_log_); |
| 1811 ct_verify_result_.ev_policy_compliance = ev_policy_compliance; |
| 1812 if (ev_policy_compliance != |
| 1813 ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY && |
| 1814 ev_policy_compliance != |
| 1815 ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_WHITELIST && |
| 1816 ev_policy_compliance != |
| 1817 ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS) { |
| 1818 server_cert_verify_result_.cert_status |= |
| 1819 CERT_STATUS_CT_COMPLIANCE_FAILED; |
| 1820 server_cert_verify_result_.cert_status &= ~CERT_STATUS_IS_EV; |
| 1821 } |
| 1822 } |
| 1823 ct_verify_result_.cert_policy_compliance = |
| 1824 policy_enforcer_->DoesConformToCertPolicy( |
| 1825 server_cert_verify_result_.verified_cert.get(), |
| 1826 ct_verify_result_.verified_scts, net_log_); |
| 1827 |
| 1828 if (ct_verify_result_.cert_policy_compliance != |
| 1829 ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS && |
| 1830 transport_security_state_->ShouldRequireCT( |
| 1831 host_and_port_.host(), server_cert_verify_result_.verified_cert.get(), |
| 1832 server_cert_verify_result_.public_key_hashes)) { |
| 1833 server_cert_verify_result_.cert_status |= |
| 1834 CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED; |
| 1835 return ERR_CERTIFICATE_TRANSPARENCY_REQUIRED; |
| 1836 } |
| 1837 |
| 1838 return OK; |
| 1839 } |
| 1840 |
| 1829 int SSLClientSocketImpl::ClientCertRequestCallback(SSL* ssl) { | 1841 int SSLClientSocketImpl::ClientCertRequestCallback(SSL* ssl) { |
| 1830 DCHECK(ssl == ssl_); | 1842 DCHECK(ssl == ssl_); |
| 1831 | 1843 |
| 1832 net_log_.AddEvent(NetLog::TYPE_SSL_CLIENT_CERT_REQUESTED); | 1844 net_log_.AddEvent(NetLog::TYPE_SSL_CLIENT_CERT_REQUESTED); |
| 1833 | 1845 |
| 1834 // Clear any currently configured certificates. | 1846 // Clear any currently configured certificates. |
| 1835 SSL_certs_clear(ssl_); | 1847 SSL_certs_clear(ssl_); |
| 1836 | 1848 |
| 1837 #if defined(OS_IOS) | 1849 #if defined(OS_IOS) |
| 1838 // TODO(droger): Support client auth on iOS. See http://crbug.com/145954). | 1850 // TODO(droger): Support client auth on iOS. See http://crbug.com/145954). |
| (...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2313 if (rv != OK) { | 2325 if (rv != OK) { |
| 2314 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv); | 2326 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv); |
| 2315 return; | 2327 return; |
| 2316 } | 2328 } |
| 2317 | 2329 |
| 2318 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, | 2330 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, |
| 2319 base::Bind(&NetLogSSLInfoCallback, base::Unretained(this))); | 2331 base::Bind(&NetLogSSLInfoCallback, base::Unretained(this))); |
| 2320 } | 2332 } |
| 2321 | 2333 |
| 2322 } // namespace net | 2334 } // namespace net |
| OLD | NEW |