From: Rainer Jung Date: Wed, 10 Aug 2016 20:05:11 +0000 (+0000) Subject: Support for OpenSSL 1.1.0: X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7cc20d3fce823efac5c93e0fae60fc0c18e06376;p=thirdparty%2Fapache%2Fhttpd.git Support for OpenSSL 1.1.0: - further improvements for renegotiation No more test suite failures for reneg, but still using not so nice polling. Backport of r1729927 from trunk. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x-openssl-1.1.0-compat@1755829 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c index 3d53f5e4664..17f28942716 100644 --- a/modules/ssl/ssl_engine_kernel.c +++ b/modules/ssl/ssl_engine_kernel.c @@ -1041,16 +1041,20 @@ int ssl_hook_Access(request_rec *r) /* XXX: Polling is bad, alternatives? */ for (i = 0; i < SSL_HANDSHAKE_MAX_POLLS; i++) { has_buffered_data(r); - if (sslconn->ssl == NULL || SSL_is_init_finished(ssl)) { + if (sslconn->ssl == NULL || + sslconn->reneg_state == RENEG_DONE || + sslconn->reneg_state == RENEG_ALLOW) { break; } apr_sleep(SSL_HANDSHAKE_POLL_MS); } ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, APLOGNO() "Renegotiation loop %d iterations, " + "reneg_state=%d, " "in_init=%d, init_finished=%d, " "state=%s, sslconn->ssl=%s, peer_certs=%s", - i, SSL_in_init(ssl), SSL_is_init_finished(ssl), + i, sslconn->reneg_state, + SSL_in_init(ssl), SSL_is_init_finished(ssl), SSL_state_string_long(ssl), sslconn->ssl != NULL ? "yes" : "no", SSL_get_peer_certificate(ssl) != NULL ? "yes" : "no"); @@ -2144,6 +2148,18 @@ void ssl_callback_Info(const SSL *ssl, int where, int rc) } #endif } +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + else if ((where & SSL_CB_HANDSHAKE_START) && scr->reneg_state == RENEG_ALLOW) { + scr->reneg_state = RENEG_STARTED; + } + else if ((where & SSL_CB_HANDSHAKE_DONE) && scr->reneg_state == RENEG_STARTED) { + scr->reneg_state = RENEG_DONE; + } + else if ((where & SSL_CB_ALERT) && + (scr->reneg_state == RENEG_ALLOW || scr->reneg_state == RENEG_STARTED)) { + scr->reneg_state = RENEG_ALERT; + } +#endif /* 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) { diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h index d51d304807c..40dd4e84a1d 100644 --- a/modules/ssl/ssl_private.h +++ b/modules/ssl/ssl_private.h @@ -456,12 +456,17 @@ typedef struct { * partial fix for CVE-2009-3555. */ enum { RENEG_INIT = 0, /* Before initial handshake */ - RENEG_REJECT, /* After initial handshake; any client-initiated - * renegotiation should be rejected */ - RENEG_ALLOW, /* A server-initiated renegotiation is taking - * place (as dictated by configuration) */ - RENEG_ABORT /* Renegotiation initiated by client, abort the - * connection */ + RENEG_REJECT, /* After initial handshake; any client-initiated + * renegotiation should be rejected */ + RENEG_ALLOW, /* A server-initiated renegotiation is taking + * place (as dictated by configuration) */ +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + RENEG_STARTED, /* A renegotiation has started after RENEG_ALLOW */ + RENEG_DONE, /* A renegotiation has finished after RENEG_STARTED */ + RENEG_ALERT, /* A renegotiation has finished with an SSL Alert */ +#endif + RENEG_ABORT /* Renegotiation initiated by client, abort the + * connection */ } reneg_state; server_rec *server;