DH-parameters loading support
This commit adds support for loading DH-parameters (Diffie-Hellman parameters) via the new "dhparam-file" option within "tls" clause. In particular, Diffie-Hellman parameters are needed to enable the range of forward-secrecy enabled cyphers for TLSv1.2, which are getting silently disabled otherwise.
This commit is contained in:
@@ -84,6 +84,17 @@ isc_tls_protocol_name_to_version(const char *name);
|
||||
*\li 'name' != NULL.
|
||||
*/
|
||||
|
||||
bool
|
||||
isc_tlsctx_load_dhparams(isc_tlsctx_t *ctx, const char *dhparams_file);
|
||||
/*%<
|
||||
* Load Diffie-Hellman parameters file and apply it to the given TLS context
|
||||
* 'ctx'.
|
||||
*
|
||||
* Requires:
|
||||
* \li 'ctx' != NULL;
|
||||
* \li 'dhaprams_file' a valid pointer to a non empty string.
|
||||
*/
|
||||
|
||||
isc_tls_t *
|
||||
isc_tls_create(isc_tlsctx_t *ctx);
|
||||
/*%<
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/rand.h>
|
||||
@@ -460,6 +461,71 @@ isc_tlsctx_set_protocols(isc_tlsctx_t *ctx, const uint32_t tls_versions) {
|
||||
(void)SSL_CTX_clear_options(ctx, clear_options);
|
||||
}
|
||||
|
||||
bool
|
||||
isc_tlsctx_load_dhparams(isc_tlsctx_t *ctx, const char *dhparams_file) {
|
||||
REQUIRE(ctx != NULL);
|
||||
REQUIRE(dhparams_file != NULL);
|
||||
REQUIRE(*dhparams_file != '\0');
|
||||
|
||||
#ifdef SSL_CTX_set_tmp_dh
|
||||
/* OpenSSL < 3.0 */
|
||||
DH *dh = NULL;
|
||||
FILE *paramfile;
|
||||
|
||||
paramfile = fopen(dhparams_file, "r");
|
||||
|
||||
if (paramfile) {
|
||||
int check = 0;
|
||||
dh = PEM_read_DHparams(paramfile, NULL, NULL, NULL);
|
||||
fclose(paramfile);
|
||||
|
||||
if (dh == NULL) {
|
||||
return (false);
|
||||
} else if (DH_check(dh, &check) != 1 || check != 0) {
|
||||
DH_free(dh);
|
||||
return (false);
|
||||
}
|
||||
} else {
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (SSL_CTX_set_tmp_dh(ctx, dh) != 1) {
|
||||
DH_free(dh);
|
||||
return (false);
|
||||
}
|
||||
|
||||
DH_free(dh);
|
||||
#else
|
||||
/* OpenSSL >= 3.0: SSL_CTX_set_tmp_dh() is deprecated in OpenSSL 3.0 */
|
||||
EVP_PKEY *dh = NULL;
|
||||
BIO *bio = NULL;
|
||||
|
||||
bio = BIO_new_file(dhparams_file, "r");
|
||||
if (bio == NULL) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
dh = PEM_read_bio_Parameters(bio, NULL);
|
||||
if (dh == NULL) {
|
||||
BIO_free(bio);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (SSL_CTX_set0_tmp_dh_pkey(ctx, dh) != 1) {
|
||||
BIO_free(bio);
|
||||
EVP_PKEY_free(dh);
|
||||
return (false);
|
||||
}
|
||||
|
||||
/* No need to call EVP_PKEY_free(dh) as the "dh" is owned by the
|
||||
* SSL context at this point. */
|
||||
|
||||
BIO_free(bio);
|
||||
#endif
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
isc_tls_t *
|
||||
isc_tls_create(isc_tlsctx_t *ctx) {
|
||||
isc_tls_t *newctx = NULL;
|
||||
|
||||
@@ -3887,7 +3887,7 @@ static cfg_clausedef_t tls_clauses[] = {
|
||||
{ "cert-file", &cfg_type_qstring, 0 },
|
||||
{ "ca-file", &cfg_type_qstring, 0 },
|
||||
{ "hostname", &cfg_type_qstring, 0 },
|
||||
{ "dh-param", &cfg_type_qstring, CFG_CLAUSEFLAG_EXPERIMENTAL },
|
||||
{ "dhparam-file", &cfg_type_qstring, 0 },
|
||||
{ "protocols", &cfg_type_tlsprotos, 0 },
|
||||
{ "ciphers", &cfg_type_astring, CFG_CLAUSEFLAG_EXPERIMENTAL },
|
||||
{ NULL, NULL, 0 }
|
||||
|
||||
@@ -63,6 +63,7 @@ typedef struct ns_listen_tls_params {
|
||||
const char *key;
|
||||
const char *cert;
|
||||
uint32_t protocols;
|
||||
const char *dhparam_file;
|
||||
} ns_listen_tls_params_t;
|
||||
|
||||
/***
|
||||
|
||||
@@ -46,6 +46,15 @@ ns_listenelt_create(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp,
|
||||
if (tls_params->protocols != 0) {
|
||||
isc_tlsctx_set_protocols(sslctx, tls_params->protocols);
|
||||
}
|
||||
|
||||
if (tls_params->dhparam_file != NULL) {
|
||||
if (!isc_tlsctx_load_dhparams(sslctx,
|
||||
tls_params->dhparam_file))
|
||||
{
|
||||
isc_tlsctx_free(&sslctx);
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
elt = isc_mem_get(mctx, sizeof(*elt));
|
||||
|
||||
Reference in New Issue
Block a user