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

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: Rebase. 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_(0),
345 transport_write_error_(0),
Ryan Sleevi 2014/06/18 01:39:52 Shouldn't this be ERR_IO_PENDING ?
davidben 2014/06/18 22:27:22 Fixed docs.
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_ = 0;
471 transport_write_error_ = 0;
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 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 bool SSLClientSocketOpenSSL::DoTransportIO() { 778 bool SSLClientSocketOpenSSL::DoTransportIO() {
779 bool network_moved = false; 779 bool network_moved = false;
780 int rv; 780 int rv;
781 // Read and write as much data as possible. The loop is necessary because 781 // Read and write as much data as possible. The loop is necessary because
782 // Write() may return synchronously. 782 // Write() may return synchronously.
783 do { 783 do {
784 rv = BufferSend(); 784 rv = BufferSend();
785 if (rv != ERR_IO_PENDING && rv != 0) 785 if (rv != ERR_IO_PENDING && rv != 0)
786 network_moved = true; 786 network_moved = true;
787 } while (rv > 0); 787 } while (rv > 0);
788 if (!transport_recv_eof_ && BufferRecv() != ERR_IO_PENDING) 788 if (transport_read_error_ == 0 && BufferRecv() != ERR_IO_PENDING) {
789 network_moved = true; 789 network_moved = true;
790 }
Ryan Sleevi 2014/06/18 01:39:52 No need for these braces.
davidben 2014/06/18 22:27:22 Done. I think that was a remnant of when it was ER
790 return network_moved; 791 return network_moved;
791 } 792 }
792 793
793 int SSLClientSocketOpenSSL::DoHandshake() { 794 int SSLClientSocketOpenSSL::DoHandshake() {
794 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 795 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
795 int net_error = OK; 796 int net_error = OK;
796 int rv = SSL_do_handshake(ssl_); 797 int rv = SSL_do_handshake(ssl_);
797 798
798 if (client_auth_cert_needed_) { 799 if (client_auth_cert_needed_) {
799 net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; 800 net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
(...skipping 24 matching lines...) Expand all
824 base::Unretained(server_cert_.get()))); 825 base::Unretained(server_cert_.get())));
825 GotoState(STATE_VERIFY_CERT); 826 GotoState(STATE_VERIFY_CERT);
826 } else { 827 } else {
827 int ssl_error = SSL_get_error(ssl_, rv); 828 int ssl_error = SSL_get_error(ssl_, rv);
828 829
829 if (ssl_error == SSL_ERROR_WANT_CHANNEL_ID_LOOKUP) { 830 if (ssl_error == SSL_ERROR_WANT_CHANNEL_ID_LOOKUP) {
830 // The server supports TLS channel id and the lookup is asynchronous. 831 // The server supports TLS channel id and the lookup is asynchronous.
831 // Retrieve the error from the call to |server_bound_cert_service_|. 832 // Retrieve the error from the call to |server_bound_cert_service_|.
832 net_error = channel_id_request_return_value_; 833 net_error = channel_id_request_return_value_;
833 } else { 834 } else {
834 net_error = MapOpenSSLError(ssl_error, err_tracer); 835 net_error = HandleOpenSSLError(ssl_error, err_tracer);
835 } 836 }
836 837
837 // If not done, stay in this state 838 // If not done, stay in this state
838 if (net_error == ERR_IO_PENDING) { 839 if (net_error == ERR_IO_PENDING) {
839 GotoState(STATE_HANDSHAKE); 840 GotoState(STATE_HANDSHAKE);
840 } else { 841 } else {
841 LOG(ERROR) << "handshake failed; returned " << rv 842 LOG(ERROR) << "handshake failed; returned " << rv
842 << ", SSL error code " << ssl_error 843 << ", SSL error code " << ssl_error
843 << ", net_error " << net_error; 844 << ", net_error " << net_error;
844 net_log_.AddEvent( 845 net_log_.AddEvent(
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
967 // In handshake phase. 968 // In handshake phase.
968 OnHandshakeIOComplete(result); 969 OnHandshakeIOComplete(result);
969 return; 970 return;
970 } 971 }
971 972
972 // Network layer received some data, check if client requested to read 973 // Network layer received some data, check if client requested to read
973 // decrypted data. 974 // decrypted data.
974 if (!user_read_buf_.get()) 975 if (!user_read_buf_.get())
975 return; 976 return;
976 977
977 int rv = DoReadLoop(result); 978 int rv = DoReadLoop();
978 if (rv != ERR_IO_PENDING) 979 if (rv != ERR_IO_PENDING)
979 DoReadCallback(rv); 980 DoReadCallback(rv);
980 } 981 }
981 982
982 int SSLClientSocketOpenSSL::DoHandshakeLoop(int last_io_result) { 983 int SSLClientSocketOpenSSL::DoHandshakeLoop(int last_io_result) {
983 int rv = last_io_result; 984 int rv = last_io_result;
984 do { 985 do {
985 // Default to STATE_NONE for next state. 986 // Default to STATE_NONE for next state.
986 // (This is a quirk carried over from the windows 987 // (This is a quirk carried over from the windows
987 // implementation. It makes reading the logs a bit harder.) 988 // implementation. It makes reading the logs a bit harder.)
(...skipping 23 matching lines...) Expand all
1011 if (network_moved && next_handshake_state_ == STATE_HANDSHAKE) { 1012 if (network_moved && next_handshake_state_ == STATE_HANDSHAKE) {
1012 // In general we exit the loop if rv is ERR_IO_PENDING. In this 1013 // 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 1014 // special case we keep looping even if rv is ERR_IO_PENDING because
1014 // the transport IO may allow DoHandshake to make progress. 1015 // the transport IO may allow DoHandshake to make progress.
1015 rv = OK; // This causes us to stay in the loop. 1016 rv = OK; // This causes us to stay in the loop.
1016 } 1017 }
1017 } while (rv != ERR_IO_PENDING && next_handshake_state_ != STATE_NONE); 1018 } while (rv != ERR_IO_PENDING && next_handshake_state_ != STATE_NONE);
1018 return rv; 1019 return rv;
1019 } 1020 }
1020 1021
1021 int SSLClientSocketOpenSSL::DoReadLoop(int result) { 1022 int SSLClientSocketOpenSSL::DoReadLoop() {
1022 if (result < 0)
1023 return result;
1024
1025 bool network_moved; 1023 bool network_moved;
Ryan Sleevi 2014/06/18 01:39:53 I'm having trouble reasoning why this deletion is
davidben 2014/06/18 22:27:22 Hrm. Good point that there's an extra DoTransportI
1026 int rv; 1024 int rv;
1027 do { 1025 do {
1028 rv = DoPayloadRead(); 1026 rv = DoPayloadRead();
1029 network_moved = DoTransportIO(); 1027 network_moved = DoTransportIO();
1030 } while (rv == ERR_IO_PENDING && network_moved); 1028 } while (rv == ERR_IO_PENDING && network_moved);
1031 1029
1032 return rv; 1030 return rv;
1033 } 1031 }
1034 1032
1035 int SSLClientSocketOpenSSL::DoWriteLoop(int result) { 1033 int SSLClientSocketOpenSSL::DoWriteLoop() {
1036 if (result < 0)
1037 return result;
1038
1039 bool network_moved; 1034 bool network_moved;
1040 int rv; 1035 int rv;
1041 do { 1036 do {
1042 rv = DoPayloadWrite(); 1037 rv = DoPayloadWrite();
1043 network_moved = DoTransportIO(); 1038 network_moved = DoTransportIO();
1044 } while (rv == ERR_IO_PENDING && network_moved); 1039 } while (rv == ERR_IO_PENDING && network_moved);
1045 1040
1046 return rv; 1041 return rv;
1047 } 1042 }
1048 1043
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1085 if (total_bytes_read > 0) { 1080 if (total_bytes_read > 0) {
1086 pending_read_error_ = rv; 1081 pending_read_error_ = rv;
1087 rv = total_bytes_read; 1082 rv = total_bytes_read;
1088 next_result = &pending_read_error_; 1083 next_result = &pending_read_error_;
1089 } 1084 }
1090 1085
1091 if (client_auth_cert_needed_) { 1086 if (client_auth_cert_needed_) {
1092 *next_result = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; 1087 *next_result = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
1093 } else if (*next_result < 0) { 1088 } else if (*next_result < 0) {
1094 int err = SSL_get_error(ssl_, *next_result); 1089 int err = SSL_get_error(ssl_, *next_result);
1095 *next_result = MapOpenSSLError(err, err_tracer); 1090 *next_result = HandleOpenSSLError(err, err_tracer);
1096 if (rv > 0 && *next_result == ERR_IO_PENDING) { 1091 if (rv > 0 && *next_result == ERR_IO_PENDING) {
1097 // If at least some data was read from SSL_read(), do not treat 1092 // 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 1093 // insufficient data as an error to return in the next call to
1099 // DoPayloadRead() - instead, let the call fall through to check 1094 // DoPayloadRead() - instead, let the call fall through to check
1100 // SSL_read() again. This is because DoTransportIO() may complete 1095 // SSL_read() again. This is because DoTransportIO() may complete
1101 // in between the next call to DoPayloadRead(), and thus it is 1096 // in between the next call to DoPayloadRead(), and thus it is
1102 // important to check SSL_read() on subsequent invocations to see 1097 // important to check SSL_read() on subsequent invocations to see
1103 // if a complete record may now be read. 1098 // if a complete record may now be read.
1104 *next_result = kNoPendingReadResult; 1099 *next_result = kNoPendingReadResult;
1105 } 1100 }
1106 } 1101 }
1107 } 1102 }
1108 1103
1109 if (rv >= 0) { 1104 if (rv >= 0) {
1110 net_log_.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_RECEIVED, rv, 1105 net_log_.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_RECEIVED, rv,
1111 user_read_buf_->data()); 1106 user_read_buf_->data());
1112 } 1107 }
1113 return rv; 1108 return rv;
1114 } 1109 }
1115 1110
1116 int SSLClientSocketOpenSSL::DoPayloadWrite() { 1111 int SSLClientSocketOpenSSL::DoPayloadWrite() {
1117 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 1112 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
1118 int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_); 1113 int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_);
1119 1114
1120 if (rv >= 0) { 1115 if (rv >= 0) {
1121 net_log_.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_SENT, rv, 1116 net_log_.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_SENT, rv,
1122 user_write_buf_->data()); 1117 user_write_buf_->data());
1123 return rv; 1118 return rv;
1124 } 1119 }
1125 1120
1126 int err = SSL_get_error(ssl_, rv); 1121 int err = SSL_get_error(ssl_, rv);
1127 return MapOpenSSLError(err, err_tracer); 1122 return HandleOpenSSLError(err, err_tracer);
1128 } 1123 }
1129 1124
1130 int SSLClientSocketOpenSSL::BufferSend(void) { 1125 int SSLClientSocketOpenSSL::BufferSend(void) {
1131 if (transport_send_busy_) 1126 if (transport_send_busy_)
1132 return ERR_IO_PENDING; 1127 return ERR_IO_PENDING;
1133 1128
1134 if (!send_buffer_.get()) { 1129 if (!send_buffer_.get()) {
1135 // Get a fresh send buffer out of the send BIO. 1130 // Get a fresh send buffer out of the send BIO.
1136 size_t max_read = BIO_ctrl_pending(transport_bio_); 1131 size_t max_read = BIO_ctrl_pending(transport_bio_);
1137 if (!max_read) 1132 if (!max_read)
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1203 1198
1204 void SSLClientSocketOpenSSL::BufferRecvComplete(int result) { 1199 void SSLClientSocketOpenSSL::BufferRecvComplete(int result) {
1205 result = TransportReadComplete(result); 1200 result = TransportReadComplete(result);
1206 OnRecvComplete(result); 1201 OnRecvComplete(result);
1207 } 1202 }
1208 1203
1209 void SSLClientSocketOpenSSL::TransportWriteComplete(int result) { 1204 void SSLClientSocketOpenSSL::TransportWriteComplete(int result) {
1210 DCHECK(ERR_IO_PENDING != result); 1205 DCHECK(ERR_IO_PENDING != result);
1211 if (result < 0) { 1206 if (result < 0) {
1212 // Got a socket write error; close the BIO to indicate this upward. 1207 // Got a socket write error; close the BIO to indicate this upward.
1213 //
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; 1208 DVLOG(1) << "TransportWriteComplete error " << result;
1218 (void)BIO_shutdown_wr(SSL_get_wbio(ssl_)); 1209 (void)BIO_shutdown_wr(SSL_get_wbio(ssl_));
1219 1210
1220 // Match the fix for http://crbug.com/249848 in NSS by erroring future reads 1211 // Record the error. Save it to be reported in a future read or write on
1221 // from the socket after a write error. 1212 // transport_bio_'s peer.
1222 //
1223 // TODO(davidben): Avoid having read and write ends interact this way.
1224 transport_write_error_ = result; 1213 transport_write_error_ = result;
1225 (void)BIO_shutdown_wr(transport_bio_);
1226 send_buffer_ = NULL; 1214 send_buffer_ = NULL;
1227 } else { 1215 } else {
1228 DCHECK(send_buffer_.get()); 1216 DCHECK(send_buffer_.get());
1229 send_buffer_->DidConsume(result); 1217 send_buffer_->DidConsume(result);
1230 DCHECK_GE(send_buffer_->BytesRemaining(), 0); 1218 DCHECK_GE(send_buffer_->BytesRemaining(), 0);
1231 if (send_buffer_->BytesRemaining() <= 0) 1219 if (send_buffer_->BytesRemaining() <= 0)
1232 send_buffer_ = NULL; 1220 send_buffer_ = NULL;
1233 } 1221 }
1234 } 1222 }
1235 1223
1236 int SSLClientSocketOpenSSL::TransportReadComplete(int result) { 1224 int SSLClientSocketOpenSSL::TransportReadComplete(int result) {
1237 DCHECK(ERR_IO_PENDING != result); 1225 DCHECK(ERR_IO_PENDING != result);
1238 if (result <= 0) { 1226 // If an EOF, canonicalize to ERR_CONNECTION_CLOSED here so HandleOpenSSLError
1227 // does not report success.
1228 if (result == 0)
1229 result = ERR_CONNECTION_CLOSED;
1230 if (result < 0) {
1239 DVLOG(1) << "TransportReadComplete result " << result; 1231 DVLOG(1) << "TransportReadComplete result " << result;
1240 // Received 0 (end of file) or an error. Either way, bubble it up to the 1232 // 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 1233 // read on transport_bio_'s peer.
1242 // relay up to the SSL socket client (i.e. via DoReadCallback). 1234 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 { 1235 } else {
1252 DCHECK(recv_buffer_.get()); 1236 DCHECK(recv_buffer_.get());
1253 int ret = BIO_write(transport_bio_, recv_buffer_->data(), result); 1237 int ret = BIO_write(transport_bio_, recv_buffer_->data(), result);
1254 // A write into a memory BIO should always succeed. 1238 // A write into a memory BIO should always succeed.
1255 DCHECK_EQ(result, ret); 1239 DCHECK_EQ(result, ret);
1256 } 1240 }
1257 recv_buffer_ = NULL; 1241 recv_buffer_ = NULL;
1258 transport_recv_busy_ = false; 1242 transport_recv_busy_ = false;
1259 return result; 1243 return result;
1260 } 1244 }
1261 1245
1246 int SSLClientSocketOpenSSL::HandleOpenSSLError(
1247 int ssl_error,
1248 const crypto::OpenSSLErrStackTracer& tracer) {
1249 // Route transport failures around OpenSSL. Use |ssl_error| to determine
Ryan Sleevi 2014/06/18 01:39:52 It's unclear what you mean by "around OpenSSL" Th
davidben 2014/06/18 22:27:22 Rewrote comment.
1250 // whether to use the read or write failure on the transport. This is done in
1251 // lieu of routing net errors though OpenSSL's error system.
1252 if (ssl_error == SSL_ERROR_WANT_READ) {
1253 // If OpenSSL wanted read data, report any pending errors that were
1254 // observed. Note that both |transport_read_error_| and
1255 // |transport_write_error_| are checked, since the application may have
1256 // encountered a socket error while writing that would otherwise not be
1257 // reported until the application attempted to write again - which it may
1258 // never do. This matches the fix for https://crbug.com/249848 in NSS.
Ryan Sleevi 2014/06/18 01:39:53 I think I'm getting confused by your actor model,
davidben 2014/06/18 22:27:22 I actually do mean if OpenSSL wanted to read data.
Ryan Sleevi 2014/06/19 00:27:06 Ok, hereby declaring a moratorium on the personifi
1259 if (transport_read_error_ != 0)
1260 return transport_read_error_;
1261 if (transport_write_error_ != 0)
1262 return transport_write_error_;
1263 } else if (ssl_error == SSL_ERROR_SSL) {
1264 // On transport write failure, BIO_R_BROKEN_PIPE will be pushed on the error
1265 // queue. Use this to signal transport write failure.
Ryan Sleevi 2014/06/18 01:39:52 "On transport write failure, ... Use this to signa
davidben 2014/06/18 22:27:22 Rephrased it a little.
1266 //
1267 // Because of the write buffer, this reports a failure from the previous
1268 // write payload. If the current payload fails to write, the error will be
1269 // reported in a future write or read.
Ryan Sleevi 2014/06/18 01:39:52 s/write or read/call to XXX or YYY/
davidben 2014/06/18 22:27:22 Elaborated.
1270 unsigned long error = ERR_peek_error();
1271 if (error &&
1272 ERR_GET_LIB(error) == ERR_LIB_BIO &&
1273 ERR_GET_REASON(error) == BIO_R_BROKEN_PIPE) {
1274 DCHECK_NE(0, transport_write_error_);
1275 return transport_write_error_;
1276 }
1277 }
1278
1279 // Otherwise, map the error code.
1280 return MapOpenSSLError(ssl_error, tracer);
1281 }
1282
1262 int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl, 1283 int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl,
1263 X509** x509, 1284 X509** x509,
1264 EVP_PKEY** pkey) { 1285 EVP_PKEY** pkey) {
1265 DVLOG(3) << "OpenSSL ClientCertRequestCallback called"; 1286 DVLOG(3) << "OpenSSL ClientCertRequestCallback called";
1266 DCHECK(ssl == ssl_); 1287 DCHECK(ssl == ssl_);
1267 DCHECK(*x509 == NULL); 1288 DCHECK(*x509 == NULL);
1268 DCHECK(*pkey == NULL); 1289 DCHECK(*pkey == NULL);
1269 if (!ssl_config_.send_client_cert) { 1290 if (!ssl_config_.send_client_cert) {
1270 // First pass: we know that a client certificate is needed, but we do not 1291 // First pass: we know that a client certificate is needed, but we do not
1271 // have one at hand. 1292 // have one at hand.
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1430 DVLOG(2) << "next protocol: '" << npn_proto_ << "' status: " << npn_status_; 1451 DVLOG(2) << "next protocol: '" << npn_proto_ << "' status: " << npn_status_;
1431 return SSL_TLSEXT_ERR_OK; 1452 return SSL_TLSEXT_ERR_OK;
1432 } 1453 }
1433 1454
1434 scoped_refptr<X509Certificate> 1455 scoped_refptr<X509Certificate>
1435 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { 1456 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const {
1436 return server_cert_; 1457 return server_cert_;
1437 } 1458 }
1438 1459
1439 } // namespace net 1460 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698