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 |