| 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 #endif | 61 #endif |
| 62 | 62 |
| 63 // This constant can be any non-negative/non-zero value (eg: it does not | 63 // This constant can be any non-negative/non-zero value (eg: it does not |
| 64 // overlap with any value of the net::Error range, including net::OK). | 64 // overlap with any value of the net::Error range, including net::OK). |
| 65 const int kNoPendingReadResult = 1; | 65 const int kNoPendingReadResult = 1; |
| 66 | 66 |
| 67 // If a client doesn't have a list of protocols that it supports, but | 67 // If a client doesn't have a list of protocols that it supports, but |
| 68 // the server supports NPN, choosing "http/1.1" is the best answer. | 68 // the server supports NPN, choosing "http/1.1" is the best answer. |
| 69 const char kDefaultSupportedNPNProtocol[] = "http/1.1"; | 69 const char kDefaultSupportedNPNProtocol[] = "http/1.1"; |
| 70 | 70 |
| 71 // Default size of the internal BoringSSL buffers. |
| 72 const int KDefaultOpenSSLBufferSize = 17 * 1024; |
| 73 |
| 71 void FreeX509Stack(STACK_OF(X509)* ptr) { | 74 void FreeX509Stack(STACK_OF(X509)* ptr) { |
| 72 sk_X509_pop_free(ptr, X509_free); | 75 sk_X509_pop_free(ptr, X509_free); |
| 73 } | 76 } |
| 74 | 77 |
| 75 typedef crypto::ScopedOpenSSL<X509, X509_free>::Type ScopedX509; | 78 typedef crypto::ScopedOpenSSL<X509, X509_free>::Type ScopedX509; |
| 76 typedef crypto::ScopedOpenSSL<STACK_OF(X509), FreeX509Stack>::Type | 79 typedef crypto::ScopedOpenSSL<STACK_OF(X509), FreeX509Stack>::Type |
| 77 ScopedX509Stack; | 80 ScopedX509Stack; |
| 78 | 81 |
| 79 #if OPENSSL_VERSION_NUMBER < 0x1000103fL | 82 #if OPENSSL_VERSION_NUMBER < 0x1000103fL |
| 80 // This method doesn't seem to have made it into the OpenSSL headers. | 83 // This method doesn't seem to have made it into the OpenSSL headers. |
| (...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 721 | 724 |
| 722 if (!SSL_set_tlsext_host_name(ssl_, host_and_port_.host().c_str())) | 725 if (!SSL_set_tlsext_host_name(ssl_, host_and_port_.host().c_str())) |
| 723 return ERR_UNEXPECTED; | 726 return ERR_UNEXPECTED; |
| 724 | 727 |
| 725 // Set an OpenSSL callback to monitor this SSL*'s connection. | 728 // Set an OpenSSL callback to monitor this SSL*'s connection. |
| 726 SSL_set_info_callback(ssl_, &InfoCallback); | 729 SSL_set_info_callback(ssl_, &InfoCallback); |
| 727 | 730 |
| 728 trying_cached_session_ = context->session_cache()->SetSSLSessionWithKey( | 731 trying_cached_session_ = context->session_cache()->SetSSLSessionWithKey( |
| 729 ssl_, GetSessionCacheKey()); | 732 ssl_, GetSessionCacheKey()); |
| 730 | 733 |
| 734 send_buffer_ = new GrowableIOBuffer(); |
| 735 send_buffer_->SetCapacity(KDefaultOpenSSLBufferSize); |
| 736 recv_buffer_ = new GrowableIOBuffer(); |
| 737 recv_buffer_->SetCapacity(KDefaultOpenSSLBufferSize); |
| 738 |
| 731 BIO* ssl_bio = NULL; | 739 BIO* ssl_bio = NULL; |
| 732 // 0 => use default buffer sizes. | 740 |
| 733 if (!BIO_new_bio_pair(&ssl_bio, 0, &transport_bio_, 0)) | 741 // SSLClientSocketOpenSSL retains ownership of the BIO buffers. |
| 742 if (!BIO_new_bio_pair_external_buf( |
| 743 &ssl_bio, send_buffer_->capacity(), |
| 744 reinterpret_cast<uint8_t*>(send_buffer_->data()), &transport_bio_, |
| 745 recv_buffer_->capacity(), |
| 746 reinterpret_cast<uint8_t*>(recv_buffer_->data()))) |
| 734 return ERR_UNEXPECTED; | 747 return ERR_UNEXPECTED; |
| 735 DCHECK(ssl_bio); | 748 DCHECK(ssl_bio); |
| 736 DCHECK(transport_bio_); | 749 DCHECK(transport_bio_); |
| 737 | 750 |
| 738 // Install a callback on OpenSSL's end to plumb transport errors through. | 751 // Install a callback on OpenSSL's end to plumb transport errors through. |
| 739 BIO_set_callback(ssl_bio, BIOCallback); | 752 BIO_set_callback(ssl_bio, BIOCallback); |
| 740 BIO_set_callback_arg(ssl_bio, reinterpret_cast<char*>(this)); | 753 BIO_set_callback_arg(ssl_bio, reinterpret_cast<char*>(this)); |
| 741 | 754 |
| 742 SSL_set_bio(ssl_, ssl_bio, ssl_bio); | 755 SSL_set_bio(ssl_, ssl_bio, ssl_bio); |
| 743 | 756 |
| (...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1523 NetLog::TYPE_SSL_WRITE_ERROR, | 1536 NetLog::TYPE_SSL_WRITE_ERROR, |
| 1524 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info)); | 1537 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info)); |
| 1525 } | 1538 } |
| 1526 return net_error; | 1539 return net_error; |
| 1527 } | 1540 } |
| 1528 | 1541 |
| 1529 int SSLClientSocketOpenSSL::BufferSend(void) { | 1542 int SSLClientSocketOpenSSL::BufferSend(void) { |
| 1530 if (transport_send_busy_) | 1543 if (transport_send_busy_) |
| 1531 return ERR_IO_PENDING; | 1544 return ERR_IO_PENDING; |
| 1532 | 1545 |
| 1533 if (!send_buffer_.get()) { | 1546 size_t buffer_read_offset; |
| 1534 // Get a fresh send buffer out of the send BIO. | 1547 uint8_t* read_buf; |
| 1535 size_t max_read = BIO_pending(transport_bio_); | 1548 size_t max_read; |
| 1536 if (!max_read) | 1549 int status = BIO_zero_copy_get_read_buf(transport_bio_, &read_buf, |
| 1537 return 0; // Nothing pending in the OpenSSL write BIO. | 1550 &buffer_read_offset, &max_read); |
| 1538 send_buffer_ = new DrainableIOBuffer(new IOBuffer(max_read), max_read); | 1551 DCHECK_EQ(status, 1); // Should never fail. |
| 1539 int read_bytes = BIO_read(transport_bio_, send_buffer_->data(), max_read); | 1552 if (!max_read) |
| 1540 DCHECK_GT(read_bytes, 0); | 1553 return 0; // Nothing pending in the OpenSSL write BIO. |
| 1541 CHECK_EQ(static_cast<int>(max_read), read_bytes); | 1554 CHECK_EQ(read_buf, reinterpret_cast<uint8_t*>(send_buffer_->StartOfBuffer())); |
| 1542 } | 1555 CHECK_LT(buffer_read_offset, static_cast<size_t>(send_buffer_->capacity())); |
| 1556 send_buffer_->set_offset(buffer_read_offset); |
| 1543 | 1557 |
| 1544 int rv = transport_->socket()->Write( | 1558 int rv = transport_->socket()->Write( |
| 1545 send_buffer_.get(), | 1559 send_buffer_.get(), max_read, |
| 1546 send_buffer_->BytesRemaining(), | |
| 1547 base::Bind(&SSLClientSocketOpenSSL::BufferSendComplete, | 1560 base::Bind(&SSLClientSocketOpenSSL::BufferSendComplete, |
| 1548 base::Unretained(this))); | 1561 base::Unretained(this))); |
| 1549 if (rv == ERR_IO_PENDING) { | 1562 if (rv == ERR_IO_PENDING) { |
| 1550 transport_send_busy_ = true; | 1563 transport_send_busy_ = true; |
| 1551 } else { | 1564 } else { |
| 1552 TransportWriteComplete(rv); | 1565 TransportWriteComplete(rv); |
| 1553 } | 1566 } |
| 1554 return rv; | 1567 return rv; |
| 1555 } | 1568 } |
| 1556 | 1569 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1569 } | 1582 } |
| 1570 | 1583 |
| 1571 // Known Issue: While only reading |requested| data is the more correct | 1584 // Known Issue: While only reading |requested| data is the more correct |
| 1572 // implementation, it has the downside of resulting in frequent reads: | 1585 // implementation, it has the downside of resulting in frequent reads: |
| 1573 // One read for the SSL record header (~5 bytes) and one read for the SSL | 1586 // One read for the SSL record header (~5 bytes) and one read for the SSL |
| 1574 // record body. Rather than issuing these reads to the underlying socket | 1587 // record body. Rather than issuing these reads to the underlying socket |
| 1575 // (and constantly allocating new IOBuffers), a single Read() request to | 1588 // (and constantly allocating new IOBuffers), a single Read() request to |
| 1576 // fill |transport_bio_| is issued. As long as an SSL client socket cannot | 1589 // fill |transport_bio_| is issued. As long as an SSL client socket cannot |
| 1577 // be gracefully shutdown (via SSL close alerts) and re-used for non-SSL | 1590 // be gracefully shutdown (via SSL close alerts) and re-used for non-SSL |
| 1578 // traffic, this over-subscribed Read()ing will not cause issues. | 1591 // traffic, this over-subscribed Read()ing will not cause issues. |
| 1579 size_t max_write = BIO_ctrl_get_write_guarantee(transport_bio_); | 1592 |
| 1593 size_t buffer_write_offset; |
| 1594 uint8_t* write_buf; |
| 1595 size_t max_write; |
| 1596 int status = BIO_zero_copy_get_write_buf(transport_bio_, &write_buf, |
| 1597 &buffer_write_offset, &max_write); |
| 1598 DCHECK_EQ(status, 1); // Should never fail. |
| 1580 if (!max_write) | 1599 if (!max_write) |
| 1581 return ERR_IO_PENDING; | 1600 return ERR_IO_PENDING; |
| 1582 | 1601 |
| 1583 recv_buffer_ = new IOBuffer(max_write); | 1602 CHECK_EQ(write_buf, |
| 1603 reinterpret_cast<uint8_t*>(recv_buffer_->StartOfBuffer())); |
| 1604 CHECK_LT(buffer_write_offset, static_cast<size_t>(recv_buffer_->capacity())); |
| 1605 |
| 1606 recv_buffer_->set_offset(buffer_write_offset); |
| 1584 int rv = transport_->socket()->Read( | 1607 int rv = transport_->socket()->Read( |
| 1585 recv_buffer_.get(), | 1608 recv_buffer_.get(), |
| 1586 max_write, | 1609 max_write, |
| 1587 base::Bind(&SSLClientSocketOpenSSL::BufferRecvComplete, | 1610 base::Bind(&SSLClientSocketOpenSSL::BufferRecvComplete, |
| 1588 base::Unretained(this))); | 1611 base::Unretained(this))); |
| 1589 if (rv == ERR_IO_PENDING) { | 1612 if (rv == ERR_IO_PENDING) { |
| 1590 transport_recv_busy_ = true; | 1613 transport_recv_busy_ = true; |
| 1591 } else { | 1614 } else { |
| 1592 rv = TransportReadComplete(rv); | 1615 rv = TransportReadComplete(rv); |
| 1593 } | 1616 } |
| 1594 return rv; | 1617 return rv; |
| 1595 } | 1618 } |
| 1596 | 1619 |
| 1597 void SSLClientSocketOpenSSL::BufferSendComplete(int result) { | 1620 void SSLClientSocketOpenSSL::BufferSendComplete(int result) { |
| 1598 transport_send_busy_ = false; | |
| 1599 TransportWriteComplete(result); | 1621 TransportWriteComplete(result); |
| 1600 OnSendComplete(result); | 1622 OnSendComplete(result); |
| 1601 } | 1623 } |
| 1602 | 1624 |
| 1603 void SSLClientSocketOpenSSL::BufferRecvComplete(int result) { | 1625 void SSLClientSocketOpenSSL::BufferRecvComplete(int result) { |
| 1604 result = TransportReadComplete(result); | 1626 result = TransportReadComplete(result); |
| 1605 OnRecvComplete(result); | 1627 OnRecvComplete(result); |
| 1606 } | 1628 } |
| 1607 | 1629 |
| 1608 void SSLClientSocketOpenSSL::TransportWriteComplete(int result) { | 1630 void SSLClientSocketOpenSSL::TransportWriteComplete(int result) { |
| 1609 DCHECK(ERR_IO_PENDING != result); | 1631 DCHECK(ERR_IO_PENDING != result); |
| 1632 int bytes_written = 0; |
| 1610 if (result < 0) { | 1633 if (result < 0) { |
| 1611 // Record the error. Save it to be reported in a future read or write on | 1634 // Record the error. Save it to be reported in a future read or write on |
| 1612 // transport_bio_'s peer. | 1635 // transport_bio_'s peer. |
| 1613 transport_write_error_ = result; | 1636 transport_write_error_ = result; |
| 1614 send_buffer_ = NULL; | |
| 1615 } else { | 1637 } else { |
| 1616 DCHECK(send_buffer_.get()); | 1638 bytes_written = result; |
| 1617 send_buffer_->DidConsume(result); | |
| 1618 DCHECK_GE(send_buffer_->BytesRemaining(), 0); | |
| 1619 if (send_buffer_->BytesRemaining() <= 0) | |
| 1620 send_buffer_ = NULL; | |
| 1621 } | 1639 } |
| 1640 DCHECK_GE(send_buffer_->RemainingCapacity(), bytes_written); |
| 1641 int ret = BIO_zero_copy_get_read_buf_done(transport_bio_, bytes_written); |
| 1642 DCHECK_EQ(1, ret); |
| 1643 transport_send_busy_ = false; |
| 1622 } | 1644 } |
| 1623 | 1645 |
| 1624 int SSLClientSocketOpenSSL::TransportReadComplete(int result) { | 1646 int SSLClientSocketOpenSSL::TransportReadComplete(int result) { |
| 1625 DCHECK(ERR_IO_PENDING != result); | 1647 DCHECK(ERR_IO_PENDING != result); |
| 1626 // If an EOF, canonicalize to ERR_CONNECTION_CLOSED here so MapOpenSSLError | 1648 // If an EOF, canonicalize to ERR_CONNECTION_CLOSED here so MapOpenSSLError |
| 1627 // does not report success. | 1649 // does not report success. |
| 1628 if (result == 0) | 1650 if (result == 0) |
| 1629 result = ERR_CONNECTION_CLOSED; | 1651 result = ERR_CONNECTION_CLOSED; |
| 1652 int bytes_read = 0; |
| 1630 if (result < 0) { | 1653 if (result < 0) { |
| 1631 DVLOG(1) << "TransportReadComplete result " << result; | 1654 DVLOG(1) << "TransportReadComplete result " << result; |
| 1632 // Received an error. Save it to be reported in a future read on | 1655 // Received an error. Save it to be reported in a future read on |
| 1633 // transport_bio_'s peer. | 1656 // transport_bio_'s peer. |
| 1634 transport_read_error_ = result; | 1657 transport_read_error_ = result; |
| 1635 } else { | 1658 } else { |
| 1636 DCHECK(recv_buffer_.get()); | 1659 bytes_read = result; |
| 1637 int ret = BIO_write(transport_bio_, recv_buffer_->data(), result); | |
| 1638 // A write into a memory BIO should always succeed. | |
| 1639 DCHECK_EQ(result, ret); | |
| 1640 } | 1660 } |
| 1641 recv_buffer_ = NULL; | 1661 DCHECK_GE(recv_buffer_->RemainingCapacity(), bytes_read); |
| 1662 int ret = BIO_zero_copy_get_write_buf_done(transport_bio_, bytes_read); |
| 1663 DCHECK_EQ(1, ret); |
| 1642 transport_recv_busy_ = false; | 1664 transport_recv_busy_ = false; |
| 1643 return result; | 1665 return result; |
| 1644 } | 1666 } |
| 1645 | 1667 |
| 1646 int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl) { | 1668 int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl) { |
| 1647 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. | 1669 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. |
| 1648 tracked_objects::ScopedTracker tracking_profile( | 1670 tracked_objects::ScopedTracker tracking_profile( |
| 1649 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1671 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 1650 "424386 SSLClientSocketOpenSSL::ClientCertRequestCallback")); | 1672 "424386 SSLClientSocketOpenSSL::ClientCertRequestCallback")); |
| 1651 | 1673 |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1923 ct::SCT_STATUS_LOG_UNKNOWN)); | 1945 ct::SCT_STATUS_LOG_UNKNOWN)); |
| 1924 } | 1946 } |
| 1925 } | 1947 } |
| 1926 | 1948 |
| 1927 scoped_refptr<X509Certificate> | 1949 scoped_refptr<X509Certificate> |
| 1928 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { | 1950 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { |
| 1929 return server_cert_; | 1951 return server_cert_; |
| 1930 } | 1952 } |
| 1931 | 1953 |
| 1932 } // namespace net | 1954 } // namespace net |
| OLD | NEW |