You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
173 lines
5.0 KiB
173 lines
5.0 KiB
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c |
|
index 46769e9..0275452 100644 |
|
--- a/modules/ssl/ssl_engine_init.c |
|
+++ b/modules/ssl/ssl_engine_init.c |
|
@@ -41,6 +41,79 @@ |
|
#define KEYTYPES "RSA or DSA" |
|
#endif |
|
|
|
+/* |
|
+ * Grab well-defined DH parameters from OpenSSL, see the get_rfc* |
|
+ * functions in <openssl/bn.h> for all available primes. |
|
+ */ |
|
+static DH *make_dh_params(BIGNUM *(*prime)(BIGNUM *), const char *gen) |
|
+{ |
|
+ DH *dh = DH_new(); |
|
+ |
|
+ if (!dh) { |
|
+ return NULL; |
|
+ } |
|
+ dh->p = prime(NULL); |
|
+ BN_dec2bn(&dh->g, gen); |
|
+ if (!dh->p || !dh->g) { |
|
+ DH_free(dh); |
|
+ return NULL; |
|
+ } |
|
+ return dh; |
|
+} |
|
+ |
|
+/* Storage and initialization for DH parameters. */ |
|
+static struct dhparam { |
|
+ BIGNUM *(*const prime)(BIGNUM *); /* function to generate... */ |
|
+ DH *dh; /* ...this, used for keys.... */ |
|
+ const unsigned int min; /* ...of length >= this. */ |
|
+} dhparams[] = { |
|
+ { get_rfc3526_prime_8192, NULL, 6145 }, |
|
+ { get_rfc3526_prime_6144, NULL, 4097 }, |
|
+ { get_rfc3526_prime_4096, NULL, 3073 }, |
|
+ { get_rfc3526_prime_3072, NULL, 2049 }, |
|
+ { get_rfc3526_prime_2048, NULL, 1025 }, |
|
+ { get_rfc2409_prime_1024, NULL, 0 } |
|
+}; |
|
+ |
|
+static void init_dh_params(void) |
|
+{ |
|
+ unsigned n; |
|
+ |
|
+ for (n = 0; n < sizeof(dhparams)/sizeof(dhparams[0]); n++) |
|
+ dhparams[n].dh = make_dh_params(dhparams[n].prime, "2"); |
|
+} |
|
+ |
|
+static void free_dh_params(void) |
|
+{ |
|
+ unsigned n; |
|
+ |
|
+ /* DH_free() is a noop for a NULL parameter, so these are harmless |
|
+ * in the (unexpected) case where these variables are already |
|
+ * NULL. */ |
|
+ for (n = 0; n < sizeof(dhparams)/sizeof(dhparams[0]); n++) { |
|
+ DH_free(dhparams[n].dh); |
|
+ dhparams[n].dh = NULL; |
|
+ } |
|
+} |
|
+ |
|
+/* Hand out the same DH structure though once generated as we leak |
|
+ * memory otherwise and freeing the structure up after use would be |
|
+ * hard to track and in fact is not needed at all as it is safe to |
|
+ * use the same parameters over and over again security wise (in |
|
+ * contrast to the keys itself) and code safe as the returned structure |
|
+ * is duplicated by OpenSSL anyway. Hence no modification happens |
|
+ * to our copy. */ |
|
+DH *modssl_get_dh_params(unsigned keylen) |
|
+{ |
|
+ unsigned n; |
|
+ |
|
+ for (n = 0; n < sizeof(dhparams)/sizeof(dhparams[0]); n++) |
|
+ if (keylen >= dhparams[n].min) |
|
+ return dhparams[n].dh; |
|
+ |
|
+ return NULL; /* impossible to reach. */ |
|
+} |
|
+ |
|
static void ssl_add_version_components(apr_pool_t *p, |
|
server_rec *s) |
|
{ |
|
@@ -244,6 +317,8 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog, |
|
|
|
SSL_init_app_data2_idx(); /* for SSL_get_app_data2() at request time */ |
|
|
|
+ init_dh_params(); |
|
+ |
|
return OK; |
|
} |
|
|
|
@@ -1623,6 +1698,8 @@ apr_status_t ssl_init_ModuleKill(void *data) |
|
ssl_init_ctx_cleanup_server(sc->server); |
|
} |
|
|
|
+ free_dh_params(); |
|
+ |
|
return APR_SUCCESS; |
|
} |
|
|
|
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c |
|
index 2d6d59e..1ecbccd 100644 |
|
--- a/modules/ssl/ssl_engine_kernel.c |
|
+++ b/modules/ssl/ssl_engine_kernel.c |
|
@@ -1287,34 +1287,6 @@ const authz_provider ssl_authz_provider_verify_client = |
|
*/ |
|
|
|
/* |
|
- * Grab well-defined DH parameters from OpenSSL, see <openssl/bn.h> |
|
- * (get_rfc*) for all available primes. |
|
- */ |
|
-#define make_get_dh(rfc,size,gen) \ |
|
-static DH *get_dh##size(void) \ |
|
-{ \ |
|
- DH *dh; \ |
|
- if (!(dh = DH_new())) { \ |
|
- return NULL; \ |
|
- } \ |
|
- dh->p = get_##rfc##_prime_##size(NULL); \ |
|
- BN_dec2bn(&dh->g, #gen); \ |
|
- if (!dh->p || !dh->g) { \ |
|
- DH_free(dh); \ |
|
- return NULL; \ |
|
- } \ |
|
- return dh; \ |
|
-} |
|
- |
|
-/* |
|
- * Prepare DH parameters from 1024 to 4096 bits, in 1024-bit increments |
|
- */ |
|
-make_get_dh(rfc2409, 1024, 2) |
|
-make_get_dh(rfc3526, 2048, 2) |
|
-make_get_dh(rfc3526, 3072, 2) |
|
-make_get_dh(rfc3526, 4096, 2) |
|
- |
|
-/* |
|
* Hand out standard DH parameters, based on the authentication strength |
|
*/ |
|
DH *ssl_callback_TmpDH(SSL *ssl, int export, int keylen) |
|
@@ -1342,14 +1314,7 @@ DH *ssl_callback_TmpDH(SSL *ssl, int export, int keylen) |
|
ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, |
|
"handing out built-in DH parameters for %d-bit authenticated connection", keylen); |
|
|
|
- if (keylen >= 4096) |
|
- return get_dh4096(); |
|
- else if (keylen >= 3072) |
|
- return get_dh3072(); |
|
- else if (keylen >= 2048) |
|
- return get_dh2048(); |
|
- else |
|
- return get_dh1024(); |
|
+ return modssl_get_dh_params(keylen); |
|
} |
|
|
|
/* |
|
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h |
|
index 744af9e..f47ed47 100644 |
|
--- a/modules/ssl/ssl_private.h |
|
+++ b/modules/ssl/ssl_private.h |
|
@@ -990,6 +990,11 @@ OCSP_RESPONSE *modssl_dispatch_ocsp_request(const apr_uri_t *uri, |
|
conn_rec *c, apr_pool_t *p); |
|
#endif |
|
|
|
+/* Retrieve DH parameters for given key length. Return value should |
|
+ * be treated as unmutable, since it is stored in process-global |
|
+ * memory. */ |
|
+DH *modssl_get_dh_params(unsigned keylen); |
|
+ |
|
#endif /* SSL_PRIVATE_H */ |
|
/** @} */ |
|
|
|
|