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

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

Issue 280853002: Preserve transport errors for OpenSSL sockets. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: USE_NSS -> USE_OPENSSL for Windows and Mac Created 6 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 | Annotate | Revision Log
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 // OpenSSL binding for SSLClientSocket. The class layout and general principle 5 // OpenSSL binding for SSLClientSocket. The class layout and general principle
6 // of operation is derived from SSLClientSocketNSS. 6 // of operation is derived from SSLClientSocketNSS.
7 7
8 #include "net/socket/ssl_client_socket_openssl.h" 8 #include "net/socket/ssl_client_socket_openssl.h"
9 9
10 #include <openssl/err.h> 10 #include <openssl/err.h>
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 #endif 332 #endif
333 } 333 }
334 334
335 SSLClientSocketOpenSSL::SSLClientSocketOpenSSL( 335 SSLClientSocketOpenSSL::SSLClientSocketOpenSSL(
336 scoped_ptr<ClientSocketHandle> transport_socket, 336 scoped_ptr<ClientSocketHandle> transport_socket,
337 const HostPortPair& host_and_port, 337 const HostPortPair& host_and_port,
338 const SSLConfig& ssl_config, 338 const SSLConfig& ssl_config,
339 const SSLClientSocketContext& context) 339 const SSLClientSocketContext& context)
340 : transport_send_busy_(false), 340 : transport_send_busy_(false),
341 transport_recv_busy_(false), 341 transport_recv_busy_(false),
342 transport_recv_eof_(false),
343 weak_factory_(this), 342 weak_factory_(this),
344 pending_read_error_(kNoPendingReadResult), 343 pending_read_error_(kNoPendingReadResult),
345 transport_write_error_(OK), 344 transport_read_error_(ERR_IO_PENDING),
345 transport_write_error_(ERR_IO_PENDING),
346 server_cert_chain_(new PeerCertificateChain(NULL)), 346 server_cert_chain_(new PeerCertificateChain(NULL)),
347 completed_handshake_(false), 347 completed_handshake_(false),
348 was_ever_used_(false), 348 was_ever_used_(false),
349 client_auth_cert_needed_(false), 349 client_auth_cert_needed_(false),
350 cert_verifier_(context.cert_verifier), 350 cert_verifier_(context.cert_verifier),
351 server_bound_cert_service_(context.server_bound_cert_service), 351 server_bound_cert_service_(context.server_bound_cert_service),
352 ssl_(NULL), 352 ssl_(NULL),
353 transport_bio_(NULL), 353 transport_bio_(NULL),
354 transport_(transport_socket.Pass()), 354 transport_(transport_socket.Pass()),
355 host_and_port_(host_and_port), 355 host_and_port_(host_and_port),
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 int rv = SSL_export_keying_material( 394 int rv = SSL_export_keying_material(
395 ssl_, out, outlen, label.data(), label.size(), 395 ssl_, out, outlen, label.data(), label.size(),
396 reinterpret_cast<const unsigned char*>(context.data()), 396 reinterpret_cast<const unsigned char*>(context.data()),
397 context.length(), context.length() > 0); 397 context.length(), context.length() > 0);
398 398
399 if (rv != 1) { 399 if (rv != 1) {
400 int ssl_error = SSL_get_error(ssl_, rv); 400 int ssl_error = SSL_get_error(ssl_, rv);
401 LOG(ERROR) << "Failed to export keying material;" 401 LOG(ERROR) << "Failed to export keying material;"
402 << " returned " << rv 402 << " returned " << rv
403 << ", SSL error code " << ssl_error; 403 << ", SSL error code " << ssl_error;
404 return MapOpenSSLError(ssl_error, err_tracer); 404 return HandleOpenSSLError(ssl_error, err_tracer);
405 } 405 }
406 return OK; 406 return OK;
407 } 407 }
408 408
409 int SSLClientSocketOpenSSL::GetTLSUniqueChannelBinding(std::string* out) { 409 int SSLClientSocketOpenSSL::GetTLSUniqueChannelBinding(std::string* out) {
410 NOTIMPLEMENTED(); 410 NOTIMPLEMENTED();
411 return ERR_NOT_IMPLEMENTED; 411 return ERR_NOT_IMPLEMENTED;
412 } 412 }
413 413
414 int SSLClientSocketOpenSSL::Connect(const CompletionCallback& callback) { 414 int SSLClientSocketOpenSSL::Connect(const CompletionCallback& callback) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 } 449 }
450 450
451 // Shut down anything that may call us back. 451 // Shut down anything that may call us back.
452 verifier_.reset(); 452 verifier_.reset();
453 transport_->socket()->Disconnect(); 453 transport_->socket()->Disconnect();
454 454
455 // Null all callbacks, delete all buffers. 455 // Null all callbacks, delete all buffers.
456 transport_send_busy_ = false; 456 transport_send_busy_ = false;
457 send_buffer_ = NULL; 457 send_buffer_ = NULL;
458 transport_recv_busy_ = false; 458 transport_recv_busy_ = false;
459 transport_recv_eof_ = false;
460 recv_buffer_ = NULL; 459 recv_buffer_ = NULL;
461 460
462 user_connect_callback_.Reset(); 461 user_connect_callback_.Reset();
463 user_read_callback_.Reset(); 462 user_read_callback_.Reset();
464 user_write_callback_.Reset(); 463 user_write_callback_.Reset();
465 user_read_buf_ = NULL; 464 user_read_buf_ = NULL;
466 user_read_buf_len_ = 0; 465 user_read_buf_len_ = 0;
467 user_write_buf_ = NULL; 466 user_write_buf_ = NULL;
468 user_write_buf_len_ = 0; 467 user_write_buf_len_ = 0;
469 468
470 pending_read_error_ = kNoPendingReadResult; 469 pending_read_error_ = kNoPendingReadResult;
471 transport_write_error_ = OK; 470 transport_read_error_ = ERR_IO_PENDING;
471 transport_write_error_ = ERR_IO_PENDING;
472 472
473 server_cert_verify_result_.Reset(); 473 server_cert_verify_result_.Reset();
474 completed_handshake_ = false; 474 completed_handshake_ = false;
475 475
476 cert_authorities_.clear(); 476 cert_authorities_.clear();
477 cert_key_types_.clear(); 477 cert_key_types_.clear();
478 client_auth_cert_needed_ = false; 478 client_auth_cert_needed_ = false;
479 } 479 }
480 480
481 bool SSLClientSocketOpenSSL::IsConnected() const { 481 bool SSLClientSocketOpenSSL::IsConnected() const {
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 << SSLConnectionStatusToVersion(ssl_info->connection_status); 594 << SSLConnectionStatusToVersion(ssl_info->connection_status);
595 return true; 595 return true;
596 } 596 }
597 597
598 int SSLClientSocketOpenSSL::Read(IOBuffer* buf, 598 int SSLClientSocketOpenSSL::Read(IOBuffer* buf,
599 int buf_len, 599 int buf_len,
600 const CompletionCallback& callback) { 600 const CompletionCallback& callback) {
601 user_read_buf_ = buf; 601 user_read_buf_ = buf;
602 user_read_buf_len_ = buf_len; 602 user_read_buf_len_ = buf_len;
603 603
604 int rv = DoReadLoop(OK); 604 int rv = DoReadLoop();
605 605
606 if (rv == ERR_IO_PENDING) { 606 if (rv == ERR_IO_PENDING) {
607 user_read_callback_ = callback; 607 user_read_callback_ = callback;
608 } else { 608 } else {
609 if (rv > 0) 609 if (rv > 0)
610 was_ever_used_ = true; 610 was_ever_used_ = true;
611 user_read_buf_ = NULL; 611 user_read_buf_ = NULL;
612 user_read_buf_len_ = 0; 612 user_read_buf_len_ = 0;
613 } 613 }
614 614
615 return rv; 615 return rv;
616 } 616 }
617 617
618 int SSLClientSocketOpenSSL::Write(IOBuffer* buf, 618 int SSLClientSocketOpenSSL::Write(IOBuffer* buf,
619 int buf_len, 619 int buf_len,
620 const CompletionCallback& callback) { 620 const CompletionCallback& callback) {
621 user_write_buf_ = buf; 621 user_write_buf_ = buf;
622 user_write_buf_len_ = buf_len; 622 user_write_buf_len_ = buf_len;
623 623
624 int rv = DoWriteLoop(OK); 624 int rv = DoWriteLoop();
625 625
626 if (rv == ERR_IO_PENDING) { 626 if (rv == ERR_IO_PENDING) {
627 user_write_callback_ = callback; 627 user_write_callback_ = callback;
628 } else { 628 } else {
629 if (rv > 0) 629 if (rv > 0)
630 was_ever_used_ = true; 630 was_ever_used_ = true;
631 user_write_buf_ = NULL; 631 user_write_buf_ = NULL;
632 user_write_buf_len_ = 0; 632 user_write_buf_len_ = 0;
633 } 633 }
634 634
(...skipping 25 matching lines...) Expand all
660 trying_cached_session_ = context->session_cache()->SetSSLSessionWithKey( 660 trying_cached_session_ = context->session_cache()->SetSSLSessionWithKey(
661 ssl_, GetSocketSessionCacheKey(*this)); 661 ssl_, GetSocketSessionCacheKey(*this));
662 662
663 BIO* ssl_bio = NULL; 663 BIO* ssl_bio = NULL;
664 // 0 => use default buffer sizes. 664 // 0 => use default buffer sizes.
665 if (!BIO_new_bio_pair(&ssl_bio, 0, &transport_bio_, 0)) 665 if (!BIO_new_bio_pair(&ssl_bio, 0, &transport_bio_, 0))
666 return ERR_UNEXPECTED; 666 return ERR_UNEXPECTED;
667 DCHECK(ssl_bio); 667 DCHECK(ssl_bio);
668 DCHECK(transport_bio_); 668 DCHECK(transport_bio_);
669 669
670 // Install a callback on OpenSSL's end to plumb transport errors through.
671 BIO_set_callback(ssl_bio, &SSLClientSocketOpenSSL::BIOCallbackThunk);
672 BIO_set_callback_arg(ssl_bio, reinterpret_cast<char*>(this));
673
670 SSL_set_bio(ssl_, ssl_bio, ssl_bio); 674 SSL_set_bio(ssl_, ssl_bio, ssl_bio);
671 675
672 // OpenSSL defaults some options to on, others to off. To avoid ambiguity, 676 // OpenSSL defaults some options to on, others to off. To avoid ambiguity,
673 // set everything we care about to an absolute value. 677 // set everything we care about to an absolute value.
674 SslSetClearMask options; 678 SslSetClearMask options;
675 options.ConfigureFlag(SSL_OP_NO_SSLv2, true); 679 options.ConfigureFlag(SSL_OP_NO_SSLv2, true);
676 bool ssl3_enabled = (ssl_config_.version_min == SSL_PROTOCOL_VERSION_SSL3); 680 bool ssl3_enabled = (ssl_config_.version_min == SSL_PROTOCOL_VERSION_SSL3);
677 options.ConfigureFlag(SSL_OP_NO_SSLv3, !ssl3_enabled); 681 options.ConfigureFlag(SSL_OP_NO_SSLv3, !ssl3_enabled);
678 bool tls1_enabled = (ssl_config_.version_min <= SSL_PROTOCOL_VERSION_TLS1 && 682 bool tls1_enabled = (ssl_config_.version_min <= SSL_PROTOCOL_VERSION_TLS1 &&
679 ssl_config_.version_max >= SSL_PROTOCOL_VERSION_TLS1); 683 ssl_config_.version_max >= SSL_PROTOCOL_VERSION_TLS1);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 bool SSLClientSocketOpenSSL::DoTransportIO() { 782 bool SSLClientSocketOpenSSL::DoTransportIO() {
779 bool network_moved = false; 783 bool network_moved = false;
780 int rv; 784 int rv;
781 // Read and write as much data as possible. The loop is necessary because 785 // Read and write as much data as possible. The loop is necessary because
782 // Write() may return synchronously. 786 // Write() may return synchronously.
783 do { 787 do {
784 rv = BufferSend(); 788 rv = BufferSend();
785 if (rv != ERR_IO_PENDING && rv != 0) 789 if (rv != ERR_IO_PENDING && rv != 0)
786 network_moved = true; 790 network_moved = true;
787 } while (rv > 0); 791 } while (rv > 0);
788 if (!transport_recv_eof_ && BufferRecv() != ERR_IO_PENDING) 792 if (transport_read_error_ == ERR_IO_PENDING &&
793 BufferRecv() != ERR_IO_PENDING) {
789 network_moved = true; 794 network_moved = true;
795 }
790 return network_moved; 796 return network_moved;
791 } 797 }
792 798
793 int SSLClientSocketOpenSSL::DoHandshake() { 799 int SSLClientSocketOpenSSL::DoHandshake() {
794 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 800 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
795 int net_error = OK; 801 int net_error = OK;
796 int rv = SSL_do_handshake(ssl_); 802 int rv = SSL_do_handshake(ssl_);
797 803
798 if (client_auth_cert_needed_) { 804 if (client_auth_cert_needed_) {
799 net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; 805 net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
(...skipping 24 matching lines...) Expand all
824 base::Unretained(server_cert_.get()))); 830 base::Unretained(server_cert_.get())));
825 GotoState(STATE_VERIFY_CERT); 831 GotoState(STATE_VERIFY_CERT);
826 } else { 832 } else {
827 int ssl_error = SSL_get_error(ssl_, rv); 833 int ssl_error = SSL_get_error(ssl_, rv);
828 834
829 if (ssl_error == SSL_ERROR_WANT_CHANNEL_ID_LOOKUP) { 835 if (ssl_error == SSL_ERROR_WANT_CHANNEL_ID_LOOKUP) {
830 // The server supports TLS channel id and the lookup is asynchronous. 836 // The server supports TLS channel id and the lookup is asynchronous.
831 // Retrieve the error from the call to |server_bound_cert_service_|. 837 // Retrieve the error from the call to |server_bound_cert_service_|.
832 net_error = channel_id_request_return_value_; 838 net_error = channel_id_request_return_value_;
833 } else { 839 } else {
834 net_error = MapOpenSSLError(ssl_error, err_tracer); 840 net_error = HandleOpenSSLError(ssl_error, err_tracer);
835 } 841 }
836 842
837 // If not done, stay in this state 843 // If not done, stay in this state
838 if (net_error == ERR_IO_PENDING) { 844 if (net_error == ERR_IO_PENDING) {
839 GotoState(STATE_HANDSHAKE); 845 GotoState(STATE_HANDSHAKE);
840 } else { 846 } else {
841 LOG(ERROR) << "handshake failed; returned " << rv 847 LOG(ERROR) << "handshake failed; returned " << rv
842 << ", SSL error code " << ssl_error 848 << ", SSL error code " << ssl_error
843 << ", net_error " << net_error; 849 << ", net_error " << net_error;
844 net_log_.AddEvent( 850 net_log_.AddEvent(
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
967 // In handshake phase. 973 // In handshake phase.
968 OnHandshakeIOComplete(result); 974 OnHandshakeIOComplete(result);
969 return; 975 return;
970 } 976 }
971 977
972 // Network layer received some data, check if client requested to read 978 // Network layer received some data, check if client requested to read
973 // decrypted data. 979 // decrypted data.
974 if (!user_read_buf_.get()) 980 if (!user_read_buf_.get())
975 return; 981 return;
976 982
977 int rv = DoReadLoop(result); 983 int rv = DoReadLoop();
978 if (rv != ERR_IO_PENDING) 984 if (rv != ERR_IO_PENDING)
979 DoReadCallback(rv); 985 DoReadCallback(rv);
980 } 986 }
981 987
982 int SSLClientSocketOpenSSL::DoHandshakeLoop(int last_io_result) { 988 int SSLClientSocketOpenSSL::DoHandshakeLoop(int last_io_result) {
983 int rv = last_io_result; 989 int rv = last_io_result;
984 do { 990 do {
985 // Default to STATE_NONE for next state. 991 // Default to STATE_NONE for next state.
986 // (This is a quirk carried over from the windows 992 // (This is a quirk carried over from the windows
987 // implementation. It makes reading the logs a bit harder.) 993 // implementation. It makes reading the logs a bit harder.)
(...skipping 23 matching lines...) Expand all
1011 if (network_moved && next_handshake_state_ == STATE_HANDSHAKE) { 1017 if (network_moved && next_handshake_state_ == STATE_HANDSHAKE) {
1012 // In general we exit the loop if rv is ERR_IO_PENDING. In this 1018 // In general we exit the loop if rv is ERR_IO_PENDING. In this
1013 // special case we keep looping even if rv is ERR_IO_PENDING because 1019 // special case we keep looping even if rv is ERR_IO_PENDING because
1014 // the transport IO may allow DoHandshake to make progress. 1020 // the transport IO may allow DoHandshake to make progress.
1015 rv = OK; // This causes us to stay in the loop. 1021 rv = OK; // This causes us to stay in the loop.
1016 } 1022 }
1017 } while (rv != ERR_IO_PENDING && next_handshake_state_ != STATE_NONE); 1023 } while (rv != ERR_IO_PENDING && next_handshake_state_ != STATE_NONE);
1018 return rv; 1024 return rv;
1019 } 1025 }
1020 1026
1021 int SSLClientSocketOpenSSL::DoReadLoop(int result) { 1027 int SSLClientSocketOpenSSL::DoReadLoop() {
1022 if (result < 0)
1023 return result;
1024
1025 bool network_moved; 1028 bool network_moved;
1026 int rv; 1029 int rv;
1027 do { 1030 do {
1028 rv = DoPayloadRead(); 1031 rv = DoPayloadRead();
1029 network_moved = DoTransportIO(); 1032 network_moved = DoTransportIO();
1030 } while (rv == ERR_IO_PENDING && network_moved); 1033 } while (rv == ERR_IO_PENDING && network_moved);
1031 1034
1032 return rv; 1035 return rv;
1033 } 1036 }
1034 1037
1035 int SSLClientSocketOpenSSL::DoWriteLoop(int result) { 1038 int SSLClientSocketOpenSSL::DoWriteLoop() {
1036 if (result < 0)
1037 return result;
1038
1039 bool network_moved; 1039 bool network_moved;
1040 int rv; 1040 int rv;
1041 do { 1041 do {
1042 rv = DoPayloadWrite(); 1042 rv = DoPayloadWrite();
1043 network_moved = DoTransportIO(); 1043 network_moved = DoTransportIO();
1044 } while (rv == ERR_IO_PENDING && network_moved); 1044 } while (rv == ERR_IO_PENDING && network_moved);
1045 1045
1046 return rv; 1046 return rv;
1047 } 1047 }
1048 1048
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1085 if (total_bytes_read > 0) { 1085 if (total_bytes_read > 0) {
1086 pending_read_error_ = rv; 1086 pending_read_error_ = rv;
1087 rv = total_bytes_read; 1087 rv = total_bytes_read;
1088 next_result = &pending_read_error_; 1088 next_result = &pending_read_error_;
1089 } 1089 }
1090 1090
1091 if (client_auth_cert_needed_) { 1091 if (client_auth_cert_needed_) {
1092 *next_result = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; 1092 *next_result = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
1093 } else if (*next_result < 0) { 1093 } else if (*next_result < 0) {
1094 int err = SSL_get_error(ssl_, *next_result); 1094 int err = SSL_get_error(ssl_, *next_result);
1095 *next_result = MapOpenSSLError(err, err_tracer); 1095 *next_result = HandleOpenSSLError(err, err_tracer);
1096 if (rv > 0 && *next_result == ERR_IO_PENDING) { 1096 if (rv > 0 && *next_result == ERR_IO_PENDING) {
1097 // If at least some data was read from SSL_read(), do not treat 1097 // If at least some data was read from SSL_read(), do not treat
1098 // insufficient data as an error to return in the next call to 1098 // insufficient data as an error to return in the next call to
1099 // DoPayloadRead() - instead, let the call fall through to check 1099 // DoPayloadRead() - instead, let the call fall through to check
1100 // SSL_read() again. This is because DoTransportIO() may complete 1100 // SSL_read() again. This is because DoTransportIO() may complete
1101 // in between the next call to DoPayloadRead(), and thus it is 1101 // in between the next call to DoPayloadRead(), and thus it is
1102 // important to check SSL_read() on subsequent invocations to see 1102 // important to check SSL_read() on subsequent invocations to see
1103 // if a complete record may now be read. 1103 // if a complete record may now be read.
1104 *next_result = kNoPendingReadResult; 1104 *next_result = kNoPendingReadResult;
1105 } 1105 }
1106 } 1106 }
1107 } 1107 }
1108 1108
1109 if (rv >= 0) { 1109 if (rv >= 0) {
1110 net_log_.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_RECEIVED, rv, 1110 net_log_.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_RECEIVED, rv,
1111 user_read_buf_->data()); 1111 user_read_buf_->data());
1112 } 1112 }
1113 return rv; 1113 return rv;
1114 } 1114 }
1115 1115
1116 int SSLClientSocketOpenSSL::DoPayloadWrite() { 1116 int SSLClientSocketOpenSSL::DoPayloadWrite() {
1117 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 1117 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
1118 int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_); 1118 int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_);
1119 1119
1120 if (rv >= 0) { 1120 if (rv >= 0) {
1121 net_log_.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_SENT, rv, 1121 net_log_.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_SENT, rv,
1122 user_write_buf_->data()); 1122 user_write_buf_->data());
1123 return rv; 1123 return rv;
1124 } 1124 }
1125 1125
1126 int err = SSL_get_error(ssl_, rv); 1126 int err = SSL_get_error(ssl_, rv);
1127 return MapOpenSSLError(err, err_tracer); 1127 return HandleOpenSSLError(err, err_tracer);
1128 } 1128 }
1129 1129
1130 int SSLClientSocketOpenSSL::BufferSend(void) { 1130 int SSLClientSocketOpenSSL::BufferSend(void) {
1131 if (transport_send_busy_) 1131 if (transport_send_busy_)
1132 return ERR_IO_PENDING; 1132 return ERR_IO_PENDING;
1133 1133
1134 if (!send_buffer_.get()) { 1134 if (!send_buffer_.get()) {
1135 // Get a fresh send buffer out of the send BIO. 1135 // Get a fresh send buffer out of the send BIO.
1136 size_t max_read = BIO_ctrl_pending(transport_bio_); 1136 size_t max_read = BIO_ctrl_pending(transport_bio_);
1137 if (!max_read) 1137 if (!max_read)
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1202 } 1202 }
1203 1203
1204 void SSLClientSocketOpenSSL::BufferRecvComplete(int result) { 1204 void SSLClientSocketOpenSSL::BufferRecvComplete(int result) {
1205 result = TransportReadComplete(result); 1205 result = TransportReadComplete(result);
1206 OnRecvComplete(result); 1206 OnRecvComplete(result);
1207 } 1207 }
1208 1208
1209 void SSLClientSocketOpenSSL::TransportWriteComplete(int result) { 1209 void SSLClientSocketOpenSSL::TransportWriteComplete(int result) {
1210 DCHECK(ERR_IO_PENDING != result); 1210 DCHECK(ERR_IO_PENDING != result);
1211 if (result < 0) { 1211 if (result < 0) {
1212 // Got a socket write error; close the BIO to indicate this upward. 1212 // Record the error. Save it to be reported in a future read or write on
1213 // 1213 // transport_bio_'s peer.
1214 // TODO(davidben): The value of |result| gets lost. Feed the error back into
1215 // the BIO so it gets (re-)detected in OnSendComplete. Perhaps with
1216 // BIO_set_callback.
1217 DVLOG(1) << "TransportWriteComplete error " << result;
1218 (void)BIO_shutdown_wr(SSL_get_wbio(ssl_));
1219
1220 // Match the fix for http://crbug.com/249848 in NSS by erroring future reads
1221 // from the socket after a write error.
1222 //
1223 // TODO(davidben): Avoid having read and write ends interact this way.
1224 transport_write_error_ = result; 1214 transport_write_error_ = result;
1225 (void)BIO_shutdown_wr(transport_bio_);
1226 send_buffer_ = NULL; 1215 send_buffer_ = NULL;
1227 } else { 1216 } else {
1228 DCHECK(send_buffer_.get()); 1217 DCHECK(send_buffer_.get());
1229 send_buffer_->DidConsume(result); 1218 send_buffer_->DidConsume(result);
1230 DCHECK_GE(send_buffer_->BytesRemaining(), 0); 1219 DCHECK_GE(send_buffer_->BytesRemaining(), 0);
1231 if (send_buffer_->BytesRemaining() <= 0) 1220 if (send_buffer_->BytesRemaining() <= 0)
1232 send_buffer_ = NULL; 1221 send_buffer_ = NULL;
1233 } 1222 }
1234 } 1223 }
1235 1224
1236 int SSLClientSocketOpenSSL::TransportReadComplete(int result) { 1225 int SSLClientSocketOpenSSL::TransportReadComplete(int result) {
1237 DCHECK(ERR_IO_PENDING != result); 1226 DCHECK(ERR_IO_PENDING != result);
1238 if (result <= 0) { 1227 if (result <= 0) {
1239 DVLOG(1) << "TransportReadComplete result " << result; 1228 DVLOG(1) << "TransportReadComplete result " << result;
1240 // Received 0 (end of file) or an error. Either way, bubble it up to the 1229 // Received 0 (end of file) or an error. Save it to be reported in a future
1241 // SSL layer via the BIO. TODO(joth): consider stashing the error code, to 1230 // read on transport_bio_'s peer.
1242 // relay up to the SSL socket client (i.e. via DoReadCallback). 1231 transport_read_error_ = result;
1243 if (result == 0)
1244 transport_recv_eof_ = true;
1245 (void)BIO_shutdown_wr(transport_bio_);
1246 } else if (transport_write_error_ < 0) {
1247 // Mirror transport write errors as read failures; transport_bio_ has been
1248 // shut down by TransportWriteComplete, so the BIO_write will fail, failing
1249 // the CHECK. http://crbug.com/335557.
1250 result = transport_write_error_;
1251 } else { 1232 } else {
1252 DCHECK(recv_buffer_.get()); 1233 DCHECK(recv_buffer_.get());
1253 int ret = BIO_write(transport_bio_, recv_buffer_->data(), result); 1234 int ret = BIO_write(transport_bio_, recv_buffer_->data(), result);
1254 // A write into a memory BIO should always succeed. 1235 // A write into a memory BIO should always succeed.
1255 DCHECK_EQ(result, ret); 1236 DCHECK_EQ(result, ret);
1256 } 1237 }
1257 recv_buffer_ = NULL; 1238 recv_buffer_ = NULL;
1258 transport_recv_busy_ = false; 1239 transport_recv_busy_ = false;
1259 return result; 1240 return result;
1260 } 1241 }
1261 1242
1243 int SSLClientSocketOpenSSL::HandleOpenSSLError(
1244 int ssl_error,
1245 const crypto::OpenSSLErrStackTracer& tracer) {
1246 // Route transport failures around OpenSSL. Use SSL_ERROR_WANT_READ and
1247 // SSL_ERROR_WANT_WRITE to determine whether to use the read or write failure
1248 // on the transport. This is done in lieu of routing net errors though
1249 // OpenSSL's error system.
1250 if (ssl_error == SSL_ERROR_WANT_READ) {
1251 // If OpenSSL wanted read data, report any pending errors that were
1252 // observed. Note that both |transport_read_error_| and
1253 // |transport_write_error_| are checked, since the application may have
1254 // encountered a socket error while writing that would otherwise not be
1255 // reported until the application attempted to write again - which it may
1256 // never do. This matches the fix for https://crbug.com/249848 in NSS.
1257 if (transport_read_error_ != ERR_IO_PENDING)
1258 return transport_read_error_;
1259 if (transport_write_error_ != ERR_IO_PENDING)
1260 return transport_write_error_;
1261 } else if (ssl_error == SSL_ERROR_WANT_WRITE) {
1262 // Because of the write buffer, this reports a failure from the previous
1263 // write payload. If the current payload fails to write, the error will be
1264 // reported in a future write or read.
1265 if (transport_write_error_ != ERR_IO_PENDING)
1266 return transport_write_error_;
1267 }
1268
1269 // Otherwise, map the error code.
1270 return MapOpenSSLError(ssl_error, tracer);
1271 }
1272
1262 int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl, 1273 int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl,
1263 X509** x509, 1274 X509** x509,
1264 EVP_PKEY** pkey) { 1275 EVP_PKEY** pkey) {
1265 DVLOG(3) << "OpenSSL ClientCertRequestCallback called"; 1276 DVLOG(3) << "OpenSSL ClientCertRequestCallback called";
1266 DCHECK(ssl == ssl_); 1277 DCHECK(ssl == ssl_);
1267 DCHECK(*x509 == NULL); 1278 DCHECK(*x509 == NULL);
1268 DCHECK(*pkey == NULL); 1279 DCHECK(*pkey == NULL);
1269 if (!ssl_config_.send_client_cert) { 1280 if (!ssl_config_.send_client_cert) {
1270 // First pass: we know that a client certificate is needed, but we do not 1281 // First pass: we know that a client certificate is needed, but we do not
1271 // have one at hand. 1282 // have one at hand.
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
1424 ssl_config_.next_protos[0].data())); 1435 ssl_config_.next_protos[0].data()));
1425 *outlen = ssl_config_.next_protos[0].size(); 1436 *outlen = ssl_config_.next_protos[0].size();
1426 } 1437 }
1427 1438
1428 npn_proto_.assign(reinterpret_cast<const char*>(*out), *outlen); 1439 npn_proto_.assign(reinterpret_cast<const char*>(*out), *outlen);
1429 server_protos_.assign(reinterpret_cast<const char*>(in), inlen); 1440 server_protos_.assign(reinterpret_cast<const char*>(in), inlen);
1430 DVLOG(2) << "next protocol: '" << npn_proto_ << "' status: " << npn_status_; 1441 DVLOG(2) << "next protocol: '" << npn_proto_ << "' status: " << npn_status_;
1431 return SSL_TLSEXT_ERR_OK; 1442 return SSL_TLSEXT_ERR_OK;
1432 } 1443 }
1433 1444
1445 long SSLClientSocketOpenSSL::BIOCallback(BIO *bio,
1446 int cmd,
1447 const char *argp, int argi, long argl,
1448 long retvalue) {
1449 if (cmd == BIO_CB_WRITE && transport_write_error_ != ERR_IO_PENDING) {
1450 // If there is a transport write failure, act as if the buffer is full. This
1451 // is necessary so future writes are stopped even if there is room in the
1452 // buffer. Although retrying will not be of any use, mark as a retry so
1453 // SSL_get_error will return SSL_ERROR_WANT_WRITE if there is no other error
1454 // in the error queue. HandleOpenSSLError will consume that and route the
1455 // transport error code out of OpenSSL.
davidben 2014/06/06 23:31:51 As an alternative, we can BIO_shutdown_wr(SSL_get_
agl 2014/06/09 17:23:34 You mean when the write error is detected in Trans
davidben 2014/06/10 19:16:30 Revised to keep the BIO_shutdown_wr and condition
1456 BIO_set_retry_write(bio);
1457 return -1;
1458 }
1459 return retvalue;
1460 }
1461
1462 // static
1463 long SSLClientSocketOpenSSL::BIOCallbackThunk(
1464 BIO *bio,
1465 int cmd,
1466 const char *argp, int argi, long argl,
1467 long retvalue) {
1468 SSLClientSocketOpenSSL* socket = reinterpret_cast<SSLClientSocketOpenSSL*>(
1469 BIO_get_callback_arg(bio));
1470 return socket->BIOCallback(bio, cmd, argp, argi, argl, retvalue);
1471 }
1472
1434 scoped_refptr<X509Certificate> 1473 scoped_refptr<X509Certificate>
1435 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { 1474 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const {
1436 return server_cert_; 1475 return server_cert_;
1437 } 1476 }
1438 1477
1439 } // namespace net 1478 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698