From a1fc8722b572725fe088318ac1f7cfdadbb68d62 Mon Sep 17 00:00:00 2001 From: Jim Jagielski Date: Tue, 3 Apr 2012 12:37:57 +0000 Subject: [PATCH] Merge r1294306 from trunk: Initialize EC temporary key on server startup, as for DH and RSA. This fixes a race condition that could lead to a crash with threaded MPMs. Submitted by: sf Reviewed/backported by: jim git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1308862 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 3 +++ STATUS | 11 -------- modules/ssl/ssl_engine_init.c | 46 +++++++++++++++++++++++++++++++++ modules/ssl/ssl_engine_kernel.c | 18 +++++-------- modules/ssl/ssl_private.h | 5 ++++ 5 files changed, 61 insertions(+), 22 deletions(-) diff --git a/CHANGES b/CHANGES index 91bda27346..0530876b66 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,9 @@ Changes with Apache 2.4.2 envvars: Fix insecure handling of LD_LIBRARY_PATH that could lead to the current working directory to be searched for DSOs. [Stefan Fritsch] + *) mod_ssl: Fix crash with threaded MPMs due to race condition when + initializing EC temporary keys. [Stefan Fritsch] + *) mod_proxy: Add the forcerecovery balancer parameter that determines if recovery for balancer workers is enforced. [Ruediger Pluem] diff --git a/STATUS b/STATUS index bd03e3c17b..1b09575c5d 100644 --- a/STATUS +++ b/STATUS @@ -88,17 +88,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * mod_ssl: Initialize EC temporary key on server startup, fixing a crash - with threaded MPMs. - Trunk patch: http://svn.apache.org/viewvc?rev=1294306&view=rev - 2.4.x patch: Trunk patch works, skip docs/log-message-tags/next-number, - add CHANGES: - mod_ssl: Fix crash with threaded MPMs due to race condition when - initializing EC temporary keys. [Stefan Fritsch] - NOTE: If you get strange openssl errors during server start, you may have - forgotten "make clean" before building. - +1: sf, minfrin, jim - * core: Fix regexp substitution bug Trunk patch: http://svn.apache.org/viewvc?rev=1307067&view=rev 2.4.x patch: Trunk patch works, add CHANGES: diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c index acaf5d5077..5d816478cb 100644 --- a/modules/ssl/ssl_engine_init.c +++ b/modules/ssl/ssl_engine_init.c @@ -77,6 +77,9 @@ static void ssl_tmp_keys_free(server_rec *s) MODSSL_TMP_KEYS_FREE(mc, RSA); MODSSL_TMP_KEYS_FREE(mc, DH); +#ifndef OPENSSL_NO_EC + MODSSL_TMP_KEY_FREE(mc, EC_KEY, SSL_TMP_KEY_EC_256); +#endif } static int ssl_tmp_key_init_rsa(server_rec *s, @@ -157,6 +160,40 @@ static int ssl_tmp_key_init_dh(server_rec *s, return OK; } +#ifndef OPENSSL_NO_EC +static int ssl_tmp_key_init_ec(server_rec *s, + int bits, int idx) +{ + SSLModConfigRec *mc = myModConfig(s); + EC_KEY *ecdh = NULL; + + /* XXX: Are there any FIPS constraints we should enforce? */ + + if (bits != 256) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02298) + "Init: Failed to generate temporary " + "%d bit EC parameters, only 256 bits supported", bits); + return !OK; + } + + if ((ecdh = EC_KEY_new()) == NULL || + EC_KEY_set_group(ecdh, EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)) != 1) + { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02299) + "Init: Failed to generate temporary " + "%d bit EC parameters", bits); + return !OK; + } + + mc->pTmpKeys[idx] = ecdh; + return OK; +} + +#define MODSSL_TMP_KEY_INIT_EC(s, bits) \ + ssl_tmp_key_init_ec(s, bits, SSL_TMP_KEY_EC_##bits) + +#endif + #define MODSSL_TMP_KEY_INIT_RSA(s, bits) \ ssl_tmp_key_init_rsa(s, bits, SSL_TMP_KEY_RSA_##bits) @@ -181,6 +218,15 @@ static int ssl_tmp_keys_init(server_rec *s) return !OK; } +#ifndef OPENSSL_NO_EC + ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s, + "Init: Generating temporary EC parameters (256 bits)"); + + if (MODSSL_TMP_KEY_INIT_EC(s, 256)) { + return !OK; + } +#endif + return OK; } diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c index 8d1aad812e..35b2a854a9 100644 --- a/modules/ssl/ssl_engine_kernel.c +++ b/modules/ssl/ssl_engine_kernel.c @@ -1386,24 +1386,20 @@ DH *ssl_callback_TmpDH(SSL *ssl, int export, int keylen) EC_KEY *ssl_callback_TmpECDH(SSL *ssl, int export, int keylen) { conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); - static EC_KEY *ecdh = NULL; - static int init = 0; + SSLModConfigRec *mc = myModConfigFromConn(c); + int idx; /* XXX Uses 256-bit key for now. TODO: support other sizes. */ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, "handing out temporary 256 bit ECC key"); - if (init == 0) { - ecdh = EC_KEY_new(); - if (ecdh != NULL) { - /* ecdh->group = EC_GROUP_new_by_nid(NID_secp160r2); */ - EC_KEY_set_group(ecdh, - EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)); - } - init = 1; + switch (keylen) { + case 256: + default: + idx = SSL_TMP_KEY_EC_256; } - return ecdh; + return (EC_KEY *)mc->pTmpKeys[idx]; } #endif diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h index fb9ac2611b..1b5d0428ce 100644 --- a/modules/ssl/ssl_private.h +++ b/modules/ssl/ssl_private.h @@ -298,7 +298,12 @@ typedef int ssl_algo_t; #define SSL_TMP_KEY_RSA_1024 (1) #define SSL_TMP_KEY_DH_512 (2) #define SSL_TMP_KEY_DH_1024 (3) +#ifndef OPENSSL_NO_EC +#define SSL_TMP_KEY_EC_256 (4) +#define SSL_TMP_KEY_MAX (5) +#else #define SSL_TMP_KEY_MAX (4) +#endif /** * Define the SSL options -- 2.40.0