Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(703)

Side by Side Diff: net/socket/ssl_client_socket_impl.cc

Issue 2076363002: Introduce the ability to require CT for specific hosts (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@require_ct_enforcer
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 ((result == OK || 1333 if ((result == OK ||
1332 (IsCertificateError(result) && IsCertStatusMinorError(cert_status))) && 1334 (IsCertificateError(result) && IsCertStatusMinorError(cert_status)))) {
1333 !transport_security_state_->CheckPublicKeyPins( 1335 int ct_result = VerifyCT();
1334 host_and_port_, server_cert_verify_result_.is_issued_by_known_root, 1336 if (!transport_security_state_->CheckPublicKeyPins(
1335 server_cert_verify_result_.public_key_hashes, server_cert_.get(), 1337 host_and_port_, server_cert_verify_result_.is_issued_by_known_root,
1336 server_cert_verify_result_.verified_cert.get(), 1338 server_cert_verify_result_.public_key_hashes, server_cert_.get(),
1337 TransportSecurityState::ENABLE_PIN_REPORTS, &pinning_failure_log_)) { 1339 server_cert_verify_result_.verified_cert.get(),
1338 if (server_cert_verify_result_.is_issued_by_known_root) 1340 TransportSecurityState::ENABLE_PIN_REPORTS,
1339 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; 1341 &pinning_failure_log_)) {
1340 else 1342 if (server_cert_verify_result_.is_issued_by_known_root)
1341 pkp_bypassed_ = true; 1343 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN;
1344 else
1345 pkp_bypassed_ = true;
1346 }
1347 if (result != ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN && ct_result != OK)
1348 result = ct_result;
1342 } 1349 }
1343 1350
1344 if (result == OK) { 1351 if (result == OK) {
1345 // Only check Certificate Transparency if there were no other errors with
1346 // the connection.
1347 VerifyCT();
1348
1349 DCHECK(!certificate_verified_); 1352 DCHECK(!certificate_verified_);
1350 certificate_verified_ = true; 1353 certificate_verified_ = true;
1351 MaybeCacheSession(); 1354 MaybeCacheSession();
1352 } 1355 }
1353 1356
1354 completed_connect_ = true; 1357 completed_connect_ = true;
1355 // Exit DoHandshakeLoop and return the result to the caller to Connect. 1358 // Exit DoHandshakeLoop and return the result to the caller to Connect.
1356 DCHECK_EQ(STATE_NONE, next_handshake_state_); 1359 DCHECK_EQ(STATE_NONE, next_handshake_state_);
1357 return result; 1360 return result;
1358 } 1361 }
1359 1362
1360 void SSLClientSocketImpl::DoConnectCallback(int rv) { 1363 void SSLClientSocketImpl::DoConnectCallback(int rv) {
1361 if (!user_connect_callback_.is_null()) { 1364 if (!user_connect_callback_.is_null()) {
1362 CompletionCallback c = user_connect_callback_; 1365 CompletionCallback c = user_connect_callback_;
1363 user_connect_callback_.Reset(); 1366 user_connect_callback_.Reset();
1364 c.Run(rv > OK ? OK : rv); 1367 c.Run(rv > OK ? OK : rv);
1365 } 1368 }
1366 } 1369 }
1367 1370
1368 void SSLClientSocketImpl::UpdateServerCert() { 1371 void SSLClientSocketImpl::UpdateServerCert() {
1369 server_cert_chain_->Reset(SSL_get_peer_cert_chain(ssl_)); 1372 server_cert_chain_->Reset(SSL_get_peer_cert_chain(ssl_));
1370 server_cert_ = server_cert_chain_->AsOSChain(); 1373 server_cert_ = server_cert_chain_->AsOSChain();
1371 if (server_cert_.get()) { 1374 if (server_cert_.get()) {
1372 net_log_.AddEvent(NetLog::TYPE_SSL_CERTIFICATES_RECEIVED, 1375 net_log_.AddEvent(NetLog::TYPE_SSL_CERTIFICATES_RECEIVED,
1373 base::Bind(&NetLogX509CertificateCallback, 1376 base::Bind(&NetLogX509CertificateCallback,
1374 base::Unretained(server_cert_.get()))); 1377 base::Unretained(server_cert_.get())));
1375 } 1378 }
1376 } 1379 }
1377 1380
1378 void SSLClientSocketImpl::VerifyCT() {
1379 const uint8_t* ocsp_response_raw;
1380 size_t ocsp_response_len;
1381 SSL_get0_ocsp_response(ssl_, &ocsp_response_raw, &ocsp_response_len);
1382 std::string ocsp_response;
1383 if (ocsp_response_len > 0) {
1384 ocsp_response.assign(reinterpret_cast<const char*>(ocsp_response_raw),
1385 ocsp_response_len);
1386 }
1387
1388 const uint8_t* sct_list_raw;
1389 size_t sct_list_len;
1390 SSL_get0_signed_cert_timestamp_list(ssl_, &sct_list_raw, &sct_list_len);
1391 std::string sct_list;
1392 if (sct_list_len > 0)
1393 sct_list.assign(reinterpret_cast<const char*>(sct_list_raw), sct_list_len);
1394
1395 // Note that this is a completely synchronous operation: The CT Log Verifier
1396 // gets all the data it needs for SCT verification and does not do any
1397 // external communication.
1398 cert_transparency_verifier_->Verify(
1399 server_cert_verify_result_.verified_cert.get(), ocsp_response, sct_list,
1400 &ct_verify_result_, net_log_);
1401
1402 ct_verify_result_.ct_policies_applied = true;
1403 ct_verify_result_.ev_policy_compliance =
1404 ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY;
1405 if (server_cert_verify_result_.cert_status & CERT_STATUS_IS_EV) {
1406 scoped_refptr<ct::EVCertsWhitelist> ev_whitelist =
1407 SSLConfigService::GetEVCertsWhitelist();
1408 ct::EVPolicyCompliance ev_policy_compliance =
1409 policy_enforcer_->DoesConformToCTEVPolicy(
1410 server_cert_verify_result_.verified_cert.get(), ev_whitelist.get(),
1411 ct_verify_result_.verified_scts, net_log_);
1412 ct_verify_result_.ev_policy_compliance = ev_policy_compliance;
1413 if (ev_policy_compliance !=
1414 ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY &&
1415 ev_policy_compliance !=
1416 ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_WHITELIST &&
1417 ev_policy_compliance !=
1418 ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS) {
1419 server_cert_verify_result_.cert_status |=
1420 CERT_STATUS_CT_COMPLIANCE_FAILED;
1421 server_cert_verify_result_.cert_status &= ~CERT_STATUS_IS_EV;
1422 }
1423 }
1424 ct_verify_result_.cert_policy_compliance =
1425 policy_enforcer_->DoesConformToCertPolicy(
1426 server_cert_verify_result_.verified_cert.get(),
1427 ct_verify_result_.verified_scts, net_log_);
1428 }
1429
1430 void SSLClientSocketImpl::OnHandshakeIOComplete(int result) { 1381 void SSLClientSocketImpl::OnHandshakeIOComplete(int result) {
1431 int rv = DoHandshakeLoop(result); 1382 int rv = DoHandshakeLoop(result);
1432 if (rv != ERR_IO_PENDING) { 1383 if (rv != ERR_IO_PENDING) {
1433 LogConnectEndEvent(rv); 1384 LogConnectEndEvent(rv);
1434 DoConnectCallback(rv); 1385 DoConnectCallback(rv);
1435 } 1386 }
1436 } 1387 }
1437 1388
1438 void SSLClientSocketImpl::OnSendComplete(int result) { 1389 void SSLClientSocketImpl::OnSendComplete(int result) {
1439 if (next_handshake_state_ == STATE_HANDSHAKE) { 1390 if (next_handshake_state_ == STATE_HANDSHAKE) {
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
1808 } else { 1759 } else {
1809 bytes_read = result; 1760 bytes_read = result;
1810 } 1761 }
1811 DCHECK_GE(recv_buffer_->RemainingCapacity(), bytes_read); 1762 DCHECK_GE(recv_buffer_->RemainingCapacity(), bytes_read);
1812 int ret = BIO_zero_copy_get_write_buf_done(transport_bio_, bytes_read); 1763 int ret = BIO_zero_copy_get_write_buf_done(transport_bio_, bytes_read);
1813 DCHECK_EQ(1, ret); 1764 DCHECK_EQ(1, ret);
1814 transport_recv_busy_ = false; 1765 transport_recv_busy_ = false;
1815 return result; 1766 return result;
1816 } 1767 }
1817 1768
1769 int SSLClientSocketImpl::VerifyCT() {
1770 const uint8_t* ocsp_response_raw;
1771 size_t ocsp_response_len;
1772 SSL_get0_ocsp_response(ssl_, &ocsp_response_raw, &ocsp_response_len);
1773 std::string ocsp_response;
1774 if (ocsp_response_len > 0) {
1775 ocsp_response.assign(reinterpret_cast<const char*>(ocsp_response_raw),
1776 ocsp_response_len);
1777 }
1778
1779 const uint8_t* sct_list_raw;
1780 size_t sct_list_len;
1781 SSL_get0_signed_cert_timestamp_list(ssl_, &sct_list_raw, &sct_list_len);
1782 std::string sct_list;
1783 if (sct_list_len > 0)
1784 sct_list.assign(reinterpret_cast<const char*>(sct_list_raw), sct_list_len);
1785
1786 // Note that this is a completely synchronous operation: The CT Log Verifier
1787 // gets all the data it needs for SCT verification and does not do any
1788 // external communication.
1789 cert_transparency_verifier_->Verify(
1790 server_cert_verify_result_.verified_cert.get(), ocsp_response, sct_list,
1791 &ct_verify_result_, net_log_);
1792
1793 ct_verify_result_.ct_policies_applied = true;
1794 ct_verify_result_.ev_policy_compliance =
1795 ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY;
1796 if (server_cert_verify_result_.cert_status & CERT_STATUS_IS_EV) {
1797 scoped_refptr<ct::EVCertsWhitelist> ev_whitelist =
1798 SSLConfigService::GetEVCertsWhitelist();
1799 ct::EVPolicyCompliance ev_policy_compliance =
1800 policy_enforcer_->DoesConformToCTEVPolicy(
1801 server_cert_verify_result_.verified_cert.get(), ev_whitelist.get(),
1802 ct_verify_result_.verified_scts, net_log_);
1803 ct_verify_result_.ev_policy_compliance = ev_policy_compliance;
1804 if (ev_policy_compliance !=
1805 ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY &&
1806 ev_policy_compliance !=
1807 ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_WHITELIST &&
1808 ev_policy_compliance !=
1809 ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS) {
1810 server_cert_verify_result_.cert_status |=
1811 CERT_STATUS_CT_COMPLIANCE_FAILED;
1812 server_cert_verify_result_.cert_status &= ~CERT_STATUS_IS_EV;
1813 }
1814 }
1815 ct_verify_result_.cert_policy_compliance =
1816 policy_enforcer_->DoesConformToCertPolicy(
1817 server_cert_verify_result_.verified_cert.get(),
1818 ct_verify_result_.verified_scts, net_log_);
1819
1820 if (ct_verify_result_.cert_policy_compliance !=
1821 ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS &&
1822 transport_security_state_->ShouldRequireCT(
1823 host_and_port_.host(), server_cert_verify_result_.verified_cert.get(),
1824 server_cert_verify_result_.public_key_hashes)) {
1825 return ERR_SSL_CERTIFICATE_TRANSPARENCY_REQUIRED;
1826 }
1827
1828 return OK;
1829 }
1830
1818 int SSLClientSocketImpl::ClientCertRequestCallback(SSL* ssl) { 1831 int SSLClientSocketImpl::ClientCertRequestCallback(SSL* ssl) {
1819 DCHECK(ssl == ssl_); 1832 DCHECK(ssl == ssl_);
1820 1833
1821 net_log_.AddEvent(NetLog::TYPE_SSL_CLIENT_CERT_REQUESTED); 1834 net_log_.AddEvent(NetLog::TYPE_SSL_CLIENT_CERT_REQUESTED);
1822 1835
1823 // Clear any currently configured certificates. 1836 // Clear any currently configured certificates.
1824 SSL_certs_clear(ssl_); 1837 SSL_certs_clear(ssl_);
1825 1838
1826 #if defined(OS_IOS) 1839 #if defined(OS_IOS)
1827 // TODO(droger): Support client auth on iOS. See http://crbug.com/145954). 1840 // TODO(droger): Support client auth on iOS. See http://crbug.com/145954).
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
2302 if (rv != OK) { 2315 if (rv != OK) {
2303 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv); 2316 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv);
2304 return; 2317 return;
2305 } 2318 }
2306 2319
2307 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, 2320 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT,
2308 base::Bind(&NetLogSSLInfoCallback, base::Unretained(this))); 2321 base::Bind(&NetLogSSLInfoCallback, base::Unretained(this)));
2309 } 2322 }
2310 2323
2311 } // namespace net 2324 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698