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

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: Move some cleanups out 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
« no previous file with comments | « net/socket/ssl_client_socket_impl.h ('k') | net/spdy/spdy_session.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 server_cert_verify_result_.cert_status |= CERT_STATUS_PINNED_KEY_MISSING; 1341 &pinning_failure_log_)) {
1340 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; 1342 if (server_cert_verify_result_.is_issued_by_known_root) {
1341 } else { 1343 server_cert_verify_result_.cert_status |=
1342 pkp_bypassed_ = true; 1344 CERT_STATUS_PINNED_KEY_MISSING;
1345 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN;
1346 } else {
1347 pkp_bypassed_ = true;
1348 }
1343 } 1349 }
1350 if (result != ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN && ct_result != OK)
1351 result = ct_result;
1344 } 1352 }
1345 1353
1346 if (result == OK) { 1354 if (result == OK) {
1347 // Only check Certificate Transparency if there were no other errors with
1348 // the connection.
1349 VerifyCT();
1350
1351 DCHECK(!certificate_verified_); 1355 DCHECK(!certificate_verified_);
1352 certificate_verified_ = true; 1356 certificate_verified_ = true;
1353 MaybeCacheSession(); 1357 MaybeCacheSession();
1354 } 1358 }
1355 1359
1356 completed_connect_ = true; 1360 completed_connect_ = true;
1357 // Exit DoHandshakeLoop and return the result to the caller to Connect. 1361 // Exit DoHandshakeLoop and return the result to the caller to Connect.
1358 DCHECK_EQ(STATE_NONE, next_handshake_state_); 1362 DCHECK_EQ(STATE_NONE, next_handshake_state_);
1359 return result; 1363 return result;
1360 } 1364 }
1361 1365
1362 void SSLClientSocketImpl::DoConnectCallback(int rv) { 1366 void SSLClientSocketImpl::DoConnectCallback(int rv) {
1363 if (!user_connect_callback_.is_null()) { 1367 if (!user_connect_callback_.is_null()) {
1364 CompletionCallback c = user_connect_callback_; 1368 CompletionCallback c = user_connect_callback_;
1365 user_connect_callback_.Reset(); 1369 user_connect_callback_.Reset();
1366 c.Run(rv > OK ? OK : rv); 1370 c.Run(rv > OK ? OK : rv);
1367 } 1371 }
1368 } 1372 }
1369 1373
1370 void SSLClientSocketImpl::UpdateServerCert() { 1374 void SSLClientSocketImpl::UpdateServerCert() {
1371 server_cert_chain_->Reset(SSL_get_peer_cert_chain(ssl_)); 1375 server_cert_chain_->Reset(SSL_get_peer_cert_chain(ssl_));
1372 server_cert_ = server_cert_chain_->AsOSChain(); 1376 server_cert_ = server_cert_chain_->AsOSChain();
1373 if (server_cert_.get()) { 1377 if (server_cert_.get()) {
1374 net_log_.AddEvent(NetLog::TYPE_SSL_CERTIFICATES_RECEIVED, 1378 net_log_.AddEvent(NetLog::TYPE_SSL_CERTIFICATES_RECEIVED,
1375 base::Bind(&NetLogX509CertificateCallback, 1379 base::Bind(&NetLogX509CertificateCallback,
1376 base::Unretained(server_cert_.get()))); 1380 base::Unretained(server_cert_.get())));
1377 } 1381 }
1378 } 1382 }
1379 1383
1380 void SSLClientSocketImpl::VerifyCT() {
1381 const uint8_t* ocsp_response_raw;
1382 size_t ocsp_response_len;
1383 SSL_get0_ocsp_response(ssl_, &ocsp_response_raw, &ocsp_response_len);
1384 std::string ocsp_response;
1385 if (ocsp_response_len > 0) {
1386 ocsp_response.assign(reinterpret_cast<const char*>(ocsp_response_raw),
1387 ocsp_response_len);
1388 }
1389
1390 const uint8_t* sct_list_raw;
1391 size_t sct_list_len;
1392 SSL_get0_signed_cert_timestamp_list(ssl_, &sct_list_raw, &sct_list_len);
1393 std::string sct_list;
1394 if (sct_list_len > 0)
1395 sct_list.assign(reinterpret_cast<const char*>(sct_list_raw), sct_list_len);
1396
1397 // Note that this is a completely synchronous operation: The CT Log Verifier
1398 // gets all the data it needs for SCT verification and does not do any
1399 // external communication.
1400 cert_transparency_verifier_->Verify(
1401 server_cert_verify_result_.verified_cert.get(), ocsp_response, sct_list,
1402 &ct_verify_result_, net_log_);
1403
1404 ct_verify_result_.ct_policies_applied = true;
1405 ct_verify_result_.ev_policy_compliance =
1406 ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY;
1407 if (server_cert_verify_result_.cert_status & CERT_STATUS_IS_EV) {
1408 scoped_refptr<ct::EVCertsWhitelist> ev_whitelist =
1409 SSLConfigService::GetEVCertsWhitelist();
1410 ct::EVPolicyCompliance ev_policy_compliance =
1411 policy_enforcer_->DoesConformToCTEVPolicy(
1412 server_cert_verify_result_.verified_cert.get(), ev_whitelist.get(),
1413 ct_verify_result_.verified_scts, net_log_);
1414 ct_verify_result_.ev_policy_compliance = ev_policy_compliance;
1415 if (ev_policy_compliance !=
1416 ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY &&
1417 ev_policy_compliance !=
1418 ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_WHITELIST &&
1419 ev_policy_compliance !=
1420 ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS) {
1421 server_cert_verify_result_.cert_status |=
1422 CERT_STATUS_CT_COMPLIANCE_FAILED;
1423 server_cert_verify_result_.cert_status &= ~CERT_STATUS_IS_EV;
1424 }
1425 }
1426 ct_verify_result_.cert_policy_compliance =
1427 policy_enforcer_->DoesConformToCertPolicy(
1428 server_cert_verify_result_.verified_cert.get(),
1429 ct_verify_result_.verified_scts, net_log_);
1430 }
1431
1432 void SSLClientSocketImpl::OnHandshakeIOComplete(int result) { 1384 void SSLClientSocketImpl::OnHandshakeIOComplete(int result) {
1433 int rv = DoHandshakeLoop(result); 1385 int rv = DoHandshakeLoop(result);
1434 if (rv != ERR_IO_PENDING) { 1386 if (rv != ERR_IO_PENDING) {
1435 LogConnectEndEvent(rv); 1387 LogConnectEndEvent(rv);
1436 DoConnectCallback(rv); 1388 DoConnectCallback(rv);
1437 } 1389 }
1438 } 1390 }
1439 1391
1440 void SSLClientSocketImpl::OnSendComplete(int result) { 1392 void SSLClientSocketImpl::OnSendComplete(int result) {
1441 if (next_handshake_state_ == STATE_HANDSHAKE) { 1393 if (next_handshake_state_ == STATE_HANDSHAKE) {
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
1810 } else { 1762 } else {
1811 bytes_read = result; 1763 bytes_read = result;
1812 } 1764 }
1813 DCHECK_GE(recv_buffer_->RemainingCapacity(), bytes_read); 1765 DCHECK_GE(recv_buffer_->RemainingCapacity(), bytes_read);
1814 int ret = BIO_zero_copy_get_write_buf_done(transport_bio_, bytes_read); 1766 int ret = BIO_zero_copy_get_write_buf_done(transport_bio_, bytes_read);
1815 DCHECK_EQ(1, ret); 1767 DCHECK_EQ(1, ret);
1816 transport_recv_busy_ = false; 1768 transport_recv_busy_ = false;
1817 return result; 1769 return result;
1818 } 1770 }
1819 1771
1772 int SSLClientSocketImpl::VerifyCT() {
1773 const uint8_t* ocsp_response_raw;
1774 size_t ocsp_response_len;
1775 SSL_get0_ocsp_response(ssl_, &ocsp_response_raw, &ocsp_response_len);
1776 std::string ocsp_response;
1777 if (ocsp_response_len > 0) {
1778 ocsp_response.assign(reinterpret_cast<const char*>(ocsp_response_raw),
1779 ocsp_response_len);
1780 }
1781
1782 const uint8_t* sct_list_raw;
1783 size_t sct_list_len;
1784 SSL_get0_signed_cert_timestamp_list(ssl_, &sct_list_raw, &sct_list_len);
1785 std::string sct_list;
1786 if (sct_list_len > 0)
1787 sct_list.assign(reinterpret_cast<const char*>(sct_list_raw), sct_list_len);
1788
1789 // Note that this is a completely synchronous operation: The CT Log Verifier
1790 // gets all the data it needs for SCT verification and does not do any
1791 // external communication.
1792 cert_transparency_verifier_->Verify(
1793 server_cert_verify_result_.verified_cert.get(), ocsp_response, sct_list,
1794 &ct_verify_result_, net_log_);
1795
1796 ct_verify_result_.ct_policies_applied = true;
1797 ct_verify_result_.ev_policy_compliance =
1798 ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY;
1799 if (server_cert_verify_result_.cert_status & CERT_STATUS_IS_EV) {
1800 scoped_refptr<ct::EVCertsWhitelist> ev_whitelist =
1801 SSLConfigService::GetEVCertsWhitelist();
1802 ct::EVPolicyCompliance ev_policy_compliance =
1803 policy_enforcer_->DoesConformToCTEVPolicy(
1804 server_cert_verify_result_.verified_cert.get(), ev_whitelist.get(),
1805 ct_verify_result_.verified_scts, net_log_);
1806 ct_verify_result_.ev_policy_compliance = ev_policy_compliance;
1807 if (ev_policy_compliance !=
1808 ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY &&
1809 ev_policy_compliance !=
1810 ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_WHITELIST &&
1811 ev_policy_compliance !=
1812 ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS) {
1813 server_cert_verify_result_.cert_status |=
1814 CERT_STATUS_CT_COMPLIANCE_FAILED;
1815 server_cert_verify_result_.cert_status &= ~CERT_STATUS_IS_EV;
1816 }
1817 }
1818 ct_verify_result_.cert_policy_compliance =
1819 policy_enforcer_->DoesConformToCertPolicy(
1820 server_cert_verify_result_.verified_cert.get(),
1821 ct_verify_result_.verified_scts, net_log_);
1822
1823 if (ct_verify_result_.cert_policy_compliance !=
Ryan Sleevi 2016/06/21 00:09:33 I know moving around can be a pain, sorry about th
1824 ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS &&
1825 transport_security_state_->ShouldRequireCT(
1826 host_and_port_.host(), server_cert_verify_result_.verified_cert.get(),
1827 server_cert_verify_result_.public_key_hashes)) {
1828 server_cert_verify_result_.cert_status |=
1829 CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED;
1830 return ERR_CERTIFICATE_TRANSPARENCY_REQUIRED;
1831 }
1832
1833 return OK;
1834 }
1835
1820 int SSLClientSocketImpl::ClientCertRequestCallback(SSL* ssl) { 1836 int SSLClientSocketImpl::ClientCertRequestCallback(SSL* ssl) {
1821 DCHECK(ssl == ssl_); 1837 DCHECK(ssl == ssl_);
1822 1838
1823 net_log_.AddEvent(NetLog::TYPE_SSL_CLIENT_CERT_REQUESTED); 1839 net_log_.AddEvent(NetLog::TYPE_SSL_CLIENT_CERT_REQUESTED);
1824 1840
1825 // Clear any currently configured certificates. 1841 // Clear any currently configured certificates.
1826 SSL_certs_clear(ssl_); 1842 SSL_certs_clear(ssl_);
1827 1843
1828 #if defined(OS_IOS) 1844 #if defined(OS_IOS)
1829 // TODO(droger): Support client auth on iOS. See http://crbug.com/145954). 1845 // TODO(droger): Support client auth on iOS. See http://crbug.com/145954).
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
2304 if (rv != OK) { 2320 if (rv != OK) {
2305 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv); 2321 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv);
2306 return; 2322 return;
2307 } 2323 }
2308 2324
2309 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, 2325 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT,
2310 base::Bind(&NetLogSSLInfoCallback, base::Unretained(this))); 2326 base::Bind(&NetLogSSLInfoCallback, base::Unretained(this)));
2311 } 2327 }
2312 2328
2313 } // namespace net 2329 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/ssl_client_socket_impl.h ('k') | net/spdy/spdy_session.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698