]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
fix function pointer type mismatch in PEM_X509_INFO_read_bio_ex
authorNikola Pajkovsky <nikolap@openssl.org>
Tue, 19 May 2026 08:50:02 +0000 (10:50 +0200)
committerNeil Horman <nhorman@openssl.org>
Thu, 25 Jun 2026 12:12:29 +0000 (08:12 -0400)
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 <nikolap@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Milan Broz <mbroz@openssl.org>
MergeDate: Thu Jun 25 12:12:53 2026
(Merged from https://github.com/openssl/openssl/pull/31523)

crypto/pem/pem_info.c

index 8f38fe058079ee4b48e6dcb62edde7bb5cc3a40c..d9bbb7256eee66362c9d9d62b9487f5666be1e10 100644 (file)
 #include <openssl/dsa.h>
 #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))