Does OpenSSL and/or the SSL/TLS protocol provide some kind of built in protection against infinite renegotiation?
In particular, is it possible for SSL_read()
to continue executing forever because the remote side (possibly maliciously) keeps requesting renegotiations without sending payload data?
I am worried about this because I want to service a number of SSL connections from a single thread using a polling mechanism and also ensure a form of fairness where the processing of I/O on one connection does not lead to starvation of I/O on the other connections.
When I call regular read()
on a socket in nonblocking mode, I know it cannot keep executing forever, because the buffer will fill up eventually.
However, since SSL_read()
can handle renegotiations transparently, it seems to me that if the remote side (possibly maliciously) keeps requesting renegotiations without sending payload data, and the underlying transport layer is fast enough to make the underlying reads and writes never fail with EWOULDBLOCK
, then SSL_read()
could end up executing forever, and thereby starving the other connections.
Therefore my question: Does OpenSSL or the protocols have mechanisms for avoiding that? The question applies equally to SSL_write()
by the way.
EDIT: For example, can I be sure that SSL_read()
will return with an SSL_ERROR_WANT_READ
/SSL_ERROR_WANT_WRITE
indication before engaging in multiple renegotiations, even if the underlying read/write operations never fail with EWOULDBLOCK
?
EDIT: For the purpose of this question, assume that I am using a regular socket BIO (BIO_s_socket()
) and that the underlying socket is in nonblocking mode.
There is no built-in protection in OpenSSL. But you can use SSL_CTX_set_info_callback
or similar to set a function which gets called on each negotiation. This way you can cut the connection if too much renegotiations happen inside the same connection. See Protect against client-initiated renegotiation DoS in OpenSSL/Python for more information.