From 5c15ca521e0c841ecfcc35a2d53013f19b4de8e1 Mon Sep 17 00:00:00 2001
From: Finn Rayk Gaertner <finn.gartner@canonical.com>
Date: Fri, 31 Jul 2026 04:25:48 +0200
Subject: [PATCH] OpenSSL 4.0 compatibility

---
 src/lib/crypto.c |  6 +++---
 src/lib/tls.c    | 27 +++++++++++++++------------
 2 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/src/lib/crypto.c b/src/lib/crypto.c
index dd7a2f982..8913f695c 100644
--- a/src/lib/crypto.c
+++ b/src/lib/crypto.c
@@ -309,7 +309,7 @@ typedef struct PEM_CB_Context {
  *          NULL on failure.
  */
 static ASN1_OCTET_STRING *openssl_cert_keyid(X509 *cert) {
-   X509_EXTENSION *ext;
+   const X509_EXTENSION *ext;
    const X509V3_EXT_METHOD *method;
    ASN1_OCTET_STRING *keyid;
    int i;
@@ -327,11 +327,11 @@ static ASN1_OCTET_STRING *openssl_cert_keyid(X509 *cert) {
    ext = X509_get_ext(cert, i);
 
    /* Get x509 extension method structure */
-   if (!(method = X509V3_EXT_get(ext))) {
+   if (!(method = X509V3_EXT_get((X509_EXTENSION *)ext))) {
       return NULL;
    }
 
-   asn1_ext_val = X509_EXTENSION_get_data(ext);
+   asn1_ext_val = X509_EXTENSION_get_data((X509_EXTENSION *)ext);
    ext_value_data = ASN1_STRING_get0_data(asn1_ext_val);
 
    if (method->it) {
diff --git a/src/lib/tls.c b/src/lib/tls.c
index 398577997..77499434d 100644
--- a/src/lib/tls.c
+++ b/src/lib/tls.c
@@ -484,7 +484,7 @@ bool tls_postconnect_verify_cn(JCR *jcr, TLS_CONNECTION *tls, alist *verify_list
 {
    SSL *ssl = tls->openssl;
    X509 *cert;
-   X509_NAME *subject;
+   const X509_NAME *subject;
    bool auth_success = false;
    char data[256];
 
@@ -523,15 +523,15 @@ bool tls_postconnect_verify_host(JCR *jcr, TLS_CONNECTION *tls, const char *host
 {
    SSL *ssl = tls->openssl;
    X509 *cert;
-   X509_NAME *subject;
+   const X509_NAME *subject;
    bool auth_success = false;
    int extensions;
    int i, j;
    const char *pval, *phost;
 
    int cnLastPos = -1;
-   X509_NAME_ENTRY *neCN;
-   ASN1_STRING *asn1CN;
+   const X509_NAME_ENTRY *neCN;
+   const ASN1_STRING *asn1CN;
 
    /* Check if peer provided a certificate */
    if (!(cert = SSL_get_peer_certificate(ssl))) {
@@ -544,11 +544,11 @@ bool tls_postconnect_verify_host(JCR *jcr, TLS_CONNECTION *tls, const char *host
    /* Check subjectAltName extensions first */
    if ((extensions = X509_get_ext_count(cert)) > 0) {
       for (i = 0; i < extensions; i++) {
-         X509_EXTENSION *ext;
+         const X509_EXTENSION *ext;
          const char *extname;
 
          ext = X509_get_ext(cert, i);
-         extname = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
+         extname = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object((X509_EXTENSION *)ext)));
 
          if (strcmp(extname, "subjectAltName") == 0) {
 #ifdef HAVE_OPENSSLv1
@@ -563,11 +563,11 @@ bool tls_postconnect_verify_host(JCR *jcr, TLS_CONNECTION *tls, const char *host
             const ASN1_STRING *asn1_ext_val;
 
             /* Get x509 extension method structure */
-            if (!(method = X509V3_EXT_get(ext))) {
+            if (!(method = X509V3_EXT_get((X509_EXTENSION *)ext))) {
                break;
             }
 
-            asn1_ext_val = X509_EXTENSION_get_data(ext);
+            asn1_ext_val = X509_EXTENSION_get_data((X509_EXTENSION *)ext);
             ext_value_data = ASN1_STRING_get0_data(asn1_ext_val);
 
             if (method->it) {
@@ -622,26 +622,29 @@ bool tls_postconnect_verify_host(JCR *jcr, TLS_CONNECTION *tls, const char *host
       if ((subject = X509_get_subject_name(cert)) != NULL) {
          /* Loop through all CNs */
          for (;;) {
+            const char *cnval;
+
             cnLastPos = X509_NAME_get_index_by_NID(subject, NID_commonName, cnLastPos);
             if (cnLastPos == -1) {
                break;
             }
             neCN = X509_NAME_get_entry(subject, cnLastPos);
             asn1CN = X509_NAME_ENTRY_get_data(neCN);
-            if (strncasecmp((const char*)asn1CN->data, "*.", 2) == 0) {
+            cnval = (const char *)ASN1_STRING_get0_data(asn1CN);
+            if (strncasecmp(cnval, "*.", 2) == 0) {
                /* wildcard certificate */
                Dmsg0(250, "Wildcard Certificate\n");
-               pval = strstr((const char*)asn1CN->data, ".");
+               pval = strstr(cnval, ".");
                phost = strstr(host, ".");
                if (pval && phost && (strcasecmp(pval, phost) == 0)) {
                   auth_success = true;
                   goto success;
                }
-            } else if (strcasecmp((const char*)asn1CN->data, host) == 0) {
+            } else if (strcasecmp(cnval, host) == 0) {
                auth_success = true;
                break;
             }
-            Dmsg2(250, "No subject name match. Host=%s cert=%s\n", host, (const char*)asn1CN->data);
+            Dmsg2(250, "No subject name match. Host=%s cert=%s\n", host, cnval);
          }
       }
    }
-- 
2.53.0

