From: Olivier Houchard Date: Fri, 8 Aug 2025 16:26:29 +0000 (+0200) Subject: BUG/MEDIUM: ssl: Fix 0rtt to the server X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=13aa5616c9f99dbca0711fd18f716bd6f48eb2ae;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: ssl: Fix 0rtt to the server In order to send early data, we have to make sure no handshake has been initiated at all. To do that, we remove the CO_FL_SSL_WAIT_HS flag, so that we won't attempt to start a handshake. However, by removing those flags, we allow ssl_sock_to_buf() to call SSL_read(), as it's no longer aware that no handshake has been done, and SSL_read() will begin the handshake, thus preventing us from sending early data. The fix is to just call SSL_in_before() to check if no handshake has been done yet, in addition to checking CO_FL_SSL_WAIT_HS (both are needed, as CO_FL_SSL_WAIT_HS may come back in case of renegociation). In ssl_sock_from_buf(), fix the check to see if we may attempt to send early data. Use SSL_in_before() instead of SSL_is_init_finished(), as SSL_is_init_finished() will return 1 if the handshake has been started, but not terminated, and if the handshake has been started, we can no longer send early data. This fixes errors when attempting to send early data (as well as actually sending early data). This should be backported up to 2.8. --- diff --git a/src/ssl_sock.c b/src/ssl_sock.c index c77c82d97..201f28602 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -5928,7 +5928,12 @@ static size_t ssl_sock_to_buf(struct connection *conn, void *xprt_ctx, struct bu } #endif - if (conn->flags & (CO_FL_WAIT_XPRT | CO_FL_SSL_WAIT_HS)) { + /* + * We have to check SSL_in_before() here, as the handshake flags + * may have been removed in case we want to try to send early data. + */ + if (SSL_in_before(ctx->ssl) || + (conn->flags & (CO_FL_WAIT_XPRT | CO_FL_SSL_WAIT_HS))) { /* a handshake was requested */ TRACE_LEAVE(SSL_EV_CONN_RECV, conn); return 0; @@ -6101,7 +6106,7 @@ static size_t ssl_sock_from_buf(struct connection *conn, void *xprt_ctx, const s ctx->xprt_st &= ~SSL_SOCK_SEND_MORE; #ifdef SSL_READ_EARLY_DATA_SUCCESS - if (!SSL_is_init_finished(ctx->ssl) && conn_is_back(conn)) { + if (SSL_in_before(ctx->ssl) && conn_is_back(conn)) { unsigned int max_early; if (objt_listener(conn->target))