mirror of
https://github.com/openssl/openssl.git
synced 2026-05-07 20:12:39 +00:00
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:
committed by
Eugene Syromiatnikov
parent
11d9ea4ae4
commit
b9ab1f3c01
+21
-6
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user