From: Stefan Fritsch Date: Mon, 27 Feb 2012 20:01:40 +0000 (+0000) Subject: Initialize EC temporary key on server startup, as for DH and X-Git-Tag: 2.5.0-alpha~7436 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=960f0a63cdd91f5184d3d3e2c2115583ad3c44b1;p=apache 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. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1294306 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/docs/log-message-tags/next-number b/docs/log-message-tags/next-number index 3e263d2e55..0c80f59274 100644 --- a/docs/log-message-tags/next-number +++ b/docs/log-message-tags/next-number @@ -1 +1 @@ -2298 +2300 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