[Openvpn-devel,v5] OpenSSL 4.0: Make X509 objects const

Message ID 20260402121049.41102-1-frank@lichtenheld.com
State New
Headers show
Series [Openvpn-devel,v5] OpenSSL 4.0: Make X509 objects const | expand

Commit Message

Frank Lichtenheld April 2, 2026, 12:10 p.m. UTC
From: Arne Schwabe <arne@rfc2549.org>

In OpenSSL 4.0 a lot of the APIs have changed to return const objects.
Adjust our source code to use const objects as well.

Change-Id: Iea1d13c160599f134587c6f1c2f4a90e7f5e3991
Signed-off-by: Arne Schwabe <arne@rfc2549.org>
Acked-by: Frank Lichtenheld <frank@lichtenheld.com>
Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1596
---

This change was reviewed on Gerrit and approved by at least one
developer. I request to merge it to master.

Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1596
This mail reflects revision 5 of this Change.

Acked-by according to Gerrit (reflected above):
Frank Lichtenheld <frank@lichtenheld.com>

Comments

Gert Doering April 4, 2026, 3:51 p.m. UTC | #1
Most of these changes are easy enough (it really needs the comments to
explain why the cast :-) )

The second change in ssl_openssl.c looks a bit spurious, but then, not
overwriting our initial "xn" in the dup looks like good housekeeping...
- finding useful documentation about the functions involved is hard,
though.

Tested by pushing to GHA which builds with all these different library
versions...

Your patch has been applied to the master and release/2.7 branch
(long-term compat).

commit 9b663a08245d92527059c9681e9d429badd6cdef (master)
commit 120bc506b0c61f5353cacbcbdb4a371e0330eeb3 (release/2.7)
Author: Arne Schwabe
Date:   Thu Apr 2 14:10:49 2026 +0200

     OpenSSL 4.0: Make X509 objects const

     Signed-off-by: Arne Schwabe <arne@rfc2549.org>
     Acked-by: Frank Lichtenheld <frank@lichtenheld.com>
     Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1596
     Message-Id: <20260402121049.41102-1-frank@lichtenheld.com>
     URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg36437.html
     Signed-off-by: Gert Doering <gert@greenie.muc.de>


--
kind regards,

Gert Doering

Patch

diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
index a26663a..fd05f43 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -1789,7 +1789,6 @@ 
     STACK_OF(X509_NAME) *cert_names = NULL;
     X509_LOOKUP *lookup = NULL;
     X509_STORE *store = NULL;
-    X509_NAME *xn = NULL;
     BIO *in = NULL;
     int i, added = 0, prev = 0;
 
@@ -1853,21 +1852,26 @@ 
                         }
                     }
 
-                    xn = X509_get_subject_name(info->x509);
+                    /* OpenSSL 4.0 has made X509_get_subject_name return const
+                     * but not adjusted the other functions to take const
+                     * arguments, and other libraries do not have const
+                     * arguments, so just ignore const here */
+                    X509_NAME *xn = (X509_NAME *)X509_get_subject_name(info->x509);
                     if (!xn)
                     {
                         continue;
                     }
 
+
                     /* Don't add duplicate CA names */
-                    if (sk_X509_NAME_find(cert_names, xn) == -1)
+                    if (sk_X509_NAME_find(cert_names, (X509_NAME *)xn) == -1)
                     {
-                        xn = X509_NAME_dup(xn);
-                        if (!xn)
+                        X509_NAME *xn_dup = X509_NAME_dup(xn);
+                        if (!xn_dup)
                         {
                             continue;
                         }
-                        sk_X509_NAME_push(cert_names, xn);
+                        sk_X509_NAME_push(cert_names, xn_dup);
                     }
                 }
 
diff --git a/src/openvpn/ssl_verify_openssl.c b/src/openvpn/ssl_verify_openssl.c
index 08946cd..c5c4acd 100644
--- a/src/openvpn/ssl_verify_openssl.c
+++ b/src/openvpn/ssl_verify_openssl.c
@@ -191,7 +191,7 @@ 
  * to contain result is grounds for error).
  */
 static result_t
-extract_x509_field_ssl(X509_NAME *x509, const char *field_name, char *out, size_t size)
+extract_x509_field_ssl(const X509_NAME *x509, const char *field_name, char *out, size_t size)
 {
     int lastpos = -1;
     int tmp = -1;
@@ -209,7 +209,12 @@ 
     do
     {
         lastpos = tmp;
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
         tmp = X509_NAME_get_index_by_OBJ(x509, field_name_obj, lastpos);
+#else
+        /* OpenSSL 1.1.x has the argument as non-const */
+        tmp = X509_NAME_get_index_by_OBJ((X509_NAME *)x509, field_name_obj, lastpos);
+#endif
     } while (tmp > -1);
 
     ASN1_OBJECT_free(field_name_obj);
@@ -269,7 +274,7 @@ 
     }
     else
     {
-        X509_NAME *x509_subject_name = X509_get_subject_name(peer_cert);
+        const X509_NAME *x509_subject_name = X509_get_subject_name(peer_cert);
         if (x509_subject_name == NULL)
         {
             msg(D_TLS_ERRORS, "X509 subject name is NULL");
@@ -457,7 +462,12 @@ 
 x509_setenv_track(const struct x509_track *xt, struct env_set *es, const int depth, X509 *x509)
 {
     struct gc_arena gc = gc_new();
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+    /* OpenSSL 1.1.x APIs all take non-const arguments */
     X509_NAME *x509_name = X509_get_subject_name(x509);
+#else
+    const X509_NAME *x509_name = X509_get_subject_name(x509);
+#endif
     const char nullc = '\0';
 
     while (xt)
@@ -491,10 +501,10 @@ 
                     int i = X509_NAME_get_index_by_NID(x509_name, xt->nid, -1);
                     if (i >= 0)
                     {
-                        X509_NAME_ENTRY *ent = X509_NAME_get_entry(x509_name, i);
+                        const X509_NAME_ENTRY *ent = X509_NAME_get_entry(x509_name, i);
                         if (ent)
                         {
-                            ASN1_STRING *val = X509_NAME_ENTRY_get_data(ent);
+                            const ASN1_STRING *val = X509_NAME_ENTRY_get_data(ent);
                             unsigned char *buf = NULL;
                             if (ASN1_STRING_to_UTF8(&buf, val) >= 0)
                             {
@@ -508,7 +518,11 @@ 
                         i = X509_get_ext_by_NID(x509, xt->nid, -1);
                         if (i >= 0)
                         {
+#if OPENSSL_VERSION_NUMBER < 0x40000000L
                             X509_EXTENSION *ext = X509_get_ext(x509, i);
+#else
+                            const X509_EXTENSION *ext = X509_get_ext(x509, i);
+#endif
                             if (ext)
                             {
                                 BIO *bio = BIO_new(BIO_s_mem());
@@ -544,51 +558,43 @@ 
 void
 x509_setenv(struct env_set *es, int cert_depth, openvpn_x509_cert_t *peer_cert)
 {
-    int i, n;
-    int fn_nid;
-    ASN1_OBJECT *fn;
-    ASN1_STRING *val;
-    X509_NAME_ENTRY *ent;
-    const char *objbuf;
-    unsigned char *buf = NULL;
-    char *name_expand;
-    size_t name_expand_size;
-    X509_NAME *x509 = X509_get_subject_name(peer_cert);
+    const X509_NAME *x509 = X509_get_subject_name(peer_cert);
 
-    n = X509_NAME_entry_count(x509);
-    for (i = 0; i < n; ++i)
+    int n = X509_NAME_entry_count(x509);
+    for (int i = 0; i < n; ++i)
     {
-        ent = X509_NAME_get_entry(x509, i);
+        const X509_NAME_ENTRY *ent = X509_NAME_get_entry(x509, i);
         if (!ent)
         {
             continue;
         }
-        fn = X509_NAME_ENTRY_get_object(ent);
+        const ASN1_OBJECT *fn = X509_NAME_ENTRY_get_object(ent);
         if (!fn)
         {
             continue;
         }
-        val = X509_NAME_ENTRY_get_data(ent);
+        const ASN1_STRING *val = X509_NAME_ENTRY_get_data(ent);
         if (!val)
         {
             continue;
         }
-        fn_nid = OBJ_obj2nid(fn);
+        int fn_nid = OBJ_obj2nid(fn);
         if (fn_nid == NID_undef)
         {
             continue;
         }
-        objbuf = OBJ_nid2sn(fn_nid);
+        const char *objbuf = OBJ_nid2sn(fn_nid);
         if (!objbuf)
         {
             continue;
         }
+        unsigned char *buf = NULL;
         if (ASN1_STRING_to_UTF8(&buf, val) < 0)
         {
             continue;
         }
-        name_expand_size = 64 + strlen(objbuf);
-        name_expand = (char *)malloc(name_expand_size);
+        size_t name_expand_size = 64 + strlen(objbuf);
+        char *name_expand = malloc(name_expand_size);
         check_malloc_return(name_expand);
         snprintf(name_expand, name_expand_size, "X509_%d_%s", cert_depth, objbuf);
         string_mod(name_expand, CC_PRINT, CC_CRLF, '_');