MEDIUM: ssl: Replace all DH objects by EVP_PKEY on OpenSSLv3 (via HASSL_DH type)

DH structure is a low-level one that should not be used anymore with
OpenSSLv3. All functions working on DH were marked as deprecated and
this patch replaces the ones we used with new APIs recommended in
OpenSSLv3, be it in the migration guide or the multiple new manpages
they created.
This patch replaces all mentions of the DH type by the HASSL_DH one,
which will be replaced by EVP_PKEY with OpenSSLv3 and will remain DH on
older versions. It also uses all the newly created helper functions that
enable for instance to load DH parameters from a file into an EVP_PKEY,
or to set DH parameters into an SSL_CTX for use in a DHE negotiation.

The following deprecated functions will effectively disappear when
building with OpenSSLv3 : DH_set0_pqg, PEM_read_bio_DHparams, DH_new,
DH_free, DH_up_ref, SSL_CTX_set_tmp_dh.
This commit is contained in:
Remi Tricot-Le Breton 2022-02-11 12:04:55 +01:00 committed by William Lallemand
parent 55d7e782ee
commit c76c3c4e59
3 changed files with 53 additions and 61 deletions

View File

@ -50,7 +50,7 @@ struct cert_key_and_chain {
X509 *cert; X509 *cert;
EVP_PKEY *key; EVP_PKEY *key;
STACK_OF(X509) *chain; STACK_OF(X509) *chain;
DH *dh; HASSL_DH *dh;
struct buffer *sctl; struct buffer *sctl;
struct buffer *ocsp_response; struct buffer *ocsp_response;
X509 *ocsp_issuer; X509 *ocsp_issuer;

View File

@ -499,7 +499,7 @@ int ssl_sock_load_pem_into_ckch(const char *path, char *buf, struct cert_key_and
X509 *ca; X509 *ca;
X509 *cert = NULL; X509 *cert = NULL;
EVP_PKEY *key = NULL; EVP_PKEY *key = NULL;
DH *dh = NULL; HASSL_DH *dh = NULL;
STACK_OF(X509) *chain = NULL; STACK_OF(X509) *chain = NULL;
if (buf) { if (buf) {
@ -537,7 +537,8 @@ int ssl_sock_load_pem_into_ckch(const char *path, char *buf, struct cert_key_and
goto end; goto end;
} }
dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); dh = ssl_sock_get_dh_from_bio(in);
ERR_clear_error();
/* no need to return an error there, dh is not mandatory */ /* no need to return an error there, dh is not mandatory */
#endif #endif
@ -605,7 +606,7 @@ end:
if (key) if (key)
EVP_PKEY_free(key); EVP_PKEY_free(key);
if (dh) if (dh)
DH_free(dh); HASSL_DH_free(dh);
if (cert) if (cert)
X509_free(cert); X509_free(cert);
if (chain) if (chain)
@ -637,7 +638,7 @@ void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
ckch->chain = NULL; ckch->chain = NULL;
if (ckch->dh) if (ckch->dh)
DH_free(ckch->dh); HASSL_DH_free(ckch->dh);
ckch->dh = NULL; ckch->dh = NULL;
if (ckch->sctl) { if (ckch->sctl) {
@ -685,7 +686,7 @@ struct cert_key_and_chain *ssl_sock_copy_cert_key_and_chain(struct cert_key_and_
} }
if (src->dh) { if (src->dh) {
DH_up_ref(src->dh); HASSL_DH_up_ref(src->dh);
dst->dh = src->dh; dst->dh = src->dh;
} }

View File

@ -467,10 +467,10 @@ struct ssl_engine_list {
#ifndef OPENSSL_NO_DH #ifndef OPENSSL_NO_DH
static int ssl_dh_ptr_index = -1; static int ssl_dh_ptr_index = -1;
static DH *global_dh = NULL; static HASSL_DH *global_dh = NULL;
static DH *local_dh_1024 = NULL; static HASSL_DH *local_dh_1024 = NULL;
static DH *local_dh_2048 = NULL; static HASSL_DH *local_dh_2048 = NULL;
static DH *local_dh_4096 = NULL; static HASSL_DH *local_dh_4096 = NULL;
static DH *ssl_get_tmp_dh_cbk(SSL *ssl, int export, int keylen); static DH *ssl_get_tmp_dh_cbk(SSL *ssl, int export, int keylen);
#endif /* OPENSSL_NO_DH */ #endif /* OPENSSL_NO_DH */
@ -2927,7 +2927,7 @@ end:
return pkey; return pkey;
#else #else
DH *dh = DH_new(); HASSL_DH *dh = DH_new();
if (!dh) if (!dh)
return NULL; return NULL;
@ -2939,7 +2939,7 @@ end:
} }
static DH * ssl_get_dh_1024(void) static HASSL_DH * ssl_get_dh_1024(void)
{ {
static unsigned char dh1024_p[]={ static unsigned char dh1024_p[]={
0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7, 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
@ -2960,22 +2960,19 @@ static DH * ssl_get_dh_1024(void)
BIGNUM *p; BIGNUM *p;
BIGNUM *g; BIGNUM *g;
DH *dh = DH_new();
if (dh) { HASSL_DH *dh = NULL;
p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL); p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL); g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
if (!p || !g) { if (p && g)
DH_free(dh); dh = ssl_new_dh_fromdata(p, g);
dh = NULL;
} else {
DH_set0_pqg(dh, p, NULL, g);
}
}
return dh; return dh;
} }
static DH *ssl_get_dh_2048(void) static HASSL_DH *ssl_get_dh_2048(void)
{ {
static unsigned char dh2048_p[]={ static unsigned char dh2048_p[]={
0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59, 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
@ -3007,22 +3004,19 @@ static DH *ssl_get_dh_2048(void)
BIGNUM *p; BIGNUM *p;
BIGNUM *g; BIGNUM *g;
DH *dh = DH_new();
if (dh) { HASSL_DH *dh = NULL;
p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL); p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL); g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
if (!p || !g) { if (p && g)
DH_free(dh); dh = ssl_new_dh_fromdata(p, g);
dh = NULL;
} else {
DH_set0_pqg(dh, p, NULL, g);
}
}
return dh; return dh;
} }
static DH *ssl_get_dh_4096(void) static HASSL_DH *ssl_get_dh_4096(void)
{ {
static unsigned char dh4096_p[]={ static unsigned char dh4096_p[]={
0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11, 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
@ -3075,24 +3069,21 @@ static DH *ssl_get_dh_4096(void)
BIGNUM *p; BIGNUM *p;
BIGNUM *g; BIGNUM *g;
DH *dh = DH_new();
if (dh) { HASSL_DH *dh = NULL;
p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL); p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL); g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
if (!p || !g) { if (p && g)
DH_free(dh); dh = ssl_new_dh_fromdata(p, g);
dh = NULL;
} else {
DH_set0_pqg(dh, p, NULL, g);
}
}
return dh; return dh;
} }
static DH *ssl_get_tmp_dh(EVP_PKEY *pkey) static HASSL_DH *ssl_get_tmp_dh(EVP_PKEY *pkey)
{ {
DH *dh = NULL; HASSL_DH *dh = NULL;
int type; int type;
int keylen = 0; int keylen = 0;
@ -3130,7 +3121,7 @@ static DH *ssl_get_tmp_dh(EVP_PKEY *pkey)
/* Returns Diffie-Hellman parameters matching the private key length /* Returns Diffie-Hellman parameters matching the private key length
but not exceeding global_ssl.default_dh_param */ but not exceeding global_ssl.default_dh_param */
static DH *ssl_get_tmp_dh_cbk(SSL *ssl, int export, int keylen) static HASSL_DH *ssl_get_tmp_dh_cbk(SSL *ssl, int export, int keylen)
{ {
EVP_PKEY *pkey = SSL_get_privatekey(ssl); EVP_PKEY *pkey = SSL_get_privatekey(ssl);
@ -3202,9 +3193,9 @@ end:
#endif #endif
} }
static DH * ssl_sock_get_dh_from_file(const char *filename) static HASSL_DH * ssl_sock_get_dh_from_file(const char *filename)
{ {
DH *dh = NULL; HASSL_DH *dh = NULL;
BIO *in = BIO_new(BIO_s_file()); BIO *in = BIO_new(BIO_s_file());
if (in == NULL) if (in == NULL)
@ -3213,7 +3204,7 @@ static DH * ssl_sock_get_dh_from_file(const char *filename)
if (BIO_read_filename(in, filename) <= 0) if (BIO_read_filename(in, filename) <= 0)
goto end; goto end;
dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); dh = ssl_sock_get_dh_from_bio(in);
end: end:
if (in) if (in)
@ -3362,11 +3353,11 @@ static int ssl_sock_load_dh_params(SSL_CTX *ctx, const struct cert_key_and_chain
const char *path, char **err) const char *path, char **err)
{ {
int ret = 0; int ret = 0;
DH *dh = NULL; HASSL_DH *dh = NULL;
if (ckch && ckch->dh) { if (ckch && ckch->dh) {
dh = ckch->dh; dh = ckch->dh;
if (!SSL_CTX_set_tmp_dh(ctx, dh)) { if (!ssl_sock_set_tmp_dh(ctx, dh)) {
memprintf(err, "%sunable to load the DH parameter specified in '%s'", memprintf(err, "%sunable to load the DH parameter specified in '%s'",
err && *err ? *err : "", path); err && *err ? *err : "", path);
#if defined(SSL_CTX_set_dh_auto) #if defined(SSL_CTX_set_dh_auto)
@ -3388,7 +3379,7 @@ static int ssl_sock_load_dh_params(SSL_CTX *ctx, const struct cert_key_and_chain
} }
} }
else if (global_dh) { else if (global_dh) {
if (!SSL_CTX_set_tmp_dh(ctx, global_dh)) { if (!ssl_sock_set_tmp_dh(ctx, global_dh)) {
memprintf(err, "%sunable to use the global DH parameter for certificate '%s'", memprintf(err, "%sunable to use the global DH parameter for certificate '%s'",
err && *err ? *err : "", path); err && *err ? *err : "", path);
#if defined(SSL_CTX_set_dh_auto) #if defined(SSL_CTX_set_dh_auto)
@ -3419,7 +3410,7 @@ static int ssl_sock_load_dh_params(SSL_CTX *ctx, const struct cert_key_and_chain
goto end; goto end;
} }
if (!SSL_CTX_set_tmp_dh(ctx, local_dh_1024)) { if (!ssl_sock_set_tmp_dh(ctx, local_dh_1024)) {
memprintf(err, "%sunable to load default 1024 bits DH parameter for certificate '%s'.\n", memprintf(err, "%sunable to load default 1024 bits DH parameter for certificate '%s'.\n",
err && *err ? *err : "", path); err && *err ? *err : "", path);
#if defined(SSL_CTX_set_dh_auto) #if defined(SSL_CTX_set_dh_auto)
@ -7983,19 +7974,19 @@ void ssl_free_engines(void) {
#ifndef OPENSSL_NO_DH #ifndef OPENSSL_NO_DH
void ssl_free_dh(void) { void ssl_free_dh(void) {
if (local_dh_1024) { if (local_dh_1024) {
DH_free(local_dh_1024); HASSL_DH_free(local_dh_1024);
local_dh_1024 = NULL; local_dh_1024 = NULL;
} }
if (local_dh_2048) { if (local_dh_2048) {
DH_free(local_dh_2048); HASSL_DH_free(local_dh_2048);
local_dh_2048 = NULL; local_dh_2048 = NULL;
} }
if (local_dh_4096) { if (local_dh_4096) {
DH_free(local_dh_4096); HASSL_DH_free(local_dh_4096);
local_dh_4096 = NULL; local_dh_4096 = NULL;
} }
if (global_dh) { if (global_dh) {
DH_free(global_dh); HASSL_DH_free(global_dh);
global_dh = NULL; global_dh = NULL;
} }
} }