diff --git a/include/haproxy/ssl_sock.h b/include/haproxy/ssl_sock.h index e80ad2dd4..cd1c2d402 100644 --- a/include/haproxy/ssl_sock.h +++ b/include/haproxy/ssl_sock.h @@ -95,6 +95,7 @@ struct tls_keys_ref *tlskeys_ref_lookup(const char *filename); struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id); #endif #ifndef OPENSSL_NO_DH +HASSL_DH *ssl_sock_get_dh_from_bio(BIO *bio); int ssl_sock_load_global_dh_param_from_file(const char *filename); void ssl_free_dh(void); #endif diff --git a/src/ssl_sock.c b/src/ssl_sock.c index b360f714b..41a716573 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -3084,6 +3084,40 @@ static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen) return dh; } +HASSL_DH *ssl_sock_get_dh_from_bio(BIO *bio) +{ +#if (HA_OPENSSL_VERSION_NUMBER >= 0x3000000fL) + HASSL_DH *dh = NULL; + OSSL_DECODER_CTX *dctx = NULL; + const char *format = "PEM"; + const char *keytype = "DH"; + + dctx = OSSL_DECODER_CTX_new_for_pkey(&dh, format, NULL, keytype, + OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, + NULL, NULL); + + if (dctx == NULL || OSSL_DECODER_CTX_get_num_decoders(dctx) == 0) + goto end; + + /* The DH parameters might not be the first section found in the PEM + * file so we need to iterate over all of them until we find the right + * one. + */ + while (!BIO_eof(bio) && !dh) + OSSL_DECODER_from_bio(dctx, bio); + +end: + OSSL_DECODER_CTX_free(dctx); + return dh; +#else + HASSL_DH *dh = NULL; + + dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); + + return dh; +#endif +} + static DH * ssl_sock_get_dh_from_file(const char *filename) { DH *dh = NULL;