From 35ca22d231f30107aff092222476d93f1a555c71 Mon Sep 17 00:00:00 2001 From: Yann Ylavic Date: Fri, 15 Jun 2018 11:12:19 +0000 Subject: [PATCH] mod_ssl: disable check for client initiated renegotiations with TLS 1.3. This is already forbidden by the protocol, enforced by OpenSSL, and the current logic can't work (ssl_callback_Info() may be called multiple times with TLS 1.3). git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1833588 13f79535-47bb-0310-9956-ffa450edef68 --- modules/ssl/ssl_engine_kernel.c | 44 +++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c index 5385dc516a..4fbcb0ba45 100644 --- a/modules/ssl/ssl_engine_kernel.c +++ b/modules/ssl/ssl_engine_kernel.c @@ -2238,31 +2238,43 @@ void ssl_callback_Info(const SSL *ssl, int where, int rc) { conn_rec *c; server_rec *s; - SSLConnRec *scr; /* Retrieve the conn_rec and the associated SSLConnRec. */ if ((c = (conn_rec *)SSL_get_app_data((SSL *)ssl)) == NULL) { return; } - if ((scr = myConnConfig(c)) == NULL) { - return; - } + /* With TLS 1.3 this callback may be called multiple times on the first + * negotiation, so the below logic to detect renegotiations can't work. + * Fortunately renegotiations are forbidden starting with TLS 1.3, and + * this is enforced by OpenSSL so there's nothing to be done here. + */ +#if SSL_HAVE_PROTOCOL_TLSV1_3 + if (SSL_version(ssl) < TLS1_3_VERSION) +#endif + { + SSLConnRec *sslconn; - /* If the reneg state is to reject renegotiations, check the SSL - * state machine and move to ABORT if a Client Hello is being - * read. */ - if (!scr->is_proxy && - (where & SSL_CB_HANDSHAKE_START) && - scr->reneg_state == RENEG_REJECT) { - scr->reneg_state = RENEG_ABORT; + if ((sslconn = myConnConfig(c)) == NULL) { + return; + } + + /* If the reneg state is to reject renegotiations, check the SSL + * state machine and move to ABORT if a Client Hello is being + * read. */ + if (!sslconn->is_proxy && + (where & SSL_CB_HANDSHAKE_START) && + sslconn->reneg_state == RENEG_REJECT) { + sslconn->reneg_state = RENEG_ABORT; ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02042) "rejecting client initiated renegotiation"); - } - /* If the first handshake is complete, change state to reject any - * subsequent client-initiated renegotiation. */ - else if ((where & SSL_CB_HANDSHAKE_DONE) && scr->reneg_state == RENEG_INIT) { - scr->reneg_state = RENEG_REJECT; + } + /* If the first handshake is complete, change state to reject any + * subsequent client-initiated renegotiation. */ + else if ((where & SSL_CB_HANDSHAKE_DONE) + && sslconn->reneg_state == RENEG_INIT) { + sslconn->reneg_state = RENEG_REJECT; + } } s = mySrvFromConn(c); -- 2.40.0