Copy DH key (if available) in addition to the bare parameters in SSL_new. If SSL_OP_SINGLE_DH_USE is set, don't waste time in SSL_[CTX_]set_tmp_dh on computing a DH key that will be ignored anyway. ssltest -dhe1024dsa (w/ 160-bit sub-prime) had an unfair performance advantage over -dhe1024 (safe prime): SSL_OP_SINGLE_DH_USE was effectively always enabled because SSL_new ignored the DH key set in the SSL_CTX. Now -dhe1024 takes the server only about twice as long as -dhe1024dsa instead of three times as long (for 1024 bit RSA with 1024 bit DH).
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index 48f247c..a054e0a 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c
@@ -191,16 +191,33 @@ #ifndef NO_DH if (cert->dh_tmp != NULL) { - /* DH parameters don't have a reference count (and cannot - * reasonably be shared anyway, as the secret exponent may - * be created just when it is needed -- earlier library - * versions did not pay attention to this) */ + /* DH parameters don't have a reference count */ ret->dh_tmp = DHparams_dup(cert->dh_tmp); if (ret->dh_tmp == NULL) { SSLerr(SSL_F_SSL_CERT_NEW, ERR_R_DH_LIB); goto err; } + if (cert->dh_tmp->priv_key) + { + BIGNUM *b = BN_dup(cert->dh_tmp->priv_key); + if (!b) + { + SSLerr(SSL_F_SSL_CERT_NEW, ERR_R_BN_LIB); + goto err; + } + ret->dh_tmp->priv_key = b; + } + if (cert->dh_tmp->pub_key) + { + BIGNUM *b = BN_dup(cert->dh_tmp->pub_key); + if (!b) + { + SSLerr(SSL_F_SSL_CERT_NEW, ERR_R_BN_LIB); + goto err; + } + ret->dh_tmp->pub_key = b; + } } ret->dh_tmp_cb = cert->dh_tmp_cb; #endif