diff mbox series

[meta-oe,RFC,02/20] krb5: fix build with OpenSSL 4.0

Message ID 20260827185324.78997-3-jaipaul.cheernam@est.tech
State New
Headers show
Series Fix OpenSSL 4.0.1 build failures across meta-openembedded | expand

Commit Message

Jaipaul Cheernam Aug. 27, 2026, 6:53 p.m. UTC
OpenSSL 4.0 adds const qualifiers to X509 accessor return types,
makes ASN1_STRING opaque, and removes OpenSSL 1.0 compatibility
functions.

Backport three patches:
- Improve future OpenSSL compatibility (upstream 5e4e84523288)
- Remove OpenSSL 1.0 support (upstream f8a47bf037af, context adjusted)
- Fix remaining const qualifiers in k5tls for 1.22.x (functions
  removed on trunk, fix only needed for this version)

Upstream-Status: Backport / Inappropriate (patch 3)
Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech>
---
 ...Improve-future-OpenSSL-compatibility.patch | 285 ++++++++
 .../0002-Remove-OpenSSL-1.0-support.patch     | 627 ++++++++++++++++++
 ...ing-const-qualifiers-for-OpenSSL-4.0.patch |  67 ++
 .../recipes-connectivity/krb5/krb5_1.22.2.bb  |   3 +
 4 files changed, 982 insertions(+)
 create mode 100644 meta-oe/recipes-connectivity/krb5/krb5/0001-Improve-future-OpenSSL-compatibility.patch
 create mode 100644 meta-oe/recipes-connectivity/krb5/krb5/0002-Remove-OpenSSL-1.0-support.patch
 create mode 100644 meta-oe/recipes-connectivity/krb5/krb5/0003-k5tls-fix-remaining-const-qualifiers-for-OpenSSL-4.0.patch
diff mbox series

Patch

diff --git a/meta-oe/recipes-connectivity/krb5/krb5/0001-Improve-future-OpenSSL-compatibility.patch b/meta-oe/recipes-connectivity/krb5/krb5/0001-Improve-future-OpenSSL-compatibility.patch
new file mode 100644
index 0000000000..3ae23f0031
--- /dev/null
+++ b/meta-oe/recipes-connectivity/krb5/krb5/0001-Improve-future-OpenSSL-compatibility.patch
@@ -0,0 +1,285 @@ 
+From 5e4e8452328804948d042235bbf58ca457795857 Mon Sep 17 00:00:00 2001
+From: Bob Beck <beck@openssl.org>
+Date: Mon, 16 Feb 2026 15:15:55 -0700
+Subject: [PATCH] Improve future OpenSSL compatibility
+
+Avoid calling deprecated OpenSSL functions when compiling against
+versions of OpenSSL where they are deprecated.  Add
+-DOPENSSL_NO_DEPRECATED to the linux-clang-openssl CI build to help
+detect calls to deprecated functions in the future.
+
+Use const pointer variables to hold values retrieved by accessors
+which will return const pointers in OpenSSL 4.0.  Define macros to
+make certain functions accept these const pointers in versions of
+OpenSSL where they don't already do so.
+
+Use accessor functions instead of direct field access for ASN1_STRING
+values, as the type will become opaque in OpenSSL 4.0.
+
+The PKINIT code is written to assume that DHX support was not present
+until OpenSSL 1.1, but it was added in release 1.0.2, causing a
+compilation error against 1.0.2 from a double definition of
+EVP_PKEY_DHX.  Minimally fix the compilation error.  (The custom DHX
+marshalling code to support 1.0.x could be removed, as 1.0.2 is the
+minimum version after commit f5bbfa4821cf590a4748f96d0e016bc0485e95c4,
+but the plan is to remove 1.0.x compatibility shortly.)
+
+Contains work by Frederik Wedel-Heinen
+<frederik.wedel-heinen@dencrypt.dk> and Dimitri John Ledkov
+<dimitri.ledkov@surgut.co.uk>.
+
+[ghudson@mit.edu: combined numerous commits; added compatibility
+macros; rewrote commit message; fixed 1.0.2 compatibility issue]
+Upstream-Status: Backport [https://github.com/krb5/krb5/commit/5e4e84523288]
+
+Note: .github/workflows/build.yml hunk dropped (CI-only, not relevant
+for OE builds).
+Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech>
+---
+ .github/workflows/build.yml                   | 10 ++--
+ .../preauth/pkinit/pkinit_crypto_openssl.c    | 54 ++++++++++++++-----
+ src/plugins/tls/k5tls/openssl.c               | 26 +++++++--
+ 3 files changed, 68 insertions(+), 22 deletions(-)
+
+diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+index d1fe18e5ab..aa969aa37c 100644
+--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+@@ -209,13 +209,20 @@ create_identifiers_from_stack(STACK_OF(X509) *sk,
+ #define EVP_MD_CTX_new EVP_MD_CTX_create
+ #define EVP_MD_CTX_free EVP_MD_CTX_destroy
+ #define ASN1_STRING_get0_data ASN1_STRING_data
++#define X509_STORE_CTX_set0_trusted_stack X509_STORE_CTX_trusted_stack
+ 
+ /*
+- * 1.1 adds DHX support, which uses the RFC 3279 DomainParameters encoding we
++ * 1.0.2 adds DHX support, which uses the RFC 3279 DomainParameters encoding we
+  * need for PKINIT.  For 1.0 we must use the original DH type when creating
+  * EVP_PKEY objects.
+  */
++#ifndef EVP_PKEY_DHX
+ #define EVP_PKEY_DHX EVP_PKEY_DH
++#endif
++
++/* Make X509_NAME_print_ex() accept a const name pointer by adding a cast. */
++#define X509_NAME_print_ex(a, b, c, d)          \
++    X509_NAME_print_ex(a, (X509_NAME *)b, c, d)
+ 
+ /* 1.1 makes many handle types opaque and adds accessors.  Add compatibility
+  * versions of the new accessors we use for pre-1.1. */
+@@ -295,6 +302,10 @@ compat_ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
+ #define EVP_PKEY_get_bits EVP_PKEY_bits
+ #define EVP_PKEY_get_base_id EVP_PKEY_base_id
+ 
++/* Make X509_dup() accept a const pointer by adding a cast. */
++#define X509_dup(a) X509_dup((X509 *)a)
++#define i2d_X509_NAME(a, b) i2d_X509_NAME((X509_NAME *)a, b)
++
+ /*
+  * Convert *dh to an EVP_PKEY object, taking ownership of *dh and setting it to
+  * NULL.  On error, return NULL and do not take ownership of or change *dh.
+@@ -318,6 +329,11 @@ dh_to_pkey(DH **dh)
+ }
+ #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
+ 
++#if OPENSSL_VERSION_NUMBER < 0x40000000L
++/* Make X509V3_EXT_d2i() accept a const pointer by adding a cast. */
++#define X509V3_EXT_d2i(a) X509V3_EXT_d2i((X509_EXTENSION *)a)
++#endif
++
+ /* Encode a bignum as an ASN.1 integer in DER. */
+ static int
+ encode_bn_der(const BIGNUM *bn, uint8_t **der_out, int *len_out)
+@@ -1134,6 +1150,13 @@ oerr_cert(krb5_context context, krb5_error_code code, X509_STORE_CTX *certctx,
+     return oerr(context, code, _("%s (depth %d): %s"), msg, depth, errstr);
+ }
+ 
++/* Convert an OpenSSL ASN.1 string value to krb5_data, without copying. */
++static inline krb5_data
++asn1string_to_data(ASN1_STRING *s)
++{
++    return make_data((char *)ASN1_STRING_get0_data(s), ASN1_STRING_length(s));
++}
++
+ krb5_error_code
+ pkinit_init_plg_crypto(krb5_context context,
+                        pkinit_plg_crypto_context *cryptoctx)
+@@ -1775,7 +1798,7 @@ cms_signeddata_create(krb5_context context,
+             goto cleanup;
+         X509_STORE_CTX_init(certctx, certstore, id_cryptoctx->my_cert,
+                             id_cryptoctx->intermediateCAs);
+-        X509_STORE_CTX_trusted_stack(certctx, id_cryptoctx->trustedCAs);
++        X509_STORE_CTX_set0_trusted_stack(certctx, id_cryptoctx->trustedCAs);
+         if (!X509_verify_cert(certctx)) {
+             retval = oerr_cert(context, 0, certctx,
+                                _("Failed to verify own certificate"));
+@@ -2002,7 +2025,7 @@ cms_signeddata_verify(krb5_context context,
+         unsigned char *d;
+         *is_signed = 0;
+         octets = CMS_get0_content(cms);
+-        if (!octets || ((*octets)->type != V_ASN1_OCTET_STRING)) {
++        if (!octets || (ASN1_STRING_type(*octets) != V_ASN1_OCTET_STRING)) {
+             retval = KRB5KDC_ERR_PREAUTH_FAILED;
+             krb5_set_error_message(context, retval,
+                                    _("Invalid pkinit packet: octet string "
+@@ -2058,7 +2081,8 @@ cms_signeddata_verify(krb5_context context,
+         /* We cannot use CMS_dataInit because there may be no digest */
+         octets = CMS_get0_content(cms);
+         if (octets)
+-            out = BIO_new_mem_buf((*octets)->data, (*octets)->length);
++            out = BIO_new_mem_buf(ASN1_STRING_get0_data(*octets),
++                                  ASN1_STRING_length(*octets));
+         if (out == NULL)
+             goto cleanup;
+     } else {
+@@ -2118,7 +2142,7 @@ cms_signeddata_verify(krb5_context context,
+ 
+         /* add trusted CAs certificates for cert verification */
+         if (idctx->trustedCAs != NULL)
+-            X509_STORE_CTX_trusted_stack(cert_ctx, idctx->trustedCAs);
++            X509_STORE_CTX_set0_trusted_stack(cert_ctx, idctx->trustedCAs);
+         else {
+             pkiDebug("unable to find any trusted CAs\n");
+             goto cleanup;
+@@ -2156,7 +2180,7 @@ cms_signeddata_verify(krb5_context context,
+         i = X509_verify_cert(cert_ctx);
+         if (i <= 0) {
+             int j = X509_STORE_CTX_get_error(cert_ctx);
+-            X509 *cert;
++            const X509 *cert;
+ 
+             cert = X509_STORE_CTX_get_current_cert(cert_ctx);
+             reqctx->received_cert = X509_dup(cert);
+@@ -2316,7 +2340,7 @@ crypto_retrieve_X509_sans(krb5_context context,
+     krb5_principal *princs = NULL;
+     char **upns = NULL;
+     unsigned char **dnss = NULL;
+-    X509_EXTENSION *ext = NULL;
++    const X509_EXTENSION *ext = NULL;
+     GENERAL_NAMES *ialt = NULL;
+     GENERAL_NAME *gen = NULL;
+ 
+@@ -2379,8 +2403,7 @@ crypto_retrieve_X509_sans(krb5_context context,
+         gen = sk_GENERAL_NAME_value(ialt, i);
+         switch (gen->type) {
+         case GEN_OTHERNAME:
+-            name.length = gen->d.otherName->value->value.sequence->length;
+-            name.data = (char *)gen->d.otherName->value->value.sequence->data;
++            name = asn1string_to_data(gen->d.otherName->value->value.sequence);
+             if (princs != NULL &&
+                 OBJ_cmp(plgctx->id_pkinit_san,
+                         gen->d.otherName->type_id) == 0) {
+@@ -2414,12 +2437,13 @@ crypto_retrieve_X509_sans(krb5_context context,
+         case GEN_DNS:
+             if (dnss != NULL) {
+                 /* Prevent abuse of embedded null characters. */
+-                if (memchr(gen->d.dNSName->data, '\0', gen->d.dNSName->length))
++                if (memchr(ASN1_STRING_get0_data(gen->d.dNSName), '\0',
++                           ASN1_STRING_length(gen->d.dNSName)))
+                     break;
+                 pkiDebug("%s: found dns name = %s\n", __FUNCTION__,
+-                         gen->d.dNSName->data);
++                         ASN1_STRING_get0_data(gen->d.dNSName));
+                 dnss[d] = (unsigned char *)
+-                    strdup((char *)gen->d.dNSName->data);
++                    strdup((char *)ASN1_STRING_get0_data(gen->d.dNSName));
+                 if (dnss[d] == NULL) {
+                     pkiDebug("%s: failed to duplicate dns name\n",
+                              __FUNCTION__);
+@@ -3094,8 +3118,10 @@ int
+ pkinit_openssl_init(void)
+ {
+     /* Initialize OpenSSL. */
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
+     ERR_load_crypto_strings();
+     OpenSSL_add_all_algorithms();
++#endif
+     return 0;
+ }
+ 
+@@ -4766,7 +4792,7 @@ crypto_retrieve_X509_key_usage(krb5_context context,
+ }
+ 
+ static krb5_error_code
+-rfc2253_name(X509_NAME *name, char **str_out)
++rfc2253_name(const X509_NAME *name, char **str_out)
+ {
+     BIO *b = NULL;
+     char *str;
+@@ -5227,7 +5253,7 @@ create_identifiers_from_stack(STACK_OF(X509) *sk,
+     int i = 0, sk_size = sk_X509_num(sk);
+     krb5_external_principal_identifier **krb5_cas = NULL;
+     X509 *x = NULL;
+-    X509_NAME *xn = NULL;
++    const X509_NAME *xn = NULL;
+     unsigned char *p = NULL;
+     int len = 0;
+     PKCS7_ISSUER_AND_SERIAL *is = NULL;
+diff --git a/src/plugins/tls/k5tls/openssl.c b/src/plugins/tls/k5tls/openssl.c
+index 42d72dc9ec..7763327b7a 100644
+--- a/src/plugins/tls/k5tls/openssl.c
++++ b/src/plugins/tls/k5tls/openssl.c
+@@ -38,6 +38,24 @@
+ #include <openssl/x509v3.h>
+ #include <dirent.h>
+ 
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
++/* Make X509_get_subject_name() accept a const pointer by adding a cast. */
++#define X509_get_subject_name(a) X509_get_subject_name((X509 *)a)
++
++/* OpenSSL 1.0 did not have TLS_client_method(); use the best alternative. */
++#define TLS_client_method() SSLv23_client_method()
++#endif
++
++#if OPENSSL_VERSION_NUMBER < 0x40000000L
++/*
++ * OpenSSL 4.0 constifies the result of X509_STORE_CTX_get_current_cert() and
++ * the input of X509_check_host() and X509_check_ip_asc().  For prior versions,
++ * make the latter two functions accept const pointers via a cast.
++ */
++#define X509_check_host(a, b, c, d, e) X509_check_host((X509 *)a, b, c, d, e)
++#define X509_check_ip_asc(a, b, c) X509_check_ip_asc((X509 *)a, b, c)
++#endif
++
+ struct k5_tls_handle_st {
+     SSL *ssl;
+     char *servername;
+@@ -51,9 +69,11 @@ MAKE_INIT_FUNCTION(init_openssl);
+ int
+ init_openssl(void)
+ {
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
+     SSL_library_init();
+     SSL_load_error_strings();
+     OpenSSL_add_all_algorithms();
++#endif
+     ex_context_id = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
+     ex_handle_id = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
+     return 0;
+@@ -72,7 +92,7 @@ flush_errors(krb5_context context)
+ }
+ 
+ static krb5_boolean
+-check_cert_name_or_ip(X509 *x, const char *expected_name)
++check_cert_name_or_ip(const X509 *x, const char *expected_name)
+ {
+     struct in_addr in;
+     struct in6_addr in6;
+@@ -89,7 +109,7 @@ check_cert_name_or_ip(X509 *x, const char *expected_name)
+ static int
+ verify_callback(int preverify_ok, X509_STORE_CTX *store_ctx)
+ {
+-    X509 *x;
++    const X509 *x;
+     SSL *ssl;
+     BIO *bio;
+     krb5_context context;
+@@ -246,7 +266,7 @@ setup(krb5_context context, SOCKET fd, const char *servername,
+         return KRB5_PLUGIN_OP_NOTSUPP;
+ 
+     /* Do general SSL library setup. */
+-    ctx = SSL_CTX_new(SSLv23_client_method());
++    ctx = SSL_CTX_new(TLS_client_method());
+     if (ctx == NULL)
+         goto error;
+ 
diff --git a/meta-oe/recipes-connectivity/krb5/krb5/0002-Remove-OpenSSL-1.0-support.patch b/meta-oe/recipes-connectivity/krb5/krb5/0002-Remove-OpenSSL-1.0-support.patch
new file mode 100644
index 0000000000..b208c96e54
--- /dev/null
+++ b/meta-oe/recipes-connectivity/krb5/krb5/0002-Remove-OpenSSL-1.0-support.patch
@@ -0,0 +1,627 @@ 
+From 736397a909005913b09c1d84a32255de71aadeca Mon Sep 17 00:00:00 2001
+From: Greg Hudson <ghudson@mit.edu>
+Date: Tue, 10 Mar 2026 23:06:59 -0400
+Subject: [PATCH] Remove OpenSSL 1.0 support
+
+Upstream-Status: Backport [https://github.com/krb5/krb5/commit/f8a47bf037af]
+
+Note: Context adjusted for krb5 1.22.2 (one hunk in
+pkinit_crypto_openssl.c had offset due to earlier patches).
+doc/mitK5features.rst hunk dropped (documentation only, outside src/).
+
+Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech>
+---
+ src/configure.ac                              |   4 +-
+ .../crypto/openssl/hash_provider/hash_evp.c   |   7 -
+ src/lib/crypto/openssl/hmac.c                 |  27 --
+ src/lib/crypto/openssl/sha256.c               |   7 -
+ .../preauth/pkinit/pkinit_crypto_openssl.c    | 372 +-----------------
+ src/plugins/preauth/spake/openssl.c           |   7 -
+ src/plugins/tls/k5tls/openssl.c               |  13 -
+ 7 files changed, 4 insertions(+), 433 deletions(-)
+
+diff --git a/src/configure.ac b/src/configure.ac
+index 4325fae..9074a9f 100644
+--- a/src/configure.ac
++++ b/src/configure.ac
+@@ -1141,8 +1141,8 @@ enable_pkinit=try)
+ if test "$enable_pkinit" = yes || test "$enable_pkinit" = try; then
+   AC_CACHE_CHECK(for a recent enough OpenSSL, k5_cv_openssl_version_okay,
+ [AC_COMPILE_IFELSE([AC_LANG_SOURCE([#include <openssl/opensslv.h>
+-#if OPENSSL_VERSION_NUMBER < 0x10000000L
+-# error openssl is too old, need 1.0.0
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
++# error openssl is too old, need 1.1.0
+ #endif
+ int i = 1;
+ ])], k5_cv_openssl_version_okay=yes, k5_cv_openssl_version_okay=no)])
+diff --git a/src/lib/crypto/openssl/hash_provider/hash_evp.c b/src/lib/crypto/openssl/hash_provider/hash_evp.c
+index f2fbffd..2269daa 100644
+--- a/src/lib/crypto/openssl/hash_provider/hash_evp.c
++++ b/src/lib/crypto/openssl/hash_provider/hash_evp.c
+@@ -37,13 +37,6 @@
+ 
+ #include <openssl/evp.h>
+ 
+-/* 1.1 standardizes constructor and destructor names, renaming
+- * EVP_MD_CTX_create and EVP_MD_CTX_destroy. */
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+-#define EVP_MD_CTX_new EVP_MD_CTX_create
+-#define EVP_MD_CTX_free EVP_MD_CTX_destroy
+-#endif
+-
+ static krb5_error_code
+ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
+          krb5_data *output)
+diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c
+index 799d700..6e91017 100644
+--- a/src/lib/crypto/openssl/hmac.c
++++ b/src/lib/crypto/openssl/hmac.c
+@@ -63,33 +63,6 @@
+ #include <openssl/hmac.h>
+ #endif
+ 
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+-
+-/* OpenSSL 1.1 makes HMAC_CTX opaque, while 1.0 does not have pointer
+- * constructors or destructors. */
+-
+-#define HMAC_CTX_new compat_hmac_ctx_new
+-static HMAC_CTX *
+-compat_hmac_ctx_new(void)
+-{
+-    HMAC_CTX *ctx;
+-
+-    ctx = calloc(1, sizeof(*ctx));
+-    if (ctx != NULL)
+-        HMAC_CTX_init(ctx);
+-    return ctx;
+-}
+-
+-#define HMAC_CTX_free compat_hmac_ctx_free
+-static void
+-compat_hmac_ctx_free(HMAC_CTX *ctx)
+-{
+-    HMAC_CTX_cleanup(ctx);
+-    free(ctx);
+-}
+-
+-#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+-
+ /*
+  * the HMAC transform looks like:
+  *
+diff --git a/src/lib/crypto/openssl/sha256.c b/src/lib/crypto/openssl/sha256.c
+index 855ebd7..6f2c5d9 100644
+--- a/src/lib/crypto/openssl/sha256.c
++++ b/src/lib/crypto/openssl/sha256.c
+@@ -36,13 +36,6 @@
+ 
+ #include <openssl/evp.h>
+ 
+-/* 1.1 standardizes constructor and destructor names, renaming
+- * EVP_MD_CTX_create and EVP_MD_CTX_destroy. */
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+-#define EVP_MD_CTX_new EVP_MD_CTX_create
+-#define EVP_MD_CTX_free EVP_MD_CTX_destroy
+-#endif
+-
+ krb5_error_code
+ k5_sha256(const krb5_data *in, size_t n, uint8_t out[K5_SHA256_HASHLEN])
+ {
+diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+index e70106f..2dd34dc 100644
+--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+@@ -201,100 +201,9 @@ static krb5_error_code
+ create_identifiers_from_stack(STACK_OF(X509) *sk,
+                               krb5_external_principal_identifier *** ids);
+ 
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+-
+-/* 1.1 standardizes constructor and destructor names, renaming
+- * EVP_MD_CTX_{create,destroy} and deprecating ASN1_STRING_data. */
+-
+-#define EVP_MD_CTX_new EVP_MD_CTX_create
+-#define EVP_MD_CTX_free EVP_MD_CTX_destroy
+-#define ASN1_STRING_get0_data ASN1_STRING_data
+-#define X509_STORE_CTX_set0_trusted_stack X509_STORE_CTX_trusted_stack
+-
+-/*
+- * 1.0.2 adds DHX support, which uses the RFC 3279 DomainParameters encoding we
+- * need for PKINIT.  For 1.0 we must use the original DH type when creating
+- * EVP_PKEY objects.
+- */
+-#ifndef EVP_PKEY_DHX
+-#define EVP_PKEY_DHX EVP_PKEY_DH
+-#endif
+-
+-/* Make X509_NAME_print_ex() accept a const name pointer by adding a cast. */
+-#define X509_NAME_print_ex(a, b, c, d)          \
+-    X509_NAME_print_ex(a, (X509_NAME *)b, c, d)
+-
+-/* 1.1 makes many handle types opaque and adds accessors.  Add compatibility
+- * versions of the new accessors we use for pre-1.1. */
+-
+-#define OBJ_get0_data(o) ((o)->data)
+-#define OBJ_length(o) ((o)->length)
+-
+-#define DH_set0_key compat_dh_set0_key
+-static int
+-compat_dh_set0_key(DH *dh, BIGNUM *pub, BIGNUM *priv)
+-{
+-    if (pub != NULL) {
+-        BN_clear_free(dh->pub_key);
+-        dh->pub_key = pub;
+-    }
+-    if (priv != NULL) {
+-        BN_clear_free(dh->priv_key);
+-        dh->priv_key = priv;
+-    }
+-    return 1;
+-}
+-
+-#define DH_get0_key compat_dh_get0_key
+-static void compat_dh_get0_key(const DH *dh, const BIGNUM **pub,
+-                               const BIGNUM **priv)
+-{
+-    if (pub != NULL)
+-        *pub = dh->pub_key;
+-    if (priv != NULL)
+-        *priv = dh->priv_key;
+-}
+-
+-#define EVP_PKEY_get0_DH compat_get0_DH
+-static DH *
+-compat_get0_DH(const EVP_PKEY *pkey)
+-{
+-    if (pkey->type != EVP_PKEY_DH)
+-        return NULL;
+-    return pkey->pkey.dh;
+-
+-}
+-
+-#define EVP_PKEY_get0_EC_KEY compat_get0_EC
+-static EC_KEY *
+-compat_get0_EC(const EVP_PKEY *pkey)
+-{
+-    if (pkey->type != EVP_PKEY_EC)
+-        return NULL;
+-    return pkey->pkey.ec;
+-}
+-
+-#define ECDSA_SIG_set0 compat_ECDSA_SIG_set0
+-static int
+-compat_ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
+-{
+-    sig->r = r;
+-    sig->s = s;
+-    return 1;
+-}
+-
+-/* Return true if the cert c includes a key usage which doesn't include u.
+- * Define using direct member access for pre-1.1. */
+-#define ku_reject(c, u)                                                 \
+-    (((c)->ex_flags & EXFLAG_KUSAGE) && !((c)->ex_kusage & (u)))
+-
+-#else /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
+-
+ /* Return true if the cert x includes a key usage which doesn't include u. */
+ #define ku_reject(c, u) (!(X509_get_key_usage(c) & (u)))
+ 
+-#endif
+-
+ #if OPENSSL_VERSION_NUMBER < 0x30000000L
+ /* OpenSSL 3.0 changes several preferred function names. */
+ #define EVP_PKEY_parameters_eq EVP_PKEY_cmp_parameters
+@@ -371,8 +280,6 @@ decode_bn_der(const uint8_t *der, size_t len)
+     return bn;
+ }
+ 
+-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+-
+ #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ static EVP_PKEY *
+ decode_params(const krb5_data *params_der, const char *type)
+@@ -442,195 +349,6 @@ decode_spki(const krb5_data *spki)
+     return d2i_PUBKEY(NULL, &inptr, spki->length);
+ }
+ 
+-#else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+-
+-/*
+- * OpenSSL 1.0 has no DHX support, so we need a custom decoder for RFC 3279
+- * DomainParameters, and we need to use X509_PUBKEY values to marshal
+- * SubjectPublicKeyInfo.
+- */
+-
+-typedef struct {
+-    ASN1_BIT_STRING *seed;
+-    BIGNUM *counter;
+-} int_dhvparams;
+-
+-typedef struct {
+-    BIGNUM *p;
+-    BIGNUM *q;
+-    BIGNUM *g;
+-    BIGNUM *j;
+-    int_dhvparams *vparams;
+-} int_dhxparams;
+-
+-ASN1_SEQUENCE(int_dhvparams) = {
+-    ASN1_SIMPLE(int_dhvparams, seed, ASN1_BIT_STRING),
+-    ASN1_SIMPLE(int_dhvparams, counter, BIGNUM)
+-} ASN1_SEQUENCE_END(int_dhvparams);
+-
+-ASN1_SEQUENCE(int_dhxparams) = {
+-    ASN1_SIMPLE(int_dhxparams, p, BIGNUM),
+-    ASN1_SIMPLE(int_dhxparams, g, BIGNUM),
+-    ASN1_SIMPLE(int_dhxparams, q, BIGNUM),
+-    ASN1_OPT(int_dhxparams, j, BIGNUM),
+-    ASN1_OPT(int_dhxparams, vparams, int_dhvparams)
+-} ASN1_SEQUENCE_END(int_dhxparams);
+-
+-static EVP_PKEY *
+-decode_dh_params(const krb5_data *params_der)
+-{
+-    int_dhxparams *params;
+-    DH *dh;
+-    EVP_PKEY *pkey;
+-    const uint8_t *p;
+-
+-    dh = DH_new();
+-    if (dh == NULL)
+-        return NULL;
+-
+-    p = (uint8_t *)params_der->data;
+-    params = (int_dhxparams *)ASN1_item_d2i(NULL, &p, params_der->length,
+-                                            ASN1_ITEM_rptr(int_dhxparams));
+-    if (params == NULL) {
+-        DH_free(dh);
+-        return NULL;
+-    }
+-
+-    /* Steal p, q, and g from dhparams for dh.  Ignore j and vparams. */
+-    dh->p = params->p;
+-    dh->q = params->q;
+-    dh->g = params->g;
+-    params->p = params->q = params->g = NULL;
+-    ASN1_item_free((ASN1_VALUE *)params, ASN1_ITEM_rptr(int_dhxparams));
+-    pkey = dh_to_pkey(&dh);
+-    DH_free(dh);
+-    return pkey;
+-}
+-
+-static krb5_error_code
+-encode_spki(EVP_PKEY *pkey, krb5_data *spki_out)
+-{
+-    krb5_error_code ret = ENOMEM;
+-    const DH *dh;
+-    uint8_t *param_der = NULL, *pubkey_der = NULL, *outptr;
+-    int param_der_len, pubkey_der_len, len;
+-    X509_PUBKEY pubkey;
+-    int_dhxparams dhxparams;
+-    X509_ALGOR algor;
+-    ASN1_OBJECT algorithm;
+-    ASN1_TYPE parameter;
+-    ASN1_STRING param_str, pubkey_str;
+-
+-    if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) {
+-        /* Only DH keys require special encoding. */
+-        len = i2d_PUBKEY(pkey, NULL);
+-        ret = alloc_data(spki_out, len);
+-        if (ret)
+-            goto cleanup;
+-        outptr = (uint8_t *)spki_out->data;
+-        (void)i2d_PUBKEY(pkey, &outptr);
+-        return 0;
+-    }
+-
+-    dh = EVP_PKEY_get0_DH(pkey);
+-    if (dh == NULL)
+-        goto cleanup;
+-
+-    dhxparams.p = dh->p;
+-    dhxparams.q = dh->q;
+-    dhxparams.g = dh->g;
+-    dhxparams.j = NULL;
+-    dhxparams.vparams = NULL;
+-    param_der_len = ASN1_item_i2d((ASN1_VALUE *)&dhxparams, &param_der,
+-                                  ASN1_ITEM_rptr(int_dhxparams));
+-    if (param_der_len < 0)
+-        goto cleanup;
+-    param_str.length = param_der_len;
+-    param_str.type = V_ASN1_SEQUENCE;
+-    param_str.data = param_der;
+-    param_str.flags = 0;
+-    parameter.type = V_ASN1_SEQUENCE;
+-    parameter.value.sequence = &param_str;
+-
+-    memset(&algorithm, 0, sizeof(algorithm));
+-    algorithm.data = (uint8_t *)dh_oid.data;
+-    algorithm.length = dh_oid.length;
+-
+-    algor.algorithm = &algorithm;
+-    algor.parameter = &parameter;
+-
+-    if (!encode_bn_der(dh->pub_key, &pubkey_der, &pubkey_der_len))
+-        goto cleanup;
+-    pubkey_str.length = pubkey_der_len;
+-    pubkey_str.type = V_ASN1_BIT_STRING;
+-    pubkey_str.data = pubkey_der;
+-    pubkey_str.flags = ASN1_STRING_FLAG_BITS_LEFT;
+-
+-    pubkey.algor = &algor;
+-    pubkey.public_key = &pubkey_str;
+-    len = i2d_X509_PUBKEY(&pubkey, NULL);
+-    if (len < 0)
+-        goto cleanup;
+-    ret = alloc_data(spki_out, len);
+-    if (ret)
+-        goto cleanup;
+-    outptr = (uint8_t *)spki_out->data;
+-    i2d_X509_PUBKEY(&pubkey, &outptr);
+-
+-cleanup:
+-    OPENSSL_free(param_der);
+-    free(pubkey_der);
+-    return ret;
+-}
+-
+-static EVP_PKEY *
+-decode_spki(const krb5_data *spki)
+-{
+-    X509_PUBKEY *pubkey = NULL;
+-    const uint8_t *inptr;
+-    DH *dh;
+-    EVP_PKEY *pkey = NULL, *pkey_ret = NULL;
+-    const ASN1_STRING *params;
+-    const ASN1_BIT_STRING *public_key;
+-    krb5_data d;
+-
+-    inptr = (uint8_t *)spki->data;
+-    pubkey = d2i_X509_PUBKEY(NULL, &inptr, spki->length);
+-    if (pubkey == NULL)
+-        goto cleanup;
+-
+-    if (OBJ_cmp(pubkey->algor->algorithm, OBJ_nid2obj(NID_dhKeyAgreement))) {
+-        /* This is not a DH key, so we don't need special decoding. */
+-        X509_PUBKEY_free(pubkey);
+-        inptr = (uint8_t *)spki->data;
+-        return d2i_PUBKEY(NULL, &inptr, spki->length);
+-    }
+-
+-    if (pubkey->algor->parameter->type != V_ASN1_SEQUENCE)
+-        goto cleanup;
+-    params = pubkey->algor->parameter->value.sequence;
+-    d = make_data(params->data, params->length);
+-    pkey = decode_dh_params(&d);
+-    if (pkey == NULL)
+-        goto cleanup;
+-    dh = EVP_PKEY_get0_DH(pkey);
+-    if (dh == NULL)
+-        goto cleanup;
+-    public_key = pubkey->public_key;
+-    dh->pub_key = decode_bn_der(public_key->data, public_key->length);
+-    if (dh->pub_key == NULL)
+-        goto cleanup;
+-
+-    pkey_ret = pkey;
+-    pkey = NULL;
+-
+-cleanup:
+-    X509_PUBKEY_free(pubkey);
+-    EVP_PKEY_free(pkey);
+-    return pkey_ret;
+-}
+-
+-#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+ 
+ #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ 
+@@ -673,7 +391,7 @@ set_padded_derivation(EVP_PKEY_CTX *ctx)
+ {
+     EVP_PKEY_CTX_set_dh_pad(ctx, 1);
+ }
+-#elif OPENSSL_VERSION_NUMBER >= 0x10100000L
++#else
+ static void
+ set_padded_derivation(EVP_PKEY_CTX *ctx)
+ {
+@@ -681,12 +399,6 @@ set_padded_derivation(EVP_PKEY_CTX *ctx)
+     EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
+                       EVP_PKEY_CTRL_DH_PAD, 1, NULL);
+ }
+-#else
+-static void
+-set_padded_derivation(EVP_PKEY_CTX *ctx)
+-{
+-    /* There's no support for padded derivation in 1.0. */
+-}
+ #endif
+ 
+ static int
+@@ -809,29 +521,6 @@ dh_pubkey_der(EVP_PKEY *pkey, uint8_t **pubkey_out, unsigned int *len_out)
+ }
+ #endif
+ 
+-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+-/* OpenSSL 1.1 and later will copy the q parameter when generating keys. */
+-static int
+-copy_q_openssl10(EVP_PKEY *src, EVP_PKEY *dest)
+-{
+-    return 1;
+-}
+-#else
+-/* OpenSSL 1.0 won't copy the q parameter, so we have to do it. */
+-static int
+-copy_q_openssl10(EVP_PKEY *src, EVP_PKEY *dest)
+-{
+-    DH *dhsrc = EVP_PKEY_get0_DH(src), *dhdest = EVP_PKEY_get0_DH(dest);
+-
+-    if (dhsrc == NULL || dhsrc->q == NULL || dhdest == NULL)
+-        return 0;
+-    if (dhdest->q != NULL)
+-        return 1;
+-    dhdest->q = BN_dup(dhsrc->q);
+-    return dhdest->q != NULL;
+-}
+-#endif
+-
+ static EVP_PKEY *
+ generate_dh_pkey(EVP_PKEY *params)
+ {
+@@ -845,11 +534,6 @@ generate_dh_pkey(EVP_PKEY *params)
+         goto cleanup;
+     if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
+         goto cleanup;
+-    if (EVP_PKEY_get_base_id(pkey) == EVP_PKEY_DH &&
+-        !copy_q_openssl10(params, pkey)) {
+-        EVP_PKEY_free(pkey);
+-        pkey = NULL;
+-    }
+ 
+ cleanup:
+     EVP_PKEY_CTX_free(ctx);
+@@ -900,33 +584,6 @@ cleanup:
+ 
+ #else /* OPENSSL_VERSION_NUMBER < 0x30000000L */
+ 
+-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+-static DH *
+-dup_dh_params(DH *src)
+-{
+-    return DHparams_dup(src);
+-}
+-#else
+-/* DHparams_dup() won't copy q in OpenSSL 1.0. */
+-static DH *
+-dup_dh_params(DH *src)
+-{
+-    DH *dh;
+-
+-    dh = DH_new();
+-    if (dh == NULL)
+-        return NULL;
+-    dh->p = BN_dup(src->p);
+-    dh->q = BN_dup(src->q);
+-    dh->g = BN_dup(src->g);
+-    if (dh->p == NULL || dh->q == NULL || dh->g == NULL) {
+-        DH_free(dh);
+-        return NULL;
+-    }
+-    return dh;
+-}
+-#endif
+-
+ static EVP_PKEY *
+ compose_dh_pkey(EVP_PKEY *params, const uint8_t *pubkey_der, size_t der_len)
+ {
+@@ -966,7 +623,7 @@ compose_dh_pkey(EVP_PKEY *params, const uint8_t *pubkey_der, size_t der_len)
+         dhparams = EVP_PKEY_get0_DH(params);
+         if (dhparams == NULL)
+             goto cleanup;
+-        dh = dup_dh_params(dhparams);
++        dh = DHparams_dup(dhparams);
+         if (dh == NULL)
+             goto cleanup;
+         if (!DH_set0_key(dh, pubkey_bn, NULL))
+@@ -1083,8 +740,6 @@ static struct pkcs11_errstrings {
+ };
+ #endif
+ 
+-MAKE_INIT_FUNCTION(pkinit_openssl_init);
+-
+ static krb5_error_code oerr(krb5_context context, krb5_error_code code,
+                             const char *fmt, ...)
+ #if !defined(__cplusplus) && (__GNUC__ > 2)
+@@ -1164,8 +819,6 @@ pkinit_init_plg_crypto(krb5_context context,
+     krb5_error_code retval = ENOMEM;
+     pkinit_plg_crypto_context ctx = NULL;
+ 
+-    (void)CALL_INIT_FUNCTION(pkinit_openssl_init);
+-
+     ctx = malloc(sizeof(*ctx));
+     if (ctx == NULL)
+         goto out;
+@@ -3114,17 +2767,6 @@ cleanup:
+     return retval;
+ }
+ 
+-int
+-pkinit_openssl_init(void)
+-{
+-    /* Initialize OpenSSL. */
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+-    ERR_load_crypto_strings();
+-    OpenSSL_add_all_algorithms();
+-#endif
+-    return 0;
+-}
+-
+ static krb5_error_code
+ pkinit_create_sequence_of_principal_identifiers(
+     krb5_context context,
+@@ -5834,13 +5476,3 @@ crypto_verify_checksums(krb5_context context, krb5_data *body,
+ 
+     return 0;
+ }
+-
+-#ifdef _WIN32
+-BOOL WINAPI
+-DllMain(HANDLE hModule, DWORD fdwReason, LPVOID lpvReserved)
+-{
+-    if (fdwReason == DLL_PROCESS_ATTACH)
+-        pkinit_openssl_init__auxinit();
+-    return TRUE;
+-}
+-#endif /* _WIN32 */
+diff --git a/src/plugins/preauth/spake/openssl.c b/src/plugins/preauth/spake/openssl.c
+index f2e4b53..fbaa65e 100644
+--- a/src/plugins/preauth/spake/openssl.c
++++ b/src/plugins/preauth/spake/openssl.c
+@@ -41,13 +41,6 @@
+ #include <openssl/obj_mac.h>
+ #include <openssl/evp.h>
+ 
+-/* OpenSSL 1.1 standardizes constructor and destructor names, renaming
+- * EVP_MD_CTX_create and EVP_MD_CTX_destroy. */
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+-#define EVP_MD_CTX_new EVP_MD_CTX_create
+-#define EVP_MD_CTX_free EVP_MD_CTX_destroy
+-#endif
+-
+ struct groupdata_st {
+     const groupdef *gdef;
+     EC_GROUP *group;
+diff --git a/src/plugins/tls/k5tls/openssl.c b/src/plugins/tls/k5tls/openssl.c
+index cc8fc70..bbfa37f 100644
+--- a/src/plugins/tls/k5tls/openssl.c
++++ b/src/plugins/tls/k5tls/openssl.c
+@@ -38,14 +38,6 @@
+ #include <openssl/x509v3.h>
+ #include <dirent.h>
+ 
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+-/* Make X509_get_subject_name() accept a const pointer by adding a cast. */
+-#define X509_get_subject_name(a) X509_get_subject_name((X509 *)a)
+-
+-/* OpenSSL 1.0 did not have TLS_client_method(); use the best alternative. */
+-#define TLS_client_method() SSLv23_client_method()
+-#endif
+-
+ #if OPENSSL_VERSION_NUMBER < 0x40000000L
+ /*
+  * OpenSSL 4.0 constifies the result of X509_STORE_CTX_get_current_cert() and
+@@ -69,11 +61,6 @@ MAKE_INIT_FUNCTION(init_openssl);
+ int
+ init_openssl(void)
+ {
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+-    SSL_library_init();
+-    SSL_load_error_strings();
+-    OpenSSL_add_all_algorithms();
+-#endif
+     ex_context_id = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
+     ex_handle_id = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
+     return 0;
diff --git a/meta-oe/recipes-connectivity/krb5/krb5/0003-k5tls-fix-remaining-const-qualifiers-for-OpenSSL-4.0.patch b/meta-oe/recipes-connectivity/krb5/krb5/0003-k5tls-fix-remaining-const-qualifiers-for-OpenSSL-4.0.patch
new file mode 100644
index 0000000000..261c8387b5
--- /dev/null
+++ b/meta-oe/recipes-connectivity/krb5/krb5/0003-k5tls-fix-remaining-const-qualifiers-for-OpenSSL-4.0.patch
@@ -0,0 +1,67 @@ 
+From 29a6ab9be8a5af0a683eb0e89ce9b094b74ae8cf Mon Sep 17 00:00:00 2001
+From: Jaipaul Cheernam <jaipaul.cheernam@est.tech>
+Date: Wed, 26 Aug 2026 11:30:58 +0000
+Subject: [PATCH] k5tls: fix remaining const qualifiers for OpenSSL 4.0
+
+OpenSSL 4.0 returns const pointers from X509_get_subject_name(),
+X509_get_ext(), and X509_STORE_CTX_get_current_cert(). Update
+function signatures and local variables to accept const pointers.
+
+Upstream-Status: Inappropriate [functions removed on trunk, fix only needed for 1.22.x]
+
+Note: Upstream fixed this by removing OpenSSL 1.0 support entirely
+(commit f8a47bf037af), but 1.22.2 still has code paths that need
+these additional const qualifiers.
+
+Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech>
+---
+ plugins/tls/k5tls/openssl.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/src/plugins/tls/k5tls/openssl.c b/src/plugins/tls/k5tls/openssl.c
+index bbfa37f..6efe613 100644
+--- a/src/plugins/tls/k5tls/openssl.c
++++ b/src/plugins/tls/k5tls/openssl.c
+@@ -146,10 +146,10 @@ domain_match(const char *presented, size_t plen, const char *expected)
+ 
+ /* Fetch the list of subjectAltNames from a certificate. */
+ static GENERAL_NAMES *
+-get_cert_sans(X509 *x)
++get_cert_sans(const X509 *x)
+ {
+     int ext;
+-    X509_EXTENSION *san_ext;
++    const X509_EXTENSION *san_ext;
+ 
+     ext = X509_get_ext_by_NID(x, NID_subject_alt_name, -1);
+     if (ext < 0)
+@@ -163,9 +163,9 @@ get_cert_sans(X509 *x)
+ /* Fetch a CN value from the subjct name field, returning its length, or -1 if
+  * there is no subject name or it contains no CN value. */
+ static int
+-get_cert_cn(X509 *x, char *buf, size_t bufsize)
++get_cert_cn(const X509 *x, char *buf, size_t bufsize)
+ {
+-    X509_NAME *name;
++    const X509_NAME *name;
+ 
+     name = X509_get_subject_name(x);
+     if (name == NULL)
+@@ -175,7 +175,7 @@ get_cert_cn(X509 *x, char *buf, size_t bufsize)
+ 
+ /* Return true if text matches any of the addresses we can recover from x. */
+ static krb5_boolean
+-check_cert_address(X509 *x, const char *text)
++check_cert_address(const X509 *x, const char *text)
+ {
+     char buf[1024];
+     GENERAL_NAMES *sans;
+@@ -234,7 +234,7 @@ check_cert_address(X509 *x, const char *text)
+ 
+ /* Return true if expected matches any of the names we can recover from x. */
+ static krb5_boolean
+-check_cert_servername(X509 *x, const char *expected)
++check_cert_servername(const X509 *x, const char *expected)
+ {
+     char buf[1024];
+     GENERAL_NAMES *sans;
diff --git a/meta-oe/recipes-connectivity/krb5/krb5_1.22.2.bb b/meta-oe/recipes-connectivity/krb5/krb5_1.22.2.bb
index 89e5502847..7666ec5671 100644
--- a/meta-oe/recipes-connectivity/krb5/krb5_1.22.2.bb
+++ b/meta-oe/recipes-connectivity/krb5/krb5_1.22.2.bb
@@ -24,6 +24,9 @@  SRC_URI = "http://web.mit.edu/kerberos/dist/${BPN}/${SHRT_VER}/${BP}.tar.gz \
            file://fix-strchr-conformance-to-C23.patch;striplevel=2 \
            file://crosscompile_nm.patch \
            file://0001-configure.ac-replace-K5_AC_INIT-with-explicit-AC_INI.patch;striplevel=2 \
+           file://0001-Improve-future-OpenSSL-compatibility.patch;striplevel=2 \
+           file://0002-Remove-OpenSSL-1.0-support.patch;striplevel=2 \
+           file://0003-k5tls-fix-remaining-const-qualifiers-for-OpenSSL-4.0.patch;striplevel=2 \
            file://etc/init.d/krb5-kdc \
            file://etc/init.d/krb5-admin-server \
            file://etc/default/krb5-kdc \