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 1416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1427 rv = DoPayloadWrite(); | 1427 rv = DoPayloadWrite(); |
1428 network_moved = DoTransportIO(); | 1428 network_moved = DoTransportIO(); |
1429 } while (rv == ERR_IO_PENDING && network_moved); | 1429 } while (rv == ERR_IO_PENDING && network_moved); |
1430 | 1430 |
1431 return rv; | 1431 return rv; |
1432 } | 1432 } |
1433 | 1433 |
1434 int SSLClientSocketOpenSSL::DoPayloadRead() { | 1434 int SSLClientSocketOpenSSL::DoPayloadRead() { |
1435 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | 1435 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
1436 | 1436 |
| 1437 DCHECK_LT(0, user_read_buf_len_); |
| 1438 DCHECK(user_read_buf_.get()); |
| 1439 |
1437 int rv; | 1440 int rv; |
1438 if (pending_read_error_ != kNoPendingReadResult) { | 1441 if (pending_read_error_ != kNoPendingReadResult) { |
1439 rv = pending_read_error_; | 1442 rv = pending_read_error_; |
1440 pending_read_error_ = kNoPendingReadResult; | 1443 pending_read_error_ = kNoPendingReadResult; |
1441 if (rv == 0) { | 1444 if (rv == 0) { |
1442 net_log_.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_RECEIVED, | 1445 net_log_.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_RECEIVED, |
1443 rv, user_read_buf_->data()); | 1446 rv, user_read_buf_->data()); |
1444 } else { | 1447 } else { |
1445 net_log_.AddEvent( | 1448 net_log_.AddEvent( |
1446 NetLog::TYPE_SSL_READ_ERROR, | 1449 NetLog::TYPE_SSL_READ_ERROR, |
1447 CreateNetLogOpenSSLErrorCallback(rv, pending_read_ssl_error_, | 1450 CreateNetLogOpenSSLErrorCallback(rv, pending_read_ssl_error_, |
1448 pending_read_error_info_)); | 1451 pending_read_error_info_)); |
1449 } | 1452 } |
1450 pending_read_ssl_error_ = SSL_ERROR_NONE; | 1453 pending_read_ssl_error_ = SSL_ERROR_NONE; |
1451 pending_read_error_info_ = OpenSSLErrorInfo(); | 1454 pending_read_error_info_ = OpenSSLErrorInfo(); |
1452 return rv; | 1455 return rv; |
1453 } | 1456 } |
1454 | 1457 |
1455 int total_bytes_read = 0; | 1458 int total_bytes_read = 0; |
| 1459 int ssl_ret; |
1456 do { | 1460 do { |
1457 rv = SSL_read(ssl_, user_read_buf_->data() + total_bytes_read, | 1461 ssl_ret = SSL_read(ssl_, user_read_buf_->data() + total_bytes_read, |
1458 user_read_buf_len_ - total_bytes_read); | 1462 user_read_buf_len_ - total_bytes_read); |
1459 if (rv > 0) | 1463 if (ssl_ret > 0) |
1460 total_bytes_read += rv; | 1464 total_bytes_read += ssl_ret; |
1461 } while (total_bytes_read < user_read_buf_len_ && rv > 0); | 1465 } while (total_bytes_read < user_read_buf_len_ && ssl_ret > 0); |
1462 | 1466 |
1463 if (total_bytes_read == user_read_buf_len_) { | 1467 // Although only the final SSL_read call may have failed, the failure needs to |
1464 rv = total_bytes_read; | 1468 // processed immediately, while the information still available in OpenSSL's |
1465 } else { | 1469 // error queue. |
1466 // Otherwise, an error occurred (rv <= 0). The error needs to be handled | 1470 if (client_auth_cert_needed_) { |
1467 // immediately, while the OpenSSL errors are still available in | 1471 pending_read_error_ = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; |
1468 // thread-local storage. However, the handled/remapped error code should | 1472 } else if (ssl_ret <= 0) { |
1469 // only be returned if no application data was already read; if it was, the | 1473 // A zero return from SSL_read may mean any of: |
1470 // error code should be deferred until the next call of DoPayloadRead. | 1474 // - The underlying BIO_read returned 0. |
| 1475 // - The peer sent a close_notify. |
| 1476 // - Any arbitrary error. https://crbug.com/466303 |
1471 // | 1477 // |
1472 // If no data was read, |*next_result| will point to the return value of | 1478 // TransportReadComplete converts the first to an ERR_CONNECTION_CLOSED |
1473 // this function. If at least some data was read, |*next_result| will point | 1479 // error, so it does not occur. The second and third are distinguished by |
1474 // to |pending_read_error_|, to be returned in a future call to | 1480 // SSL_ERROR_ZERO_RETURN. |
1475 // DoPayloadRead() (e.g.: after the current data is handled). | 1481 pending_read_ssl_error_ = SSL_get_error(ssl_, ssl_ret); |
1476 int *next_result = &rv; | 1482 if (pending_read_ssl_error_ == SSL_ERROR_ZERO_RETURN) { |
1477 if (total_bytes_read > 0) { | 1483 pending_read_error_ = 0; |
1478 pending_read_error_ = rv; | 1484 } else { |
1479 rv = total_bytes_read; | 1485 pending_read_error_ = MapOpenSSLErrorWithDetails( |
1480 next_result = &pending_read_error_; | 1486 pending_read_ssl_error_, err_tracer, &pending_read_error_info_); |
1481 } | 1487 } |
1482 | 1488 |
1483 if (client_auth_cert_needed_) { | 1489 // Many servers do not reliably send a close_notify alert when shutting down |
1484 *next_result = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; | 1490 // a connection, and instead terminate the TCP connection. This is reported |
1485 } else if (*next_result <= 0) { | 1491 // as ERR_CONNECTION_CLOSED. Because of this, map the unclean shutdown to a |
1486 // A zero return from SSL_read may mean any of: | 1492 // graceful EOF, instead of treating it as an error as it should be. |
1487 // - The underlying BIO_read returned 0. | 1493 if (pending_read_error_ == ERR_CONNECTION_CLOSED) |
1488 // - The peer sent a close_notify. | 1494 pending_read_error_ = 0; |
1489 // - Any arbitrary error. https://crbug.com/466303 | 1495 } |
1490 // | |
1491 // TransportReadComplete converts the first to an ERR_CONNECTION_CLOSED | |
1492 // error, so it does not occur. The second and third are distinguished by | |
1493 // SSL_ERROR_ZERO_RETURN. | |
1494 pending_read_ssl_error_ = SSL_get_error(ssl_, *next_result); | |
1495 if (pending_read_ssl_error_ == SSL_ERROR_ZERO_RETURN) { | |
1496 *next_result = 0; | |
1497 } else { | |
1498 *next_result = MapOpenSSLErrorWithDetails( | |
1499 pending_read_ssl_error_, err_tracer, &pending_read_error_info_); | |
1500 } | |
1501 | 1496 |
1502 // Many servers do not reliably send a close_notify alert when shutting | 1497 if (total_bytes_read > 0) { |
1503 // down a connection, and instead terminate the TCP connection. This is | 1498 // Return any bytes read to the caller. The error will be deferred to the |
1504 // reported as ERR_CONNECTION_CLOSED. Because of this, map the unclean | 1499 // next call of DoPayloadRead. |
1505 // shutdown to a graceful EOF, instead of treating it as an error as it | 1500 rv = total_bytes_read; |
1506 // should be. | |
1507 if (*next_result == ERR_CONNECTION_CLOSED) | |
1508 *next_result = 0; | |
1509 | 1501 |
1510 if (rv > 0 && *next_result == ERR_IO_PENDING) { | 1502 // Do not treat insufficient data as an error to return in the next call to |
1511 // If at least some data was read from SSL_read(), do not treat | 1503 // DoPayloadRead() - instead, let the call fall through to check SSL_read() |
1512 // insufficient data as an error to return in the next call to | 1504 // again. This is because DoTransportIO() may complete in between the next |
1513 // DoPayloadRead() - instead, let the call fall through to check | 1505 // call to DoPayloadRead(), and thus it is important to check SSL_read() on |
1514 // SSL_read() again. This is because DoTransportIO() may complete | 1506 // subsequent invocations to see if a complete record may now be read. |
1515 // in between the next call to DoPayloadRead(), and thus it is | 1507 if (pending_read_error_ == ERR_IO_PENDING) |
1516 // important to check SSL_read() on subsequent invocations to see | 1508 pending_read_error_ = kNoPendingReadResult; |
1517 // if a complete record may now be read. | 1509 } else { |
1518 *next_result = kNoPendingReadResult; | 1510 // No bytes were returned. Return the pending read error immediately. |
1519 } | 1511 DCHECK_NE(kNoPendingReadResult, pending_read_error_); |
1520 } | 1512 rv = pending_read_error_; |
| 1513 pending_read_error_ = kNoPendingReadResult; |
1521 } | 1514 } |
1522 | 1515 |
1523 if (rv >= 0) { | 1516 if (rv >= 0) { |
1524 net_log_.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_RECEIVED, rv, | 1517 net_log_.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_RECEIVED, rv, |
1525 user_read_buf_->data()); | 1518 user_read_buf_->data()); |
1526 } else if (rv != ERR_IO_PENDING) { | 1519 } else if (rv != ERR_IO_PENDING) { |
1527 net_log_.AddEvent( | 1520 net_log_.AddEvent( |
1528 NetLog::TYPE_SSL_READ_ERROR, | 1521 NetLog::TYPE_SSL_READ_ERROR, |
1529 CreateNetLogOpenSSLErrorCallback(rv, pending_read_ssl_error_, | 1522 CreateNetLogOpenSSLErrorCallback(rv, pending_read_ssl_error_, |
1530 pending_read_error_info_)); | 1523 pending_read_error_info_)); |
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1971 | 1964 |
1972 return result; | 1965 return result; |
1973 } | 1966 } |
1974 | 1967 |
1975 scoped_refptr<X509Certificate> | 1968 scoped_refptr<X509Certificate> |
1976 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { | 1969 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { |
1977 return server_cert_; | 1970 return server_cert_; |
1978 } | 1971 } |
1979 | 1972 |
1980 } // namespace net | 1973 } // namespace net |
OLD | NEW |