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 <errno.h> | 10 #include <errno.h> |
| (...skipping 1516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1527 NetLog::TYPE_SSL_READ_ERROR, | 1527 NetLog::TYPE_SSL_READ_ERROR, |
| 1528 CreateNetLogOpenSSLErrorCallback(rv, pending_read_ssl_error_, | 1528 CreateNetLogOpenSSLErrorCallback(rv, pending_read_ssl_error_, |
| 1529 pending_read_error_info_)); | 1529 pending_read_error_info_)); |
| 1530 } | 1530 } |
| 1531 pending_read_ssl_error_ = SSL_ERROR_NONE; | 1531 pending_read_ssl_error_ = SSL_ERROR_NONE; |
| 1532 pending_read_error_info_ = OpenSSLErrorInfo(); | 1532 pending_read_error_info_ = OpenSSLErrorInfo(); |
| 1533 return rv; | 1533 return rv; |
| 1534 } | 1534 } |
| 1535 | 1535 |
| 1536 int total_bytes_read = 0; | 1536 int total_bytes_read = 0; |
| 1537 int ssl_ret; | |
| 1537 do { | 1538 do { |
| 1538 rv = SSL_read(ssl_, user_read_buf_->data() + total_bytes_read, | 1539 ssl_ret = SSL_read(ssl_, user_read_buf_->data() + total_bytes_read, |
| 1539 user_read_buf_len_ - total_bytes_read); | 1540 user_read_buf_len_ - total_bytes_read); |
| 1540 if (rv > 0) | 1541 if (ssl_ret > 0) |
| 1541 total_bytes_read += rv; | 1542 total_bytes_read += ssl_ret; |
| 1542 } while (total_bytes_read < user_read_buf_len_ && rv > 0); | 1543 } while (total_bytes_read < user_read_buf_len_ && ssl_ret > 0); |
| 1543 | 1544 |
| 1544 if (total_bytes_read == user_read_buf_len_) { | 1545 // Although only the final SSL_read call may have failed, the failure needs to |
| 1545 rv = total_bytes_read; | 1546 // processed immediately, while the information still available in OpenSSL's |
| 1546 } else { | 1547 // error queue. |
| 1547 // Otherwise, an error occurred (rv <= 0). The error needs to be handled | 1548 if (client_auth_cert_needed_) { |
| 1548 // immediately, while the OpenSSL errors are still available in | 1549 pending_read_error_ = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; |
| 1549 // thread-local storage. However, the handled/remapped error code should | 1550 } else if (ssl_ret <= 0) { |
|
Ryan Sleevi
2015/03/17 00:33:14
Why is this change correct?
Previously, this code
davidben
2015/03/20 20:46:04
Claim: Exactly one of ssl_ret <= 0 and total_bytes
| |
| 1550 // only be returned if no application data was already read; if it was, the | 1551 // A zero return from SSL_read may mean any of: |
| 1551 // error code should be deferred until the next call of DoPayloadRead. | 1552 // - The underlying BIO_read returned 0. |
| 1553 // - The peer sent a close_notify. | |
| 1554 // - Any arbitrary error. https://crbug.com/466303 | |
| 1552 // | 1555 // |
| 1553 // If no data was read, |*next_result| will point to the return value of | 1556 // TransportReadComplete converts the first to an ERR_CONNECTION_CLOSED |
| 1554 // this function. If at least some data was read, |*next_result| will point | 1557 // error, so it does not occur. The second and third are distinguished by |
| 1555 // to |pending_read_error_|, to be returned in a future call to | 1558 // SSL_ERROR_ZERO_RETURN. |
| 1556 // DoPayloadRead() (e.g.: after the current data is handled). | 1559 pending_read_ssl_error_ = SSL_get_error(ssl_, ssl_ret); |
| 1557 int *next_result = &rv; | 1560 if (pending_read_ssl_error_ == SSL_ERROR_ZERO_RETURN) { |
| 1558 if (total_bytes_read > 0) { | 1561 pending_read_error_ = 0; |
| 1559 pending_read_error_ = rv; | 1562 } else { |
| 1560 rv = total_bytes_read; | 1563 pending_read_error_ = MapOpenSSLErrorWithDetails( |
| 1561 next_result = &pending_read_error_; | 1564 pending_read_ssl_error_, err_tracer, &pending_read_error_info_); |
| 1562 } | 1565 } |
| 1563 | 1566 |
| 1564 if (client_auth_cert_needed_) { | 1567 // Many servers do not reliably send a close_notify alert when shutting down |
| 1565 *next_result = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; | 1568 // a connection, and instead terminate the TCP connection. This is reported |
| 1566 } else if (*next_result <= 0) { | 1569 // as ERR_CONNECTION_CLOSED. Because of this, map the unclean shutdown to a |
| 1567 // A zero return from SSL_read may mean any of: | 1570 // graceful EOF, instead of treating it as an error as it should be. |
| 1568 // - The underlying BIO_read returned 0. | 1571 if (pending_read_error_ == ERR_CONNECTION_CLOSED) |
| 1569 // - The peer sent a close_notify. | 1572 pending_read_error_ = 0; |
| 1570 // - Any arbitrary error. https://crbug.com/466303 | 1573 } |
| 1571 // | |
| 1572 // TransportReadComplete converts the first to an ERR_CONNECTION_CLOSED | |
| 1573 // error, so it does not occur. The second and third are distinguished by | |
| 1574 // SSL_ERROR_ZERO_RETURN. | |
| 1575 pending_read_ssl_error_ = SSL_get_error(ssl_, *next_result); | |
| 1576 if (pending_read_ssl_error_ == SSL_ERROR_ZERO_RETURN) { | |
| 1577 *next_result = 0; | |
| 1578 } else { | |
| 1579 *next_result = MapOpenSSLErrorWithDetails( | |
| 1580 pending_read_ssl_error_, err_tracer, &pending_read_error_info_); | |
| 1581 } | |
| 1582 | 1574 |
| 1583 // Many servers do not reliably send a close_notify alert when shutting | 1575 if (total_bytes_read > 0 || user_read_buf_len_ == 0) { |
|
Ryan Sleevi
2015/03/17 00:33:14
How is it possible for user_read_buf_len to equal
davidben
2015/03/20 20:46:04
I noticed that we don't actually have any checks t
| |
| 1584 // down a connection, and instead terminate the TCP connection. This is | 1576 // Return any bytes read to the caller. The error will be deferred to the |
| 1585 // reported as ERR_CONNECTION_CLOSED. Because of this, map the unclean | 1577 // next call of DoPayloadRead. |
| 1586 // shutdown to a graceful EOF, instead of treating it as an error as it | 1578 rv = total_bytes_read; |
| 1587 // should be. | |
| 1588 if (*next_result == ERR_CONNECTION_CLOSED) | |
| 1589 *next_result = 0; | |
| 1590 | 1579 |
| 1591 if (rv > 0 && *next_result == ERR_IO_PENDING) { | 1580 // Do not treat insufficient data as an error to return in the next call to |
| 1592 // If at least some data was read from SSL_read(), do not treat | 1581 // DoPayloadRead() - instead, let the call fall through to check SSL_read() |
| 1593 // insufficient data as an error to return in the next call to | 1582 // again. This is because DoTransportIO() may complete in between the next |
| 1594 // DoPayloadRead() - instead, let the call fall through to check | 1583 // call to DoPayloadRead(), and thus it is important to check SSL_read() on |
| 1595 // SSL_read() again. This is because DoTransportIO() may complete | 1584 // subsequent invocations to see if a complete record may now be read. |
| 1596 // in between the next call to DoPayloadRead(), and thus it is | 1585 if (pending_read_error_ == ERR_IO_PENDING) |
| 1597 // important to check SSL_read() on subsequent invocations to see | 1586 pending_read_error_ = kNoPendingReadResult; |
| 1598 // if a complete record may now be read. | 1587 } else { |
| 1599 *next_result = kNoPendingReadResult; | 1588 // No bytes were returned. Return the pending read error immediately. |
| 1600 } | 1589 DCHECK_NE(kNoPendingReadResult, pending_read_error_); |
| 1601 } | 1590 rv = pending_read_error_; |
| 1591 pending_read_error_ = kNoPendingReadResult; | |
| 1602 } | 1592 } |
| 1603 | 1593 |
| 1604 if (rv >= 0) { | 1594 if (rv >= 0) { |
| 1605 net_log_.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_RECEIVED, rv, | 1595 net_log_.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_RECEIVED, rv, |
| 1606 user_read_buf_->data()); | 1596 user_read_buf_->data()); |
| 1607 } else if (rv != ERR_IO_PENDING) { | 1597 } else if (rv != ERR_IO_PENDING) { |
| 1608 net_log_.AddEvent( | 1598 net_log_.AddEvent( |
| 1609 NetLog::TYPE_SSL_READ_ERROR, | 1599 NetLog::TYPE_SSL_READ_ERROR, |
| 1610 CreateNetLogOpenSSLErrorCallback(rv, pending_read_ssl_error_, | 1600 CreateNetLogOpenSSLErrorCallback(rv, pending_read_ssl_error_, |
| 1611 pending_read_error_info_)); | 1601 pending_read_error_info_)); |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2054 ct::SCT_STATUS_LOG_UNKNOWN)); | 2044 ct::SCT_STATUS_LOG_UNKNOWN)); |
| 2055 } | 2045 } |
| 2056 } | 2046 } |
| 2057 | 2047 |
| 2058 scoped_refptr<X509Certificate> | 2048 scoped_refptr<X509Certificate> |
| 2059 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { | 2049 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { |
| 2060 return server_cert_; | 2050 return server_cert_; |
| 2061 } | 2051 } |
| 2062 | 2052 |
| 2063 } // namespace net | 2053 } // namespace net |
| OLD | NEW |