David Schwartz wrote:
Darryl Miles wrote:
I do not believe the SSL_write() call is allowed to access the
underlying BIO/kernel-socket to read in more data. I think SSL_write()
is allowed to process any data already read into buffer (from kernel to
OpenSSL library internal buffer) in an attempt to unstall the situation
itself. But it can't invoke read() on the kernel for it.
If SSL_write has to read from the socket to make forward progress, there is
absolutely no reason it shouldn't just do so. There is no reason it should
compel the application to do it.
My documentation says:
[T]he return value of SSL_write() will yield SSL_ERROR_WANT_READ or
SSL_ERROR_WANT_WRITE. As at any time a re-negotiation is possible, a
call to SSL_write() can also cause read operations! The calling
process
then must repeat the call after taking appropriate action to satisfy
the needs of SSL_write(). The action depends on the underlying BIO.
When using a non-blocking socket, nothing is to be done, but select()
can be used to check for the required condition. When using a
buffering
BIO, like a BIO pair, data must be written into or retrieved out of
the
BIO before being able to continue.
This suggests the exact opposite of what you said. One of these sources is
right and the other is wrong, and it makes a huge difference which!
My understanding, for many years, coincides with this documentation.
However, I can't think of any specific case where this difference would have
affected me, as my coding is extremely defensive and would tolerate either
mechanism without a problem.
"One of these sources is right and the other is wrong" ... Yes, no,
maybe... You maybe correct in the detail here, I am going on my
hazy-memory of experimenting with this situation and the observable
behavior. But I never wrote up notes on the matter not saw fit to
improve the documentation.
My conclusions on it were that an SSL_write() can cause a packet decode
to complete but only:
* If the data for the entire packet has already been read() into the
SSL user-space buffer (i.e. no longer in the BIO/kernel). The
read-ahead optimization makes it possible for this to happen.
* If there is no application data waiting to be destructively removed
ahead of the re-negotiation packet. i.e. SSL_read(). Until all
application data has been sunk/removed from OpenSSL it won't decode the
next packet.
My memory on this was that SSL_write() itself won't call on the BIO to
perform a read() but it will attempt to decode the next incoming packet
from the data it may already have, this is in the hope that it turns out
to be the re-negotiation response (in many situations it gets lucky!).
If it decodes the next packet and it turns out to be incoming
application data then SSL_write() is stuffed! No amount of calling it
again will clear the -1/WANT_READ condition.
The largest part of my previous post was explaining how to handle the
situation generalls and calling SSL_read() and then re-trying
SSL_write() to see if the condition has cleared it the way to deal with
it. You can not rely on repeatedly calling SSL_write() alone to clear
the problem. Which was my interpretation of what Jason was asking.
To re-express the same thing another way:
SSL_write() calls can not by-pass the already in-progress inbound
application data (to get at the re-negotiation response packet
immediately). There is a possibility there is still some application
data waiting to be SSL_read() before the re-negotiation SSL protocol
packet can be seen, decoded and processed.
Imagine the re-negotiation SSL protocol packet is actually still inside
the kernel buffering (waiting for user-space to read() to pull it). Now
image that there are at least 2 large full-size application data packets
also spanned across the user-space and kernel buffers (ahead of the SSL
re-negotiation packet).
SSL_write() has no where to put the data once it has decoded a large
full-sized application data packet. Inside OpenSSL there is a rigid
buffering scheme, there is a decode buffer into which the encrypted
packet is read in from BIO/kernel. There is also a clear-text buffer
into which the resultant application data from a single packet decode
can be stored. The decode/decyption process only takes place if the
clear-text buffer is empty (i.e. user-space has SSL_read() all the
previous data from it, so it will attempt to pull in more data and
re-fill it).
It is for sure that OpenSSL doesn't have an infinite expandable memory
buffer to keep holding application data to allow SSL_write() to find the
re-negotiation packet. So it is the worst-case scenario I have in mind
when explaining how to handle the matter in my previous post.
The documentation could certainly be improved no matter what the correct
way to express the situation is. The docs were written to support the
implementation (not the other way around).
Darryl
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users@openssl.org
Automated List Manager majord...@openssl.org