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 sizes of the internal BoringSSL buffers. | |
agl
2014/12/17 19:12:22
// Default size of the internal BoringSSL buffers.
haavardm
2014/12/18 12:18:07
Done.
| |
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 // Let |SSLClientSocketOpenSSL| have ownership over the bio buffers to keep |
agl
2014/12/17 19:12:22
// SSLClientSocketOpenSSL retains ownership of the
haavardm
2014/12/18 12:18:07
Done.
| |
742 // the IOBuffers user contract. | |
743 if (!BIO_new_bio_pair_external_buf( | |
744 &ssl_bio, send_buffer_->capacity(), | |
745 reinterpret_cast<uint8_t*>(send_buffer_->data()), &transport_bio_, | |
746 recv_buffer_->capacity(), | |
747 reinterpret_cast<uint8_t*>(recv_buffer_->data()))) | |
734 return ERR_UNEXPECTED; | 748 return ERR_UNEXPECTED; |
735 DCHECK(ssl_bio); | 749 DCHECK(ssl_bio); |
736 DCHECK(transport_bio_); | 750 DCHECK(transport_bio_); |
737 | 751 |
738 // Install a callback on OpenSSL's end to plumb transport errors through. | 752 // Install a callback on OpenSSL's end to plumb transport errors through. |
739 BIO_set_callback(ssl_bio, BIOCallback); | 753 BIO_set_callback(ssl_bio, BIOCallback); |
740 BIO_set_callback_arg(ssl_bio, reinterpret_cast<char*>(this)); | 754 BIO_set_callback_arg(ssl_bio, reinterpret_cast<char*>(this)); |
741 | 755 |
742 SSL_set_bio(ssl_, ssl_bio, ssl_bio); | 756 SSL_set_bio(ssl_, ssl_bio, ssl_bio); |
743 | 757 |
(...skipping 758 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1502 NetLog::TYPE_SSL_WRITE_ERROR, | 1516 NetLog::TYPE_SSL_WRITE_ERROR, |
1503 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info)); | 1517 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info)); |
1504 } | 1518 } |
1505 return net_error; | 1519 return net_error; |
1506 } | 1520 } |
1507 | 1521 |
1508 int SSLClientSocketOpenSSL::BufferSend(void) { | 1522 int SSLClientSocketOpenSSL::BufferSend(void) { |
1509 if (transport_send_busy_) | 1523 if (transport_send_busy_) |
1510 return ERR_IO_PENDING; | 1524 return ERR_IO_PENDING; |
1511 | 1525 |
1512 if (!send_buffer_.get()) { | 1526 size_t buffer_read_offset; |
1513 // Get a fresh send buffer out of the send BIO. | 1527 uint8_t* read_buf; |
1514 size_t max_read = BIO_pending(transport_bio_); | 1528 size_t max_read; |
1515 if (!max_read) | 1529 int status = BIO_zero_copy_get_read_buf(transport_bio_, &read_buf, |
1516 return 0; // Nothing pending in the OpenSSL write BIO. | 1530 &buffer_read_offset, &max_read); |
1517 send_buffer_ = new DrainableIOBuffer(new IOBuffer(max_read), max_read); | 1531 DCHECK(status == 1); // Should never fail. |
agl
2014/12/17 22:29:56
DCHECK_EQ
haavardm
2014/12/18 12:18:07
Done.
| |
1518 int read_bytes = BIO_read(transport_bio_, send_buffer_->data(), max_read); | 1532 if (!max_read) |
1519 DCHECK_GT(read_bytes, 0); | 1533 return 0; // Nothing pending in the OpenSSL write BIO. |
1520 CHECK_EQ(static_cast<int>(max_read), read_bytes); | 1534 CHECK(read_buf == reinterpret_cast<uint8_t*>(send_buffer_->data())); |
agl
2014/12/17 22:29:56
CHECK_EQ
haavardm
2014/12/18 12:18:07
Done.
| |
1521 } | 1535 CHECK(buffer_read_offset < static_cast<size_t>(send_buffer_->capacity())); |
agl
2014/12/17 22:29:56
CHECK_LT
haavardm
2014/12/18 12:18:07
Done.
| |
1536 send_buffer_->set_offset(buffer_read_offset); | |
1522 | 1537 |
1523 int rv = transport_->socket()->Write( | 1538 int rv = transport_->socket()->Write( |
1524 send_buffer_.get(), | 1539 send_buffer_.get(), max_read, |
1525 send_buffer_->BytesRemaining(), | |
1526 base::Bind(&SSLClientSocketOpenSSL::BufferSendComplete, | 1540 base::Bind(&SSLClientSocketOpenSSL::BufferSendComplete, |
1527 base::Unretained(this))); | 1541 base::Unretained(this))); |
1528 if (rv == ERR_IO_PENDING) { | 1542 if (rv == ERR_IO_PENDING) { |
1529 transport_send_busy_ = true; | 1543 transport_send_busy_ = true; |
1530 } else { | 1544 } else { |
1531 TransportWriteComplete(rv); | 1545 TransportWriteComplete(rv); |
1532 } | 1546 } |
1533 return rv; | 1547 return rv; |
1534 } | 1548 } |
1535 | 1549 |
(...skipping 11 matching lines...) Expand all Loading... | |
1547 return ERR_IO_PENDING; | 1561 return ERR_IO_PENDING; |
1548 } | 1562 } |
1549 | 1563 |
1550 // Known Issue: While only reading |requested| data is the more correct | 1564 // Known Issue: While only reading |requested| data is the more correct |
1551 // implementation, it has the downside of resulting in frequent reads: | 1565 // implementation, it has the downside of resulting in frequent reads: |
1552 // One read for the SSL record header (~5 bytes) and one read for the SSL | 1566 // One read for the SSL record header (~5 bytes) and one read for the SSL |
1553 // record body. Rather than issuing these reads to the underlying socket | 1567 // record body. Rather than issuing these reads to the underlying socket |
1554 // (and constantly allocating new IOBuffers), a single Read() request to | 1568 // (and constantly allocating new IOBuffers), a single Read() request to |
1555 // fill |transport_bio_| is issued. As long as an SSL client socket cannot | 1569 // fill |transport_bio_| is issued. As long as an SSL client socket cannot |
1556 // be gracefully shutdown (via SSL close alerts) and re-used for non-SSL | 1570 // be gracefully shutdown (via SSL close alerts) and re-used for non-SSL |
1557 // traffic, this over-subscribed Read()ing will not cause issues. | 1571 // traffic, this over-subscribed Read()ing will not cause issues. |
Ryan Sleevi
2014/12/17 22:57:10
Is this comment still applicable/accurate? Does th
haavardm
2014/12/18 12:18:07
I've done no changes to that logic, so max_write i
| |
1558 size_t max_write = BIO_ctrl_get_write_guarantee(transport_bio_); | 1572 |
1573 size_t buffer_write_offset; | |
1574 uint8_t* write_buf; | |
1575 size_t max_write; | |
1576 int status = BIO_zero_copy_get_write_buf(transport_bio_, &write_buf, | |
1577 &buffer_write_offset, &max_write); | |
1578 DCHECK(status == 1); // Should never fail. | |
agl
2014/12/17 22:29:56
DCHECK_EQ
| |
1559 if (!max_write) | 1579 if (!max_write) |
1560 return ERR_IO_PENDING; | 1580 return ERR_IO_PENDING; |
1561 | 1581 |
1562 recv_buffer_ = new IOBuffer(max_write); | 1582 CHECK(write_buf == reinterpret_cast<uint8_t*>(recv_buffer_->data())); |
agl
2014/12/17 22:29:56
CHECK_EQ
| |
1583 CHECK(buffer_write_offset < static_cast<size_t>(recv_buffer_->capacity())); | |
agl
2014/12/17 22:29:56
CHECK_LT
| |
1584 | |
1585 recv_buffer_->set_offset(buffer_write_offset); | |
1563 int rv = transport_->socket()->Read( | 1586 int rv = transport_->socket()->Read( |
1564 recv_buffer_.get(), | 1587 recv_buffer_.get(), |
1565 max_write, | 1588 max_write, |
1566 base::Bind(&SSLClientSocketOpenSSL::BufferRecvComplete, | 1589 base::Bind(&SSLClientSocketOpenSSL::BufferRecvComplete, |
1567 base::Unretained(this))); | 1590 base::Unretained(this))); |
1568 if (rv == ERR_IO_PENDING) { | 1591 if (rv == ERR_IO_PENDING) { |
1569 transport_recv_busy_ = true; | 1592 transport_recv_busy_ = true; |
1570 } else { | 1593 } else { |
1571 rv = TransportReadComplete(rv); | 1594 rv = TransportReadComplete(rv); |
1572 } | 1595 } |
1573 return rv; | 1596 return rv; |
1574 } | 1597 } |
1575 | 1598 |
1576 void SSLClientSocketOpenSSL::BufferSendComplete(int result) { | 1599 void SSLClientSocketOpenSSL::BufferSendComplete(int result) { |
1577 transport_send_busy_ = false; | |
1578 TransportWriteComplete(result); | 1600 TransportWriteComplete(result); |
1579 OnSendComplete(result); | 1601 OnSendComplete(result); |
1580 } | 1602 } |
1581 | 1603 |
1582 void SSLClientSocketOpenSSL::BufferRecvComplete(int result) { | 1604 void SSLClientSocketOpenSSL::BufferRecvComplete(int result) { |
1583 result = TransportReadComplete(result); | 1605 result = TransportReadComplete(result); |
1584 OnRecvComplete(result); | 1606 OnRecvComplete(result); |
1585 } | 1607 } |
1586 | 1608 |
1587 void SSLClientSocketOpenSSL::TransportWriteComplete(int result) { | 1609 void SSLClientSocketOpenSSL::TransportWriteComplete(int result) { |
1588 DCHECK(ERR_IO_PENDING != result); | 1610 DCHECK(ERR_IO_PENDING != result); |
1611 int bytes_written = 0; | |
1589 if (result < 0) { | 1612 if (result < 0) { |
1590 // Record the error. Save it to be reported in a future read or write on | 1613 // Record the error. Save it to be reported in a future read or write on |
1591 // transport_bio_'s peer. | 1614 // transport_bio_'s peer. |
1592 transport_write_error_ = result; | 1615 transport_write_error_ = result; |
1593 send_buffer_ = NULL; | |
1594 } else { | 1616 } else { |
1595 DCHECK(send_buffer_.get()); | 1617 bytes_written = result; |
1596 send_buffer_->DidConsume(result); | |
1597 DCHECK_GE(send_buffer_->BytesRemaining(), 0); | |
1598 if (send_buffer_->BytesRemaining() <= 0) | |
1599 send_buffer_ = NULL; | |
1600 } | 1618 } |
1619 DCHECK_GE(send_buffer_->RemainingCapacity(), bytes_written); | |
1620 int ret = BIO_zero_copy_get_read_buf_done(transport_bio_, bytes_written); | |
Ryan Sleevi
2014/12/17 22:57:10
What's the contract from BoringSSL if the zero-cop
haavardm
2014/12/18 12:18:07
Yes, BoringSSL will handle this case. BIO_zero_cop
| |
1621 DCHECK_EQ(1, ret); | |
1622 send_buffer_->set_offset(0); | |
agl
2014/12/17 22:29:56
Is this set_offset needed? It seems that it would
haavardm
2014/12/18 12:18:07
It is not really needed since the offset is always
haavardm
2014/12/18 12:18:07
Done.
| |
1623 transport_send_busy_ = false; | |
1601 } | 1624 } |
1602 | 1625 |
1603 int SSLClientSocketOpenSSL::TransportReadComplete(int result) { | 1626 int SSLClientSocketOpenSSL::TransportReadComplete(int result) { |
1604 DCHECK(ERR_IO_PENDING != result); | 1627 DCHECK(ERR_IO_PENDING != result); |
1605 // If an EOF, canonicalize to ERR_CONNECTION_CLOSED here so MapOpenSSLError | 1628 // If an EOF, canonicalize to ERR_CONNECTION_CLOSED here so MapOpenSSLError |
1606 // does not report success. | 1629 // does not report success. |
1607 if (result == 0) | 1630 if (result == 0) |
1608 result = ERR_CONNECTION_CLOSED; | 1631 result = ERR_CONNECTION_CLOSED; |
1632 int bytes_read = 0; | |
1609 if (result < 0) { | 1633 if (result < 0) { |
1610 DVLOG(1) << "TransportReadComplete result " << result; | 1634 DVLOG(1) << "TransportReadComplete result " << result; |
1611 // Received an error. Save it to be reported in a future read on | 1635 // Received an error. Save it to be reported in a future read on |
1612 // transport_bio_'s peer. | 1636 // transport_bio_'s peer. |
1613 transport_read_error_ = result; | 1637 transport_read_error_ = result; |
1614 } else { | 1638 } else { |
1615 DCHECK(recv_buffer_.get()); | 1639 bytes_read = result; |
1616 int ret = BIO_write(transport_bio_, recv_buffer_->data(), result); | |
1617 // A write into a memory BIO should always succeed. | |
1618 DCHECK_EQ(result, ret); | |
1619 } | 1640 } |
1620 recv_buffer_ = NULL; | 1641 DCHECK_GE(recv_buffer_->RemainingCapacity(), bytes_read); |
1642 int ret = BIO_zero_copy_get_write_buf_done(transport_bio_, bytes_read); | |
1643 DCHECK_EQ(1, ret); | |
1644 recv_buffer_->set_offset(0); | |
agl
2014/12/17 22:29:56
Ditto.
haavardm
2014/12/18 12:18:07
Done.
| |
1621 transport_recv_busy_ = false; | 1645 transport_recv_busy_ = false; |
1622 return result; | 1646 return result; |
1623 } | 1647 } |
1624 | 1648 |
1625 int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl) { | 1649 int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl) { |
1626 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. | 1650 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. |
1627 tracked_objects::ScopedTracker tracking_profile( | 1651 tracked_objects::ScopedTracker tracking_profile( |
1628 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1652 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
1629 "424386 SSLClientSocketOpenSSL::ClientCertRequestCallback")); | 1653 "424386 SSLClientSocketOpenSSL::ClientCertRequestCallback")); |
1630 | 1654 |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1903 ct::SCT_STATUS_LOG_UNKNOWN)); | 1927 ct::SCT_STATUS_LOG_UNKNOWN)); |
1904 } | 1928 } |
1905 } | 1929 } |
1906 | 1930 |
1907 scoped_refptr<X509Certificate> | 1931 scoped_refptr<X509Certificate> |
1908 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { | 1932 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { |
1909 return server_cert_; | 1933 return server_cert_; |
1910 } | 1934 } |
1911 | 1935 |
1912 } // namespace net | 1936 } // namespace net |
OLD | NEW |