[openssl-users] Polling fd before SSL_read() and renegotiations

Tomas Mraz tmraz at redhat.com
Tue Jun 5 11:26:10 UTC 2018

On Mon, 2018-06-04 at 18:51 +0200, Stefan via openssl-users wrote:
> 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
> 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).

You've basically answered your question yourself - you cannot do it
like this - switching phases #1 and #2, but instead you need to go to
the writing phase (i.e. start writing if you have anything to pass to
SSL_write) whenever you need to wait on data to be read to appear in
the socket.

Tomáš Mráz
No matter how far down the wrong road you've gone, turn back.
                                              Turkish proverb
[You'll know whether the road is wrong if you carefully listen to your

More information about the openssl-users mailing list