From 0e8f2844ed3e6c8fde0e5da0db6322735eb6593f Mon Sep 17 00:00:00 2001 From: Nikola Pajkovsky Date: Tue, 19 May 2026 10:50:02 +0200 Subject: [PATCH] fix function pointer type mismatch in PEM_X509_INFO_read_bio_ex PEM_X509_INFO_read_bio_ex stored d2i_X509, d2i_X509_AUX, d2i_X509_CRL or d2i_AutoPrivateKey -- each with a distinct, type-specific signature returning X509*, X509_CRL* or EVP_PKEY* -- in a single d2i_of_void* variable and dispatched through it: d2i = (D2I_OF(void))d2i_X509; ... d2i(pp, &p, len) Replace the function-pointer dispatch with an enum tag (pem_info_type) and a switch that calls each typed d2i_* directly with the correctly type. Signed-off-by: Nikola Pajkovsky Reviewed-by: Neil Horman Reviewed-by: Milan Broz MergeDate: Thu Jun 25 12:12:53 2026 (Merged from https://github.com/openssl/openssl/pull/31523) --- crypto/pem/pem_info.c | 52 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/crypto/pem/pem_info.c b/crypto/pem/pem_info.c index 8f38fe05807..d9bbb7256ee 100644 --- a/crypto/pem/pem_info.c +++ b/crypto/pem/pem_info.c @@ -24,6 +24,14 @@ #include #include "crypto/evp.h" +typedef enum { + PEM_INFO_NONE, + PEM_INFO_X509, + PEM_INFO_X509_AUX, + PEM_INFO_X509_CRL, + PEM_INFO_PKEY +} pem_info_type; + #ifndef OPENSSL_NO_STDIO STACK_OF(X509_INFO) *PEM_X509_INFO_read_ex(FILE *fp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, @@ -63,7 +71,7 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio_ex(BIO *bp, STACK_OF(X509_INFO) *sk, int ok = 0; STACK_OF(X509_INFO) *ret = NULL; unsigned int i, raw, ptype; - d2i_of_void *d2i = 0; + pem_info_type itype = PEM_INFO_NONE; if (sk == NULL) { if ((ret = sk_X509_INFO_new_null()) == NULL) { @@ -78,6 +86,7 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio_ex(BIO *bp, STACK_OF(X509_INFO) *sk, for (;;) { raw = 0; ptype = 0; + itype = PEM_INFO_NONE; ERR_set_mark(); i = PEM_read_bio(bp, &name, &header, &data, &len); if (i == 0) { @@ -102,15 +111,15 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio_ex(BIO *bp, STACK_OF(X509_INFO) *sk, goto start; } if ((strcmp(name, PEM_STRING_X509_TRUSTED) == 0)) - d2i = (D2I_OF(void))d2i_X509_AUX; + itype = PEM_INFO_X509_AUX; else - d2i = (D2I_OF(void))d2i_X509; + itype = PEM_INFO_X509; xi->x509 = X509_new_ex(libctx, propq); if (xi->x509 == NULL) goto err; pp = &(xi->x509); } else if (strcmp(name, PEM_STRING_X509_CRL) == 0) { - d2i = (D2I_OF(void))d2i_X509_CRL; + itype = PEM_INFO_X509_CRL; if (xi->crl != NULL) { if (!sk_X509_INFO_push(ret, xi)) goto err; @@ -137,7 +146,7 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio_ex(BIO *bp, STACK_OF(X509_INFO) *sk, xi->enc_data = NULL; xi->enc_len = 0; - d2i = (D2I_OF(void))d2i_AutoPrivateKey; + itype = PEM_INFO_PKEY; xi->x_pkey = X509_PKEY_new(); if (xi->x_pkey == NULL) goto err; @@ -146,11 +155,11 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio_ex(BIO *bp, STACK_OF(X509_INFO) *sk, || strcmp(name, PEM_STRING_PKCS8) == 0) raw = 1; } else { /* unknown */ - d2i = NULL; + itype = PEM_INFO_NONE; pp = NULL; } - if (d2i != NULL) { + if (itype != PEM_INFO_NONE) { if (!raw) { EVP_CIPHER_INFO cipher; @@ -160,15 +169,36 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio_ex(BIO *bp, STACK_OF(X509_INFO) *sk, goto err; p = data; if (ptype) { - if (d2i_PrivateKey_ex(ptype, pp, &p, len, + if (d2i_PrivateKey_ex(ptype, (EVP_PKEY **)pp, &p, len, libctx, propq) == NULL) { ERR_raise(ERR_LIB_PEM, ERR_R_ASN1_LIB); goto err; } - } else if (d2i(pp, &p, len) == NULL) { - ERR_raise(ERR_LIB_PEM, ERR_R_ASN1_LIB); - goto err; + } else { + void *decoded = NULL; + + switch (itype) { + case PEM_INFO_X509: + decoded = d2i_X509((X509 **)pp, &p, len); + break; + case PEM_INFO_X509_AUX: + decoded = d2i_X509_AUX((X509 **)pp, &p, len); + break; + case PEM_INFO_X509_CRL: + decoded = d2i_X509_CRL((X509_CRL **)pp, &p, len); + break; + case PEM_INFO_PKEY: + decoded = d2i_AutoPrivateKey_ex((EVP_PKEY **)pp, &p, + len, libctx, propq); + break; + case PEM_INFO_NONE: + break; + } + if (decoded == NULL) { + ERR_raise(ERR_LIB_PEM, ERR_R_ASN1_LIB); + goto err; + } } } else { /* encrypted key data */ if (!PEM_get_EVP_CIPHER_INFO(header, &xi->enc_cipher)) -- 2.47.3