|
|
d9f2e03 |
--- contrib/mod_tls.c
|
|
|
d9f2e03 |
+++ contrib/mod_tls.c
|
|
|
d9f2e03 |
@@ -461,7 +461,7 @@ static tls_sess_cache_t *tls_sess_cache
|
|
|
d9f2e03 |
static SSL *ctrl_ssl = NULL;
|
|
|
d9f2e03 |
static SSL_CTX *ssl_ctx = NULL;
|
|
|
d9f2e03 |
static X509_STORE *tls_crl_store = NULL;
|
|
|
d9f2e03 |
-static DH *tls_tmp_dh = NULL;
|
|
|
d9f2e03 |
+static array_header *tls_tmp_dhs = NULL;
|
|
|
d9f2e03 |
static RSA *tls_tmp_rsa = NULL;
|
|
|
d9f2e03 |
|
|
|
d9f2e03 |
/* SSL/TLS support functions */
|
|
|
d2f47d9 |
@@ -1952,58 +1952,60 @@ static int tls_ctrl_renegotiate_cb(CALLB
|
|
|
d9f2e03 |
#endif
|
|
|
d9f2e03 |
|
|
|
d9f2e03 |
static DH *tls_dh_cb(SSL *ssl, int is_export, int keylength) {
|
|
|
d9f2e03 |
- FILE *fp = NULL;
|
|
|
d9f2e03 |
-
|
|
|
d9f2e03 |
- if (tls_tmp_dh) {
|
|
|
d9f2e03 |
- return tls_tmp_dh;
|
|
|
d9f2e03 |
- }
|
|
|
d9f2e03 |
+ DH *dh = NULL;
|
|
|
d9f2e03 |
|
|
|
d9f2e03 |
- if (tls_dhparam_file) {
|
|
|
d9f2e03 |
- fp = fopen(tls_dhparam_file, "r");
|
|
|
d9f2e03 |
- if (fp) {
|
|
|
d9f2e03 |
- tls_tmp_dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
|
|
|
d9f2e03 |
- fclose(fp);
|
|
|
d9f2e03 |
+ if (tls_tmp_dhs != NULL &&
|
|
|
d9f2e03 |
+ tls_tmp_dhs->nelts > 0) {
|
|
|
d9f2e03 |
+ register unsigned int i;
|
|
|
d9f2e03 |
+ DH **dhs;
|
|
|
d9f2e03 |
|
|
|
d9f2e03 |
- if (tls_tmp_dh) {
|
|
|
d9f2e03 |
- return tls_tmp_dh;
|
|
|
d9f2e03 |
+ dhs = tls_tmp_dhs->elts;
|
|
|
d9f2e03 |
+ for (i = 0; i < tls_tmp_dhs->nelts; i++) {
|
|
|
d9f2e03 |
+ /* Note: the keylength argument is in BITS, but DH_size() returns
|
|
|
d9f2e03 |
+ * the number of BYTES.
|
|
|
d9f2e03 |
+ */
|
|
|
d9f2e03 |
+ if (DH_size(dhs[i]) == (keylength / 8)) {
|
|
|
d9f2e03 |
+ return dhs[i];
|
|
|
d9f2e03 |
}
|
|
|
d9f2e03 |
-
|
|
|
d9f2e03 |
- } else {
|
|
|
d9f2e03 |
- pr_log_debug(DEBUG3, MOD_TLS_VERSION
|
|
|
d9f2e03 |
- ": unable to open TLSDHParamFile '%s': %s", tls_dhparam_file,
|
|
|
d9f2e03 |
- strerror(errno));
|
|
|
d9f2e03 |
}
|
|
|
d9f2e03 |
}
|
|
|
d9f2e03 |
|
|
|
d9f2e03 |
switch (keylength) {
|
|
|
d9f2e03 |
case 512:
|
|
|
d9f2e03 |
- tls_tmp_dh = get_dh512();
|
|
|
d9f2e03 |
+ dh = get_dh512();
|
|
|
d9f2e03 |
break;
|
|
|
d9f2e03 |
|
|
|
d9f2e03 |
case 768:
|
|
|
d9f2e03 |
- tls_tmp_dh = get_dh768();
|
|
|
d9f2e03 |
+ dh = get_dh768();
|
|
|
d9f2e03 |
break;
|
|
|
d9f2e03 |
|
|
|
d9f2e03 |
case 1024:
|
|
|
d9f2e03 |
- tls_tmp_dh = get_dh1024();
|
|
|
d9f2e03 |
+ dh = get_dh1024();
|
|
|
d9f2e03 |
break;
|
|
|
d9f2e03 |
|
|
|
d9f2e03 |
case 1536:
|
|
|
d9f2e03 |
- tls_tmp_dh = get_dh1536();
|
|
|
d9f2e03 |
+ dh = get_dh1536();
|
|
|
d9f2e03 |
break;
|
|
|
d9f2e03 |
|
|
|
d9f2e03 |
case 2048:
|
|
|
d9f2e03 |
- tls_tmp_dh = get_dh2048();
|
|
|
d9f2e03 |
+ dh = get_dh2048();
|
|
|
d9f2e03 |
break;
|
|
|
d9f2e03 |
|
|
|
d9f2e03 |
default:
|
|
|
d9f2e03 |
tls_log("unsupported DH key length %d requested, returning 1024 bits",
|
|
|
d9f2e03 |
keylength);
|
|
|
d9f2e03 |
- tls_tmp_dh = get_dh1024();
|
|
|
d9f2e03 |
+ dh = get_dh1024();
|
|
|
d9f2e03 |
break;
|
|
|
d9f2e03 |
}
|
|
|
d9f2e03 |
|
|
|
d9f2e03 |
- return tls_tmp_dh;
|
|
|
d9f2e03 |
+ /* Add this DH to the list, so that it can be freed properly later. */
|
|
|
d2f47d9 |
+ if (tls_tmp_dhs == NULL) {
|
|
|
d2f47d9 |
+ tls_tmp_dhs = make_array(session.pool, 1, sizeof(DH *));
|
|
|
d2f47d9 |
+ }
|
|
|
d2f47d9 |
+
|
|
|
d9f2e03 |
+ *((DH **) push_array(tls_tmp_dhs)) = dh;
|
|
|
d9f2e03 |
+
|
|
|
d9f2e03 |
+ return dh;
|
|
|
d9f2e03 |
}
|
|
|
d9f2e03 |
|
|
|
d9f2e03 |
/* Post 0.9.7a, RSA blinding is turned on by default, so there is no need to
|
|
|
d2f47d9 |
@@ -3018,9 +3020,16 @@ static void tls_cleanup(int flags) {
|
|
|
d9f2e03 |
ssl_ctx = NULL;
|
|
|
d9f2e03 |
}
|
|
|
d9f2e03 |
|
|
|
d9f2e03 |
- if (tls_tmp_dh) {
|
|
|
d9f2e03 |
- DH_free(tls_tmp_dh);
|
|
|
d9f2e03 |
- tls_tmp_dh = NULL;
|
|
|
d9f2e03 |
+ if (tls_tmp_dhs) {
|
|
|
d9f2e03 |
+ register unsigned int i;
|
|
|
d9f2e03 |
+ DH **dhs;
|
|
|
d9f2e03 |
+
|
|
|
d9f2e03 |
+ dhs = tls_tmp_dhs->elts;
|
|
|
d9f2e03 |
+ for (i = 0; i < tls_tmp_dhs->nelts; i++) {
|
|
|
d9f2e03 |
+ DH_free(dhs[i]);
|
|
|
d9f2e03 |
+ }
|
|
|
d9f2e03 |
+
|
|
|
d9f2e03 |
+ tls_tmp_dhs = NULL;
|
|
|
d9f2e03 |
}
|
|
|
d9f2e03 |
|
|
|
d9f2e03 |
if (tls_tmp_rsa) {
|
|
|
d2f47d9 |
@@ -7320,6 +7329,38 @@ static int tls_sess_init(void) {
|
|
|
d9f2e03 |
tls_crl_path = get_param_ptr(main_server->conf, "TLSCARevocationPath", FALSE);
|
|
|
d9f2e03 |
|
|
|
d9f2e03 |
tls_dhparam_file = get_param_ptr(main_server->conf, "TLSDHParamFile", FALSE);
|
|
|
d9f2e03 |
+ if (tls_dhparam_file != NULL) {
|
|
|
d9f2e03 |
+ FILE *fp;
|
|
|
d9f2e03 |
+ int xerrno;
|
|
|
d9f2e03 |
+
|
|
|
d9f2e03 |
+ /* Load the DH params from the file. */
|
|
|
d9f2e03 |
+ PRIVS_ROOT
|
|
|
d9f2e03 |
+ fp = fopen(tls_dhparam_file, "r");
|
|
|
d9f2e03 |
+ xerrno = errno;
|
|
|
d9f2e03 |
+ PRIVS_RELINQUISH
|
|
|
d9f2e03 |
+
|
|
|
d9f2e03 |
+ if (fp != NULL) {
|
|
|
d9f2e03 |
+ DH *dh;
|
|
|
d9f2e03 |
+
|
|
|
d9f2e03 |
+ dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
|
|
|
d9f2e03 |
+ if (dh != NULL) {
|
|
|
d9f2e03 |
+ tls_tmp_dhs = make_array(session.pool, 1, sizeof(DH *));
|
|
|
d9f2e03 |
+ }
|
|
|
d9f2e03 |
+
|
|
|
d9f2e03 |
+ while (dh != NULL) {
|
|
|
d9f2e03 |
+ pr_signals_handle();
|
|
|
d9f2e03 |
+ *((DH **) push_array(tls_tmp_dhs)) = dh;
|
|
|
d9f2e03 |
+ dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
|
|
|
d9f2e03 |
+ }
|
|
|
d9f2e03 |
+
|
|
|
d9f2e03 |
+ fclose(fp);
|
|
|
d9f2e03 |
+
|
|
|
d9f2e03 |
+ } else {
|
|
|
d9f2e03 |
+ pr_log_debug(DEBUG3, MOD_TLS_VERSION
|
|
|
d9f2e03 |
+ ": unable to open TLSDHParamFile '%s': %s", tls_dhparam_file,
|
|
|
d9f2e03 |
+ strerror(xerrno));
|
|
|
d9f2e03 |
+ }
|
|
|
d9f2e03 |
+ }
|
|
|
d9f2e03 |
|
|
|
d9f2e03 |
tls_dsa_cert_file = get_param_ptr(main_server->conf, "TLSDSACertificateFile",
|
|
|
d9f2e03 |
FALSE);
|