Commit 2e976c3a38 for openssl.org
commit 2e976c3a3850f32ff13af59b2920585426d6571a
Author: Chris Baudouin, Jr. <cjb5326@rit.edu>
Date: Sat Mar 21 18:08:01 2026 +0000
Adds NULL checks for EVP_MD_CTX_get_pkey_ctx() return values
Guard against potential NULL pointer dereferences when
EVP_MD_CTX_get_pkey_ctx() is called and its result is used
without validation. Store the return value in a local variable,
check for NULL before passing it to subsequent functions, and
remove redundant repeated calls.
Fixes #27735
Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Fri Mar 27 16:39:04 2026
(Merged from https://github.com/openssl/openssl/pull/30522)
diff --git a/crypto/asn1/a_sign.c b/crypto/asn1/a_sign.c
index 1088e20967..d83efa2816 100644
--- a/crypto/asn1/a_sign.c
+++ b/crypto/asn1/a_sign.c
@@ -163,6 +163,7 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
const void *data, EVP_MD_CTX *ctx)
{
const EVP_MD *md;
+ EVP_PKEY_CTX *pctx;
EVP_PKEY *pkey;
unsigned char *buf_in = NULL, *buf_out = NULL;
size_t inl = 0, outl = 0, outll = 0;
@@ -170,7 +171,14 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
int rv, pkey_id;
md = EVP_MD_CTX_get0_md(ctx);
- pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_get_pkey_ctx(ctx));
+ pctx = EVP_MD_CTX_get_pkey_ctx(ctx);
+
+ if (pctx == NULL) {
+ ERR_raise(ERR_LIB_ASN1, ASN1_R_CONTEXT_NOT_INITIALISED);
+ goto err;
+ }
+
+ pkey = EVP_PKEY_CTX_get0_pkey(pctx);
if (pkey == NULL) {
ERR_raise(ERR_LIB_ASN1, ASN1_R_CONTEXT_NOT_INITIALISED);
@@ -178,13 +186,11 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
}
if (pkey->ameth == NULL) {
- EVP_PKEY_CTX *pctx = EVP_MD_CTX_get_pkey_ctx(ctx);
OSSL_PARAM params[2];
unsigned char aid[128];
size_t aid_len = 0;
- if (pctx == NULL
- || !EVP_PKEY_CTX_IS_SIGNATURE_OP(pctx)) {
+ if (!EVP_PKEY_CTX_IS_SIGNATURE_OP(pctx)) {
ERR_raise(ERR_LIB_ASN1, ASN1_R_CONTEXT_NOT_INITIALISED);
goto err;
}
diff --git a/crypto/asn1/a_verify.c b/crypto/asn1/a_verify.c
index 3772939e74..5dae9e9c75 100644
--- a/crypto/asn1/a_verify.c
+++ b/crypto/asn1/a_verify.c
@@ -90,6 +90,7 @@ static int item_verify(const ASN1_ITEM *it, const X509_ALGOR *alg,
const ASN1_BIT_STRING *signature, const void *data,
EVP_MD_CTX *ctx, OSSL_LIB_CTX *libctx, const char *propq)
{
+ EVP_PKEY_CTX *pctx;
EVP_PKEY *pkey;
EVP_MD *type = NULL;
unsigned char *buf_in = NULL;
@@ -97,7 +98,14 @@ static int item_verify(const ASN1_ITEM *it, const X509_ALGOR *alg,
int mdnid, pknid;
size_t inll = 0;
- pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_get_pkey_ctx(ctx));
+ pctx = EVP_MD_CTX_get_pkey_ctx(ctx);
+
+ if (pctx == NULL) {
+ ERR_raise(ERR_LIB_ASN1, ASN1_R_CONTEXT_NOT_INITIALISED);
+ return -1;
+ }
+
+ pkey = EVP_PKEY_CTX_get0_pkey(pctx);
if (pkey == NULL) {
ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_NULL_PARAMETER);
diff --git a/crypto/ocsp/ocsp_srv.c b/crypto/ocsp/ocsp_srv.c
index cc6a5bea5f..beecad63a2 100644
--- a/crypto/ocsp/ocsp_srv.c
+++ b/crypto/ocsp/ocsp_srv.c
@@ -167,14 +167,15 @@ int OCSP_basic_sign_ctx(OCSP_BASICRESP *brsp,
const STACK_OF(X509) *certs, unsigned long flags)
{
OCSP_RESPID *rid;
+ EVP_PKEY_CTX *pkctx;
EVP_PKEY *pkey;
- if (ctx == NULL || EVP_MD_CTX_get_pkey_ctx(ctx) == NULL) {
+ if (ctx == NULL || (pkctx = EVP_MD_CTX_get_pkey_ctx(ctx)) == NULL) {
ERR_raise(ERR_LIB_OCSP, OCSP_R_NO_SIGNER_KEY);
goto err;
}
- pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_get_pkey_ctx(ctx));
+ pkey = EVP_PKEY_CTX_get0_pkey(pkctx);
if (pkey == NULL || !X509_check_private_key(signer, pkey)) {
ERR_raise(ERR_LIB_OCSP, OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
goto err;
diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c
index 87bbaf04e3..1eb4649481 100644
--- a/crypto/rsa/rsa_ameth.c
+++ b/crypto/rsa/rsa_ameth.c
@@ -653,6 +653,10 @@ static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *asn,
int pad_mode;
EVP_PKEY_CTX *pkctx = EVP_MD_CTX_get_pkey_ctx(ctx);
+ if (pkctx == NULL) {
+ ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0)
return 0;
if (pad_mode == RSA_PKCS1_PADDING)
diff --git a/ssl/record/methods/tls1_meth.c b/ssl/record/methods/tls1_meth.c
index e6360d995c..f89c365d7f 100644
--- a/ssl/record/methods/tls1_meth.c
+++ b/ssl/record/methods/tls1_meth.c
@@ -414,6 +414,7 @@ static int tls1_mac(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec, unsigned char *md
EVP_MD_CTX *hash;
size_t md_size;
EVP_MD_CTX *hmac = NULL, *mac_ctx;
+ EVP_PKEY_CTX *pkctx;
unsigned char header[13];
int t;
int ret = 0;
@@ -466,8 +467,13 @@ static int tls1_mac(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec, unsigned char *md
&rec->orig_len);
*p++ = OSSL_PARAM_construct_end();
- if (!EVP_PKEY_CTX_set_params(EVP_MD_CTX_get_pkey_ctx(mac_ctx),
- tls_hmac_params))
+ pkctx = EVP_MD_CTX_get_pkey_ctx(mac_ctx);
+ if (pkctx == NULL) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ goto end;
+ }
+
+ if (!EVP_PKEY_CTX_set_params(pkctx, tls_hmac_params))
goto end;
}