Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |