Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(332)

Side by Side Diff: net/socket/ssl_client_socket_openssl.cc

Issue 822713002: Update from https://crrev.com/309415 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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 794 matching lines...) Expand 10 before | Expand all | Expand 10 after
1538 NetLog::TYPE_SSL_WRITE_ERROR, 1551 NetLog::TYPE_SSL_WRITE_ERROR,
1539 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info)); 1552 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info));
1540 } 1553 }
1541 return net_error; 1554 return net_error;
1542 } 1555 }
1543 1556
1544 int SSLClientSocketOpenSSL::BufferSend(void) { 1557 int SSLClientSocketOpenSSL::BufferSend(void) {
1545 if (transport_send_busy_) 1558 if (transport_send_busy_)
1546 return ERR_IO_PENDING; 1559 return ERR_IO_PENDING;
1547 1560
1548 if (!send_buffer_.get()) { 1561 size_t buffer_read_offset;
1549 // Get a fresh send buffer out of the send BIO. 1562 uint8_t* read_buf;
1550 size_t max_read = BIO_pending(transport_bio_); 1563 size_t max_read;
1551 if (!max_read) 1564 int status = BIO_zero_copy_get_read_buf(transport_bio_, &read_buf,
1552 return 0; // Nothing pending in the OpenSSL write BIO. 1565 &buffer_read_offset, &max_read);
1553 send_buffer_ = new DrainableIOBuffer(new IOBuffer(max_read), max_read); 1566 DCHECK_EQ(status, 1); // Should never fail.
1554 int read_bytes = BIO_read(transport_bio_, send_buffer_->data(), max_read); 1567 if (!max_read)
1555 DCHECK_GT(read_bytes, 0); 1568 return 0; // Nothing pending in the OpenSSL write BIO.
1556 CHECK_EQ(static_cast<int>(max_read), read_bytes); 1569 CHECK_EQ(read_buf, reinterpret_cast<uint8_t*>(send_buffer_->StartOfBuffer()));
1557 } 1570 CHECK_LT(buffer_read_offset, static_cast<size_t>(send_buffer_->capacity()));
1571 send_buffer_->set_offset(buffer_read_offset);
1558 1572
1559 int rv = transport_->socket()->Write( 1573 int rv = transport_->socket()->Write(
1560 send_buffer_.get(), 1574 send_buffer_.get(), max_read,
1561 send_buffer_->BytesRemaining(),
1562 base::Bind(&SSLClientSocketOpenSSL::BufferSendComplete, 1575 base::Bind(&SSLClientSocketOpenSSL::BufferSendComplete,
1563 base::Unretained(this))); 1576 base::Unretained(this)));
1564 if (rv == ERR_IO_PENDING) { 1577 if (rv == ERR_IO_PENDING) {
1565 transport_send_busy_ = true; 1578 transport_send_busy_ = true;
1566 } else { 1579 } else {
1567 TransportWriteComplete(rv); 1580 TransportWriteComplete(rv);
1568 } 1581 }
1569 return rv; 1582 return rv;
1570 } 1583 }
1571 1584
(...skipping 12 matching lines...) Expand all
1584 } 1597 }
1585 1598
1586 // Known Issue: While only reading |requested| data is the more correct 1599 // Known Issue: While only reading |requested| data is the more correct
1587 // implementation, it has the downside of resulting in frequent reads: 1600 // implementation, it has the downside of resulting in frequent reads:
1588 // One read for the SSL record header (~5 bytes) and one read for the SSL 1601 // One read for the SSL record header (~5 bytes) and one read for the SSL
1589 // record body. Rather than issuing these reads to the underlying socket 1602 // record body. Rather than issuing these reads to the underlying socket
1590 // (and constantly allocating new IOBuffers), a single Read() request to 1603 // (and constantly allocating new IOBuffers), a single Read() request to
1591 // fill |transport_bio_| is issued. As long as an SSL client socket cannot 1604 // fill |transport_bio_| is issued. As long as an SSL client socket cannot
1592 // be gracefully shutdown (via SSL close alerts) and re-used for non-SSL 1605 // be gracefully shutdown (via SSL close alerts) and re-used for non-SSL
1593 // traffic, this over-subscribed Read()ing will not cause issues. 1606 // traffic, this over-subscribed Read()ing will not cause issues.
1594 size_t max_write = BIO_ctrl_get_write_guarantee(transport_bio_); 1607
1608 size_t buffer_write_offset;
1609 uint8_t* write_buf;
1610 size_t max_write;
1611 int status = BIO_zero_copy_get_write_buf(transport_bio_, &write_buf,
1612 &buffer_write_offset, &max_write);
1613 DCHECK_EQ(status, 1); // Should never fail.
1595 if (!max_write) 1614 if (!max_write)
1596 return ERR_IO_PENDING; 1615 return ERR_IO_PENDING;
1597 1616
1598 recv_buffer_ = new IOBuffer(max_write); 1617 CHECK_EQ(write_buf,
1618 reinterpret_cast<uint8_t*>(recv_buffer_->StartOfBuffer()));
1619 CHECK_LT(buffer_write_offset, static_cast<size_t>(recv_buffer_->capacity()));
1620
1621 recv_buffer_->set_offset(buffer_write_offset);
1599 int rv = transport_->socket()->Read( 1622 int rv = transport_->socket()->Read(
1600 recv_buffer_.get(), 1623 recv_buffer_.get(),
1601 max_write, 1624 max_write,
1602 base::Bind(&SSLClientSocketOpenSSL::BufferRecvComplete, 1625 base::Bind(&SSLClientSocketOpenSSL::BufferRecvComplete,
1603 base::Unretained(this))); 1626 base::Unretained(this)));
1604 if (rv == ERR_IO_PENDING) { 1627 if (rv == ERR_IO_PENDING) {
1605 transport_recv_busy_ = true; 1628 transport_recv_busy_ = true;
1606 } else { 1629 } else {
1607 rv = TransportReadComplete(rv); 1630 rv = TransportReadComplete(rv);
1608 } 1631 }
1609 return rv; 1632 return rv;
1610 } 1633 }
1611 1634
1612 void SSLClientSocketOpenSSL::BufferSendComplete(int result) { 1635 void SSLClientSocketOpenSSL::BufferSendComplete(int result) {
1613 transport_send_busy_ = false;
1614 TransportWriteComplete(result); 1636 TransportWriteComplete(result);
1615 OnSendComplete(result); 1637 OnSendComplete(result);
1616 } 1638 }
1617 1639
1618 void SSLClientSocketOpenSSL::BufferRecvComplete(int result) { 1640 void SSLClientSocketOpenSSL::BufferRecvComplete(int result) {
1619 result = TransportReadComplete(result); 1641 result = TransportReadComplete(result);
1620 OnRecvComplete(result); 1642 OnRecvComplete(result);
1621 } 1643 }
1622 1644
1623 void SSLClientSocketOpenSSL::TransportWriteComplete(int result) { 1645 void SSLClientSocketOpenSSL::TransportWriteComplete(int result) {
1624 DCHECK(ERR_IO_PENDING != result); 1646 DCHECK(ERR_IO_PENDING != result);
1647 int bytes_written = 0;
1625 if (result < 0) { 1648 if (result < 0) {
1626 // Record the error. Save it to be reported in a future read or write on 1649 // Record the error. Save it to be reported in a future read or write on
1627 // transport_bio_'s peer. 1650 // transport_bio_'s peer.
1628 transport_write_error_ = result; 1651 transport_write_error_ = result;
1629 send_buffer_ = NULL;
1630 } else { 1652 } else {
1631 DCHECK(send_buffer_.get()); 1653 bytes_written = result;
1632 send_buffer_->DidConsume(result);
1633 DCHECK_GE(send_buffer_->BytesRemaining(), 0);
1634 if (send_buffer_->BytesRemaining() <= 0)
1635 send_buffer_ = NULL;
1636 } 1654 }
1655 DCHECK_GE(send_buffer_->RemainingCapacity(), bytes_written);
1656 int ret = BIO_zero_copy_get_read_buf_done(transport_bio_, bytes_written);
1657 DCHECK_EQ(1, ret);
1658 transport_send_busy_ = false;
1637 } 1659 }
1638 1660
1639 int SSLClientSocketOpenSSL::TransportReadComplete(int result) { 1661 int SSLClientSocketOpenSSL::TransportReadComplete(int result) {
1640 DCHECK(ERR_IO_PENDING != result); 1662 DCHECK(ERR_IO_PENDING != result);
1641 // If an EOF, canonicalize to ERR_CONNECTION_CLOSED here so MapOpenSSLError 1663 // If an EOF, canonicalize to ERR_CONNECTION_CLOSED here so MapOpenSSLError
1642 // does not report success. 1664 // does not report success.
1643 if (result == 0) 1665 if (result == 0)
1644 result = ERR_CONNECTION_CLOSED; 1666 result = ERR_CONNECTION_CLOSED;
1667 int bytes_read = 0;
1645 if (result < 0) { 1668 if (result < 0) {
1646 DVLOG(1) << "TransportReadComplete result " << result; 1669 DVLOG(1) << "TransportReadComplete result " << result;
1647 // Received an error. Save it to be reported in a future read on 1670 // Received an error. Save it to be reported in a future read on
1648 // transport_bio_'s peer. 1671 // transport_bio_'s peer.
1649 transport_read_error_ = result; 1672 transport_read_error_ = result;
1650 } else { 1673 } else {
1651 DCHECK(recv_buffer_.get()); 1674 bytes_read = result;
1652 int ret = BIO_write(transport_bio_, recv_buffer_->data(), result);
1653 // A write into a memory BIO should always succeed.
1654 DCHECK_EQ(result, ret);
1655 } 1675 }
1656 recv_buffer_ = NULL; 1676 DCHECK_GE(recv_buffer_->RemainingCapacity(), bytes_read);
1677 int ret = BIO_zero_copy_get_write_buf_done(transport_bio_, bytes_read);
1678 DCHECK_EQ(1, ret);
1657 transport_recv_busy_ = false; 1679 transport_recv_busy_ = false;
1658 return result; 1680 return result;
1659 } 1681 }
1660 1682
1661 int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl) { 1683 int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl) {
1662 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. 1684 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed.
1663 tracked_objects::ScopedTracker tracking_profile( 1685 tracked_objects::ScopedTracker tracking_profile(
1664 FROM_HERE_WITH_EXPLICIT_FUNCTION( 1686 FROM_HERE_WITH_EXPLICIT_FUNCTION(
1665 "424386 SSLClientSocketOpenSSL::ClientCertRequestCallback")); 1687 "424386 SSLClientSocketOpenSSL::ClientCertRequestCallback"));
1666 1688
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
1948 ct::SCT_STATUS_LOG_UNKNOWN)); 1970 ct::SCT_STATUS_LOG_UNKNOWN));
1949 } 1971 }
1950 } 1972 }
1951 1973
1952 scoped_refptr<X509Certificate> 1974 scoped_refptr<X509Certificate>
1953 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { 1975 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const {
1954 return server_cert_; 1976 return server_cert_;
1955 } 1977 }
1956 1978
1957 } // namespace net 1979 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698