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

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

Issue 2350483002: Improve error pages on client certificate failures. (Closed)
Patch Set: curly quotes Created 4 years, 2 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/socket/ssl_client_socket_unittest.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 481 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 transport_bio_(NULL), 492 transport_bio_(NULL),
493 transport_(std::move(transport_socket)), 493 transport_(std::move(transport_socket)),
494 host_and_port_(host_and_port), 494 host_and_port_(host_and_port),
495 ssl_config_(ssl_config), 495 ssl_config_(ssl_config),
496 ssl_session_cache_shard_(context.ssl_session_cache_shard), 496 ssl_session_cache_shard_(context.ssl_session_cache_shard),
497 next_handshake_state_(STATE_NONE), 497 next_handshake_state_(STATE_NONE),
498 disconnected_(false), 498 disconnected_(false),
499 negotiated_protocol_(kProtoUnknown), 499 negotiated_protocol_(kProtoUnknown),
500 channel_id_sent_(false), 500 channel_id_sent_(false),
501 certificate_verified_(false), 501 certificate_verified_(false),
502 certificate_requested_(false),
502 signature_result_(kNoPendingResult), 503 signature_result_(kNoPendingResult),
503 transport_security_state_(context.transport_security_state), 504 transport_security_state_(context.transport_security_state),
504 policy_enforcer_(context.ct_policy_enforcer), 505 policy_enforcer_(context.ct_policy_enforcer),
505 pkp_bypassed_(false), 506 pkp_bypassed_(false),
506 net_log_(transport_->socket()->NetLog()), 507 net_log_(transport_->socket()->NetLog()),
507 weak_factory_(this) { 508 weak_factory_(this) {
508 CHECK(cert_verifier_); 509 CHECK(cert_verifier_);
509 CHECK(transport_security_state_); 510 CHECK(transport_security_state_);
510 CHECK(cert_transparency_verifier_); 511 CHECK(cert_transparency_verifier_);
511 CHECK(policy_enforcer_); 512 CHECK(policy_enforcer_);
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 cert_key_types_.clear(); 674 cert_key_types_.clear();
674 675
675 start_cert_verification_time_ = base::TimeTicks(); 676 start_cert_verification_time_ = base::TimeTicks();
676 677
677 negotiated_protocol_ = kProtoUnknown; 678 negotiated_protocol_ = kProtoUnknown;
678 679
679 channel_id_sent_ = false; 680 channel_id_sent_ = false;
680 tb_was_negotiated_ = false; 681 tb_was_negotiated_ = false;
681 pending_session_ = nullptr; 682 pending_session_ = nullptr;
682 certificate_verified_ = false; 683 certificate_verified_ = false;
684 certificate_requested_ = false;
683 channel_id_request_.Cancel(); 685 channel_id_request_.Cancel();
684 686
685 signature_result_ = kNoPendingResult; 687 signature_result_ = kNoPendingResult;
686 signature_.clear(); 688 signature_.clear();
687 } 689 }
688 690
689 bool SSLClientSocketImpl::IsConnected() const { 691 bool SSLClientSocketImpl::IsConnected() const {
690 // If the handshake has not yet completed. 692 // If the handshake has not yet completed.
691 if (!completed_connect_) 693 if (!completed_connect_)
692 return false; 694 return false;
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after
1128 return ERR_SSL_CLIENT_AUTH_CERT_NEEDED; 1130 return ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
1129 } 1131 }
1130 if (ssl_error == SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) { 1132 if (ssl_error == SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) {
1131 DCHECK(ssl_config_.client_private_key); 1133 DCHECK(ssl_config_.client_private_key);
1132 DCHECK_NE(kNoPendingResult, signature_result_); 1134 DCHECK_NE(kNoPendingResult, signature_result_);
1133 next_handshake_state_ = STATE_HANDSHAKE; 1135 next_handshake_state_ = STATE_HANDSHAKE;
1134 return ERR_IO_PENDING; 1136 return ERR_IO_PENDING;
1135 } 1137 }
1136 1138
1137 OpenSSLErrorInfo error_info; 1139 OpenSSLErrorInfo error_info;
1138 net_error = MapOpenSSLErrorWithDetails(ssl_error, err_tracer, &error_info); 1140 net_error = MapLastOpenSSLError(ssl_error, err_tracer, &error_info);
1139 if (net_error == ERR_IO_PENDING) { 1141 if (net_error == ERR_IO_PENDING) {
1140 // If not done, stay in this state 1142 // If not done, stay in this state
1141 next_handshake_state_ = STATE_HANDSHAKE; 1143 next_handshake_state_ = STATE_HANDSHAKE;
1142 return ERR_IO_PENDING; 1144 return ERR_IO_PENDING;
1143 } 1145 }
1144 1146
1145 LOG(ERROR) << "handshake failed; returned " << rv << ", SSL error code " 1147 LOG(ERROR) << "handshake failed; returned " << rv << ", SSL error code "
1146 << ssl_error << ", net_error " << net_error; 1148 << ssl_error << ", net_error " << net_error;
1147 net_log_.AddEvent( 1149 net_log_.AddEvent(
1148 NetLogEventType::SSL_HANDSHAKE_ERROR, 1150 NetLogEventType::SSL_HANDSHAKE_ERROR,
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
1530 pending_read_error_ = 0; 1532 pending_read_error_ = 0;
1531 } else if (pending_read_ssl_error_ == SSL_ERROR_WANT_X509_LOOKUP && 1533 } else if (pending_read_ssl_error_ == SSL_ERROR_WANT_X509_LOOKUP &&
1532 !ssl_config_.send_client_cert) { 1534 !ssl_config_.send_client_cert) {
1533 pending_read_error_ = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; 1535 pending_read_error_ = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
1534 } else if (pending_read_ssl_error_ == 1536 } else if (pending_read_ssl_error_ ==
1535 SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) { 1537 SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) {
1536 DCHECK(ssl_config_.client_private_key); 1538 DCHECK(ssl_config_.client_private_key);
1537 DCHECK_NE(kNoPendingResult, signature_result_); 1539 DCHECK_NE(kNoPendingResult, signature_result_);
1538 pending_read_error_ = ERR_IO_PENDING; 1540 pending_read_error_ = ERR_IO_PENDING;
1539 } else { 1541 } else {
1540 pending_read_error_ = MapOpenSSLErrorWithDetails( 1542 pending_read_error_ = MapLastOpenSSLError(
1541 pending_read_ssl_error_, err_tracer, &pending_read_error_info_); 1543 pending_read_ssl_error_, err_tracer, &pending_read_error_info_);
1542 } 1544 }
1543 1545
1544 // Many servers do not reliably send a close_notify alert when shutting down 1546 // Many servers do not reliably send a close_notify alert when shutting down
1545 // a connection, and instead terminate the TCP connection. This is reported 1547 // a connection, and instead terminate the TCP connection. This is reported
1546 // as ERR_CONNECTION_CLOSED. Because of this, map the unclean shutdown to a 1548 // as ERR_CONNECTION_CLOSED. Because of this, map the unclean shutdown to a
1547 // graceful EOF, instead of treating it as an error as it should be. 1549 // graceful EOF, instead of treating it as an error as it should be.
1548 if (pending_read_error_ == ERR_CONNECTION_CLOSED) 1550 if (pending_read_error_ == ERR_CONNECTION_CLOSED)
1549 pending_read_error_ = 0; 1551 pending_read_error_ = 0;
1550 } 1552 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1589 if (rv >= 0) { 1591 if (rv >= 0) {
1590 net_log_.AddByteTransferEvent(NetLogEventType::SSL_SOCKET_BYTES_SENT, rv, 1592 net_log_.AddByteTransferEvent(NetLogEventType::SSL_SOCKET_BYTES_SENT, rv,
1591 user_write_buf_->data()); 1593 user_write_buf_->data());
1592 return rv; 1594 return rv;
1593 } 1595 }
1594 1596
1595 int ssl_error = SSL_get_error(ssl_, rv); 1597 int ssl_error = SSL_get_error(ssl_, rv);
1596 if (ssl_error == SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) 1598 if (ssl_error == SSL_ERROR_WANT_PRIVATE_KEY_OPERATION)
1597 return ERR_IO_PENDING; 1599 return ERR_IO_PENDING;
1598 OpenSSLErrorInfo error_info; 1600 OpenSSLErrorInfo error_info;
1599 int net_error = 1601 int net_error = MapLastOpenSSLError(ssl_error, err_tracer, &error_info);
1600 MapOpenSSLErrorWithDetails(ssl_error, err_tracer, &error_info);
1601 1602
1602 if (net_error != ERR_IO_PENDING) { 1603 if (net_error != ERR_IO_PENDING) {
1603 net_log_.AddEvent( 1604 net_log_.AddEvent(
1604 NetLogEventType::SSL_WRITE_ERROR, 1605 NetLogEventType::SSL_WRITE_ERROR,
1605 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info)); 1606 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info));
1606 } 1607 }
1607 return net_error; 1608 return net_error;
1608 } 1609 }
1609 1610
1610 void SSLClientSocketImpl::PumpReadWriteEvents() { 1611 void SSLClientSocketImpl::PumpReadWriteEvents() {
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
1814 return ERR_CERTIFICATE_TRANSPARENCY_REQUIRED; 1815 return ERR_CERTIFICATE_TRANSPARENCY_REQUIRED;
1815 } 1816 }
1816 1817
1817 return OK; 1818 return OK;
1818 } 1819 }
1819 1820
1820 int SSLClientSocketImpl::ClientCertRequestCallback(SSL* ssl) { 1821 int SSLClientSocketImpl::ClientCertRequestCallback(SSL* ssl) {
1821 DCHECK(ssl == ssl_); 1822 DCHECK(ssl == ssl_);
1822 1823
1823 net_log_.AddEvent(NetLogEventType::SSL_CLIENT_CERT_REQUESTED); 1824 net_log_.AddEvent(NetLogEventType::SSL_CLIENT_CERT_REQUESTED);
1825 certificate_requested_ = true;
1824 1826
1825 // Clear any currently configured certificates. 1827 // Clear any currently configured certificates.
1826 SSL_certs_clear(ssl_); 1828 SSL_certs_clear(ssl_);
1827 1829
1828 #if defined(OS_IOS) 1830 #if defined(OS_IOS)
1829 // TODO(droger): Support client auth on iOS. See http://crbug.com/145954). 1831 // TODO(droger): Support client auth on iOS. See http://crbug.com/145954).
1830 LOG(WARNING) << "Client auth is not supported"; 1832 LOG(WARNING) << "Client auth is not supported";
1831 #else // !defined(OS_IOS) 1833 #else // !defined(OS_IOS)
1832 if (!ssl_config_.send_client_cert) { 1834 if (!ssl_config_.send_client_cert) {
1833 // First pass: we know that a client certificate is needed, but we do not 1835 // First pass: we know that a client certificate is needed, but we do not
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
2281 supported = CLIENT_ONLY; 2283 supported = CLIENT_ONLY;
2282 } 2284 }
2283 UMA_HISTOGRAM_ENUMERATION("DomainBoundCerts.Support", supported, 2285 UMA_HISTOGRAM_ENUMERATION("DomainBoundCerts.Support", supported,
2284 CHANNEL_ID_USAGE_MAX); 2286 CHANNEL_ID_USAGE_MAX);
2285 } 2287 }
2286 2288
2287 bool SSLClientSocketImpl::IsChannelIDEnabled() const { 2289 bool SSLClientSocketImpl::IsChannelIDEnabled() const {
2288 return ssl_config_.channel_id_enabled && channel_id_service_; 2290 return ssl_config_.channel_id_enabled && channel_id_service_;
2289 } 2291 }
2290 2292
2293 int SSLClientSocketImpl::MapLastOpenSSLError(
2294 int ssl_error,
2295 const crypto::OpenSSLErrStackTracer& tracer,
2296 OpenSSLErrorInfo* info) {
2297 int net_error = MapOpenSSLErrorWithDetails(ssl_error, tracer, info);
2298
2299 if (ssl_error == SSL_ERROR_SSL &&
2300 ERR_GET_LIB(info->error_code) == ERR_LIB_SSL) {
2301 // TLS does not provide an alert for missing client certificates, so most
2302 // servers send a generic handshake_failure alert. Detect this case by
2303 // checking if we have received a CertificateRequest but sent no
2304 // certificate. See https://crbug.com/646567.
2305 if (ERR_GET_REASON(info->error_code) ==
2306 SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE &&
2307 certificate_requested_ && ssl_config_.send_client_cert &&
2308 !ssl_config_.client_cert) {
2309 net_error = ERR_BAD_SSL_CLIENT_AUTH_CERT;
2310 }
2311
2312 // Per spec, access_denied is only for client-certificate-based access
2313 // control, but some buggy firewalls use it when blocking a page. To avoid a
2314 // confusing error, map it to a generic protocol error if no
2315 // CertificateRequest was sent. See https://crbug.com/630883.
2316 if (ERR_GET_REASON(info->error_code) == SSL_R_TLSV1_ALERT_ACCESS_DENIED &&
2317 !certificate_requested_) {
2318 net_error = ERR_SSL_PROTOCOL_ERROR;
2319 }
2320 }
2321
2322 return net_error;
2323 }
2324
2291 } // namespace net 2325 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/ssl_client_socket_impl.h ('k') | net/socket/ssl_client_socket_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698