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

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

Issue 2067843003: Require a CTVerifier and CTPolicyEnforcer for TLS/QUIC sockets (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
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 512 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698