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 |