[openssl-users] Polling fd before SSL_read() and renegotiations
klein.stefan1 at googlemail.com
klein.stefan1 at googlemail.com
Mon Jun 4 16:51:05 UTC 2018
Hi everybody!
I am working on a program where each peer may write at any time, so
the other side has to be able to read incoming data when it gets
available. If the peer sent nothing my program must be able to call
SSL_write() to send its own data to the other side.
My code currently does this using non-blocking I/O like this:
1. If the underlying socket is not readable go to #2 immediately to be
able to send data. If the socket is reported to be readable, call
SSL_read() to get that data. If that call cannot be completed due
to SSL_ERROR_WANT_READ/SSL_ERROR_WANT_WRITE, poll the fd until that
condition is met. Then repeat calling SSL_read(). So I'm repeatedly
calling SSL_read() until it reports SSL_ERROR_NONE. With this I
satisfy the requirement of the OpenSSL-API to repeat an incomplete
call until it completes. Although I did not read that exactly in
the man-pages, the non-blocking-example in "Network Security with
OpenSSL" by Viega et al. takes care not to interleave the calls to
SSL_write()/SSL_read().
2. (The program reaches here only after SSL_read() has succeeded or if
it has not even tried to call SSL_read() as the socket was not
readable) If the peer has data that needs to be sent to the other
side, call SSL_write() for it. If that function returns with
SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE poll the fd accordingly
and repeat SSL_write() until it ends with SSL_ERROR_NONE. Then go
to #1 to check for incoming data.
The code above does what I want - except for renegotiations!
If the peer receives a renegotiation-request its socket becomes
readable just like if it received a normal SSL-record with user-data.
Thus my program enters #1 and repeats SSL_read() until SSL_ERROR_NONE
is returned. But this never happens in that case, because the other
peer just sent the renegotiation-packet(s) but no other data. So I'm
stuck in repeating SSL_read() and won't enter #2 until the peer that
forced the renegotiation has sent any other data to make SSL_read()
finish (which may take very long in my program).
Well, I can force that behavior only using "openssl s_client/s_server"
as peer. And if other peers do it exactly like my code, a
renogatioation can only be initiated by calling SSL_write(). So some
data will be sent after the renegotiation to prevent the described
situation.
But can I really trust on that behavior for other peers? Even if they
are using other SSL-libraries? And what if the other side detects an
session-timeout while it waits on data and immediately intiates a
renegotiation without sending data?
If not, how can I use the OpenSSL-API and not stuck in SSL_read() when
there is no data available for read?
Thanks a lot for your help!
Stefan
More information about the openssl-users
mailing list