[mod_openssl] SSL_read before second SSL_shutdown

call SSL_read() before calling SSL_shutdown() a second time.

Drain SSL read buffers in case pending records need processing.

x-ref:
  "New session ticket breaks bidirectional shutdown of TLS 1.3 connection"
  https://github.com/openssl/openssl/issues/6262
  reported to lighttpd by intexk
  https://www.lighttpd.net/2018/10/14/1.4.51/
personal/stbuehler/fix-fdevent
Glenn Strauss 2018-11-11 13:36:53 -05:00
parent 89062d8134
commit d182e90bb1
1 changed files with 27 additions and 0 deletions

View File

@ -1614,6 +1614,33 @@ mod_openssl_close_notify(server *srv, handler_ctx *hctx)
* FIXME: wait for fdevent and call SSL_shutdown again
*
*/
/* Drain SSL read buffers in case pending records need processing.
* Limit to reading 16k to avoid denial of service when the CPU
* processing TLS is slower than arrival speed of TLS data packets.
*
* references:
*
* "New session ticket breaks bidirectional shutdown of TLS 1.3 connection"
* https://github.com/openssl/openssl/issues/6262
*
* The peer is still allowed to send data after receiving the
* "close notify" event. If the peer did send data it need to be
* processed by calling SSL_read() before calling SSL_shutdown() a
* second time. SSL_read() will indicate the end of the peer data by
* returning <= 0 and SSL_get_error() returning
* SSL_ERROR_ZERO_RETURN. It is recommended to call SSL_read()
* between SSL_shutdown() calls.
*
* Additional discussion in "Auto retry in shutdown"
* https://github.com/openssl/openssl/pull/6340
*/
err = 0;
do {
char buf[4096];
ret = SSL_read(hctx->ssl, buf, (int)sizeof(buf));
} while (ret > 0 && (err += (unsigned long)ret) < 16384);
ERR_clear_error();
if (-1 != (ret = SSL_shutdown(hctx->ssl))) break;