Package: 1138443
Followup-For: Bug #1138443
X-Debbugs-Cc: [email protected]
Control: tags -1 patch

Please find attached a patch that fixes this issue. Co-authored using
GitHub Copilot.


-- System Information:
Debian Release: trixie/sid
  APT prefers noble-updates
  APT policy: (500, 'noble-updates'), (500, 'noble-security'), (500, 'noble'), 
(100, 'noble-backports')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 6.8.0-117-generic (SMP w/12 CPU threads; PREEMPT)
Kernel taint flags: TAINT_WARN
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
Description: Fix FTBFS with OpenSSL 4.0
 OpenSSL 4.0 makes X509_get_ext() return a const pointer and makes
 ASN1_OCTET_STRING fully opaque. Use a separate const variable for the
 X509_get_ext() result and replace direct struct member access (->data,
 ->length) with ASN1_STRING_get0_data() and ASN1_STRING_length() accessors.
Author: Ravi Kant Sharma <[email protected]>
Bug-Ubuntu: https://bugs.launchpad.net/bugs/2154991
Bug-Debian: https://bugs.debian.org/1138443
Forwarded: no

Index: wvstreams/crypto/wvcrl.cc
===================================================================
--- wvstreams.orig/crypto/wvcrl.cc      2026-06-10 12:57:03.057885375 +0200
+++ wvstreams/crypto/wvcrl.cc   2026-06-10 12:57:03.052885354 +0200
@@ -56,11 +56,11 @@
 
     // most of this copied from wvx509.cc, sigh
     ASN1_OCTET_STRING *ikeyid = NULL;
+    const X509_EXTENSION *src_ext;
     X509_EXTENSION *ext;
     int i = X509_get_ext_by_NID(ca.cert, NID_subject_key_identifier, -1);
-    if ((i >= 0) && (ext = X509_get_ext(ca.cert, i)))
-        ikeyid = static_cast<ASN1_OCTET_STRING *>(X509V3_EXT_d2i(ext));
-
+    if ((i >= 0) && (src_ext = X509_get_ext(ca.cert, i)))
+        ikeyid = static_cast<ASN1_OCTET_STRING 
*>(X509V3_EXT_d2i(const_cast<X509_EXTENSION *>(src_ext)));
     if (ikeyid)
     {
         AUTHORITY_KEYID *akeyid = AUTHORITY_KEYID_new();
@@ -169,7 +169,7 @@
                              &i, NULL));
     if (aki)
     {
-        char *tmp = hex_to_string(aki->keyid->data, aki->keyid->length); 
+        char *tmp = hex_to_string(ASN1_STRING_get0_data(aki->keyid), 
ASN1_STRING_length(aki->keyid));
         WvString str(tmp);
         
         OPENSSL_free(tmp);
Index: wvstreams/crypto/wvx509.cc
===================================================================
--- wvstreams.orig/crypto/wvx509.cc     2026-06-10 12:57:03.057885375 +0200
+++ wvstreams/crypto/wvx509.cc  2026-06-10 12:58:19.991208254 +0200
@@ -306,7 +306,7 @@
 
     X509_REQ_set_pubkey(certreq, pk);
 
-    name = X509_REQ_get_subject_name(certreq);
+    name = const_cast<X509_NAME *>(X509_REQ_get_subject_name(certreq));
 
     debug("Creating Certificate request for %s\n", subject);
     set_name_entry(name, subject);
@@ -606,7 +606,7 @@
 {
     CHECK_CERT_EXISTS_SET("issuer");
 
-    X509_NAME *name = X509_get_issuer_name(cert);
+    X509_NAME *name = const_cast<X509_NAME *>(X509_get_issuer_name(cert));
     set_name_entry(name, issuer);
     X509_set_issuer_name(cert, name);
 }
@@ -616,7 +616,7 @@
 {
     CHECK_CERT_EXISTS_SET("issuer");
 
-    X509_NAME *casubj = X509_get_subject_name(cacert.cert);
+    const X509_NAME *casubj = X509_get_subject_name(cacert.cert);
     X509_set_issuer_name(cert, casubj);
 }
 
@@ -636,7 +636,7 @@
 {    
     CHECK_CERT_EXISTS_SET("subject");
 
-    X509_NAME *name = X509_get_subject_name(cert);
+    X509_NAME *name = const_cast<X509_NAME *>(X509_get_subject_name(cert));
     set_name_entry(name, subject);
     X509_set_subject_name(cert, name);
 }
@@ -799,7 +799,7 @@
         ca = constraints->ca;
         if (constraints->pathlen)
         {
-            if ((constraints->pathlen->type == V_ASN1_NEG_INTEGER) || !ca)
+            if ((ASN1_INTEGER_get(constraints->pathlen) < 0) || !ca)
             {
                 debug("Path length type not valid when getting basic "
                       "constraints.\n");
@@ -1153,41 +1153,33 @@
     int index = X509_get_ext_by_NID(cert, nid, -1);
     if (index >= 0)
     {
-        X509_EXTENSION *ext = X509_get_ext(cert, index);
+        const X509_EXTENSION *ext = X509_get_ext(cert, index);
         
         if (ext)
         {
-            X509V3_EXT_METHOD *method = (X509V3_EXT_METHOD 
*)X509V3_EXT_get(ext);
-            ASN1_OCTET_STRING *ext_data_str = X509_EXTENSION_get_data(ext);
+            X509V3_EXT_METHOD *method = (X509V3_EXT_METHOD 
*)X509V3_EXT_get(const_cast<X509_EXTENSION *>(ext));
+            const ASN1_OCTET_STRING *ext_data_str = 
X509_EXTENSION_get_data(const_cast<X509_EXTENSION *>(ext));
             if (!method)
             {
                 WvDynBuf buf;
-                buf.put(ext_data_str->data, ext_data_str->length);
+                buf.put(ASN1_STRING_get0_data(ext_data_str), 
ASN1_STRING_length(ext_data_str));
                 retval = buf.getstr();
             }
             else
             {
                 void *ext_data = NULL;
-                // we NEED to use a temporary pointer for ext_value_data,
-                // as openssl's ASN1_item_d2i will muck around with it, 
-                // even though it's const (at least as of version 0.9.8e). 
-                // gah.
-#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
-                const unsigned char * ext_value_data = ext_data_str->data;
-#else
-                unsigned char *ext_value_data = ext->value->data;
-#endif
+                const unsigned char * ext_value_data = 
ASN1_STRING_get0_data(ext_data_str);
                 if (method->it)
                 {
                     ext_data = ASN1_item_d2i(NULL, &ext_value_data,
-                                             ext_data_str->length, 
+                                             ASN1_STRING_length(ext_data_str), 
                                              ASN1_ITEM_ptr(method->it));
                     TRACE("Applied generic conversion!\n");
                 }
                 else
                 {
                     ext_data = method->d2i(NULL, &ext_value_data,
-                                           ext_data_str->length);
+                                           ASN1_STRING_length(ext_data_str));
                     TRACE("Applied method specific conversion!\n");
                 }
                 
@@ -1347,7 +1339,7 @@
     memset(&d,'\0',sizeof(d));    
     memset(&newtime,'\0',sizeof newtime);
     
-    if (t->type == V_ASN1_GENERALIZEDTIME) 
+    if (ASN1_STRING_type(t) == V_ASN1_GENERALIZEDTIME) 
     {
          // For time values >= 2050, OpenSSL uses
          // ASN1_GENERALIZEDTIME - which we'll worry about
@@ -1355,7 +1347,7 @@
        return 0;
     }
 
-    p = (char *)t->data;
+    p = (char *)ASN1_STRING_get0_data(t);
     sscanf(p,"%2s%2s%2s%2s%2s%2sZ", d, &d[3], &d[6], &d[9], &d[12], &d[15]);
     
     int year = strtol(d, (char **)NULL, 10);
@@ -1448,11 +1440,11 @@
     CHECK_CERT_EXISTS_SET("ski");
 
     ASN1_OCTET_STRING *oct = ASN1_OCTET_STRING_new();
-    ASN1_BIT_STRING *pk = X509_get0_pubkey_bitstr(cert);
+    const ASN1_BIT_STRING *pk = X509_get0_pubkey_bitstr(cert);
     unsigned char pkey_dig[EVP_MAX_MD_SIZE];
     unsigned int diglen;
 
-    EVP_Digest(pk->data, pk->length, pkey_dig, &diglen, EVP_sha1(), NULL);
+    EVP_Digest(ASN1_STRING_get0_data(pk), ASN1_STRING_length(pk), pkey_dig, 
&diglen, EVP_sha1(), NULL);
 
     ASN1_OCTET_STRING_set(oct, pkey_dig, diglen);
     X509_EXTENSION *ext = X509V3_EXT_i2d(NID_subject_key_identifier, 0, 
@@ -1470,10 +1462,11 @@
     // can't set a meaningful AKI for subordinate certification without the 
     // parent having an SKI
     ASN1_OCTET_STRING *ikeyid = NULL;
+    const X509_EXTENSION *src_ext;
     X509_EXTENSION *ext;
     int i = X509_get_ext_by_NID(cacert.cert, NID_subject_key_identifier, -1);
-    if ((i >= 0) && (ext = X509_get_ext(cacert.cert, i)))
-        ikeyid = static_cast<ASN1_OCTET_STRING *>(X509V3_EXT_d2i(ext));
+    if ((i >= 0) && (src_ext = X509_get_ext(cacert.cert, i)))
+        ikeyid = static_cast<ASN1_OCTET_STRING 
*>(X509V3_EXT_d2i(const_cast<X509_EXTENSION *>(src_ext)));
 
     if (!ikeyid)
         return;
Index: wvstreams/crypto/wvx509mgr.cc
===================================================================
--- wvstreams.orig/crypto/wvx509mgr.cc  2026-06-10 12:57:03.057885375 +0200
+++ wvstreams/crypto/wvx509mgr.cc       2026-06-10 12:57:03.052885354 +0200
@@ -288,7 +288,7 @@
     {
        WvX509 newcert(X509_new());
 
-       newcert.set_subject(X509_REQ_get_subject_name(certreq));
+       newcert.set_subject(const_cast<X509_NAME 
*>(X509_REQ_get_subject_name(certreq)));
        newcert.set_version();
        
        // Set the Serial Number for the certificate

Reply via email to