Use EVP_MD_fetch() instead of EVP_get_digestbynid() in X509/TLS paths

EVP_get_digestbynid() only searches the legacy built-in digest table and
cannot resolve provider-only digests, which breaks X509 signature info
computation, GOST TLS handshakes, and OCSP cert ID matching when the
digest is loaded exclusively through a provider. Switch the three affected
sites to use EVP_MD_fetch() (with the appropriate libctx/propq).
x509_sig_info_init() gains libctx/propq parameters propagated
from the X509 struct by its caller.

Resolves: https://github.com/openssl/openssl/issues/30604

Reviewed-by: Matt Caswell <matt@openssl.foundation>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
MergeDate: Sun Apr 26 13:13:14 2026
(Merged from https://github.com/openssl/openssl/pull/30888)
This commit is contained in:
Samaresh Kumar Singh
2026-04-17 18:51:08 -05:00
committed by Eugene Syromiatnikov
parent 11d9ea4ae4
commit b9ab1f3c01
3 changed files with 37 additions and 12 deletions
+21 -6
View File
@@ -211,10 +211,11 @@ int X509_get_signature_info(const X509 *x, int *mdnid, int *pknid, int *secbits,
/* Modify *siginf according to alg and sig. Return 1 on success, else 0. */
static int x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
const ASN1_STRING *sig, const EVP_PKEY *pubkey)
const ASN1_STRING *sig, const EVP_PKEY *pubkey,
OSSL_LIB_CTX *libctx, const char *propq)
{
int pknid, mdnid, md_size;
const EVP_MD *md;
EVP_MD *md;
const EVP_PKEY_ASN1_METHOD *ameth;
siginf->mdnid = NID_undef;
@@ -276,11 +277,25 @@ static int x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
break;
default:
/* Security bits: half number of bits in digest */
if ((md = EVP_get_digestbynid(mdnid)) == NULL) {
ERR_raise(ERR_LIB_X509, X509_R_ERROR_GETTING_MD_BY_NID);
return 0;
{
char md_name[80];
ASN1_OBJECT *md_obj = OBJ_nid2obj(mdnid);
if (md_obj == NULL
|| i2t_ASN1_OBJECT(md_name, sizeof(md_name), md_obj) <= 0) {
ERR_raise_data(ERR_LIB_X509, X509_R_ERROR_GETTING_MD_BY_NID,
"nid=%d", mdnid);
return 0;
}
md = EVP_MD_fetch(libctx, md_name, propq);
if (md == NULL) {
ERR_raise_data(ERR_LIB_X509, X509_R_ERROR_GETTING_MD_BY_NID,
"nid=%d name=%s", mdnid, md_name);
return 0;
}
}
md_size = EVP_MD_get_size(md);
EVP_MD_free(md);
if (md_size <= 0)
return 0;
siginf->secbits = md_size * 4;
@@ -301,5 +316,5 @@ static int x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
int ossl_x509_init_sig_info(const X509 *x, X509_SIG_INFO *info)
{
return x509_sig_info_init(info, &x->sig_alg, &x->signature,
X509_PUBKEY_get0(x->cert_info.key));
X509_PUBKEY_get0(x->cert_info.key), x->libctx, x->propq);
}
+9 -5
View File
@@ -1284,7 +1284,7 @@ static int check_cert_ocsp_resp(X509_STORE_CTX *ctx)
OCSP_CERTID *sr_cert_id = NULL;
ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
ASN1_OBJECT *cert_id_md_oid;
EVP_MD *cert_id_md;
EVP_MD *cert_id_md = NULL;
OCSP_CERTID *cert_id = NULL;
int ret = V_OCSP_CERTSTATUS_UNKNOWN;
int num;
@@ -1317,13 +1317,17 @@ static int check_cert_ocsp_resp(X509_STORE_CTX *ctx)
/* determine the md algorithm which was used to create cert id */
sr_cert_id = (OCSP_CERTID *)OCSP_SINGLERESP_get0_id(sr);
OCSP_id_get0_info(NULL, &cert_id_md_oid, NULL, NULL, sr_cert_id);
if (cert_id_md_oid != NULL)
cert_id_md = (EVP_MD *)EVP_get_digestbyobj(cert_id_md_oid);
else
cert_id_md = NULL;
if (cert_id_md_oid != NULL) {
char md_name[80];
if (i2t_ASN1_OBJECT(md_name, sizeof(md_name), cert_id_md_oid) > 0)
cert_id_md = EVP_MD_fetch(ctx->libctx, md_name, ctx->propq);
}
/* search the stack for the requested OCSP response */
cert_id = OCSP_cert_to_id(cert_id_md, ctx->current_cert, ctx->current_issuer);
EVP_MD_free(cert_id_md);
cert_id_md = NULL;
if (cert_id == NULL) {
ret = X509_V_ERR_OCSP_RESP_INVALID;
goto end;
+7 -1
View File
@@ -3701,6 +3701,7 @@ static int tls_construct_cke_gost(SSL_CONNECTION *s, WPACKET *pkt)
unsigned int md_len;
unsigned char shared_ukm[32], tmp[256];
EVP_MD_CTX *ukm_hash = NULL;
EVP_MD *ukm_md = NULL;
int dgst_nid = NID_id_GostR3411_94;
unsigned char *pms = NULL;
size_t pmslen = 0;
@@ -3751,8 +3752,10 @@ static int tls_construct_cke_gost(SSL_CONNECTION *s, WPACKET *pkt)
* data
*/
ukm_hash = EVP_MD_CTX_new();
ukm_md = EVP_MD_fetch(sctx->libctx, OBJ_nid2sn(dgst_nid), sctx->propq);
if (ukm_hash == NULL
|| EVP_DigestInit(ukm_hash, EVP_get_digestbynid(dgst_nid)) <= 0
|| ukm_md == NULL
|| EVP_DigestInit_ex(ukm_hash, ukm_md, NULL) <= 0
|| EVP_DigestUpdate(ukm_hash, s->s3.client_random,
SSL3_RANDOM_SIZE)
<= 0
@@ -3760,9 +3763,12 @@ static int tls_construct_cke_gost(SSL_CONNECTION *s, WPACKET *pkt)
SSL3_RANDOM_SIZE)
<= 0
|| EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len) <= 0) {
EVP_MD_free(ukm_md);
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto err;
}
EVP_MD_free(ukm_md);
ukm_md = NULL;
EVP_MD_CTX_free(ukm_hash);
ukm_hash = NULL;
if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT,