control: tags -1 + patch
control: forwarded -1 https://github.com/aws/s2n-tls/pull/6074

Attached a patch and forwarded.

Sebastian
>From 997cc626e36fca1cad2f2638f46bc88c47c10958 Mon Sep 17 00:00:00 2001
From: Sebastian Andrzej Siewior <[email protected]>
Date: Sat, 29 Aug 2026 17:29:26 +0200
Subject: [PATCH] s2n: Make it OpenSSL 4.0 compatible

Make s2n compatible with OpenSSL 4.0 by:
- ASN1_STRING's members ->data and ->length can no longer be accessed
  directly instead ASN1_STRING_get0_data() and ASN1_STRING_length() must
  be used. These two were already introduced in 1.0.1.
- ASN1_STRING_data() was deprecated in 1.1.0 and removed in 4.0. It is
  replaced by ASN1_STRING_get0_data(). The difference is that
  ASN1_STRING_get0_data()'s return value is const while
  ASN1_STRING_data() wasn't.
- Collecting bonus points for make return variables const to avoid
  compiler warnings at runtime.

Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
---
 crt/s2n/crypto/s2n_certificate.c | 38 +++++++++++++++++---------------
 crt/s2n/tls/s2n_x509_validator.c | 14 ++++++------
 2 files changed, 27 insertions(+), 25 deletions(-)

diff --git a/crt/s2n/crypto/s2n_certificate.c b/crt/s2n/crypto/s2n_certificate.c
index 0b9dfefbd778..1ebbf1c40589 100644
--- a/crt/s2n/crypto/s2n_certificate.c
+++ b/crt/s2n/crypto/s2n_certificate.c
@@ -232,8 +232,8 @@ int s2n_cert_chain_and_key_load_sans(struct s2n_cert_chain_and_key *chain_and_ke
 
         if (san_name->type == GEN_DNS) {
             /* Decoding isn't necessary here since a DNS SAN name is ASCII(type V_ASN1_IA5STRING) */
-            unsigned char *san_str = san_name->d.dNSName->data;
-            const size_t san_str_len = san_name->d.dNSName->length;
+            const unsigned char *san_str = ASN1_STRING_get0_data(san_name->d.dNSName);
+            const size_t san_str_len = ASN1_STRING_length(san_name->d.dNSName);
             struct s2n_blob *san_blob = NULL;
             POSIX_GUARD_RESULT(s2n_array_pushback(chain_and_key->san_names, (void **) &san_blob));
             if (!san_blob) {
@@ -270,19 +270,19 @@ int s2n_cert_chain_and_key_load_cns(struct s2n_cert_chain_and_key *chain_and_key
     POSIX_ENSURE_REF(chain_and_key->cn_names);
     POSIX_ENSURE_REF(x509_cert);
 
-    X509_NAME *subject = X509_get_subject_name(x509_cert);
+    const X509_NAME *subject = X509_get_subject_name(x509_cert);
     if (!subject) {
         return 0;
     }
 
     int lastpos = -1;
     while ((lastpos = X509_NAME_get_index_by_NID(subject, NID_commonName, lastpos)) >= 0) {
-        X509_NAME_ENTRY *name_entry = X509_NAME_get_entry(subject, lastpos);
+        const X509_NAME_ENTRY *name_entry = X509_NAME_get_entry(subject, lastpos);
         if (!name_entry) {
             continue;
         }
 
-        ASN1_STRING *asn1_str = X509_NAME_ENTRY_get_data(name_entry);
+        const ASN1_STRING *asn1_str = X509_NAME_ENTRY_get_data(name_entry);
         if (!asn1_str) {
             continue;
         }
@@ -726,11 +726,12 @@ static int s2n_utf8_string_from_extension_data(const uint8_t *extension_data, ui
     POSIX_ENSURE_GTE(len, 0);
     if (out_data != NULL) {
         POSIX_ENSURE((int64_t) *out_len >= (int64_t) len, S2N_ERR_INSUFFICIENT_MEM_SIZE);
-        /* ASN1_STRING_data() returns an internal pointer to the data.
-        * Since this is an internal pointer it should not be freed or modified in any way.
-        * Ref: https://www.openssl.org/docs/man1.0.2/man3/ASN1_STRING_data.html.
-        */
-        unsigned char *internal_data = ASN1_STRING_data(asn1_str);
+	/* ASN1_STRING_get0_data(x) returns an internal pointer to the data of
+	 * x. Since this is an internal pointer it should not be freed or
+	 * modified in any way.
+	 * Ref: https://docs.openssl.org/master/man3/ASN1_STRING_length/
+	 */
+        const unsigned char *internal_data = ASN1_STRING_get0_data(asn1_str);
         POSIX_ENSURE_REF(internal_data);
         POSIX_CHECKED_MEMCPY(out_data, internal_data, len);
     }
@@ -793,7 +794,7 @@ static int s2n_parse_x509_extension(struct s2n_cert *cert, const uint8_t *oid,
     POSIX_ENSURE_REF(asn1_obj_in);
 
     for (size_t loc = 0; loc < ext_count; loc++) {
-        ASN1_OCTET_STRING *asn1_str = NULL;
+        const ASN1_OCTET_STRING *asn1_str = NULL;
         bool match_found = false;
 
         /* Retrieve the x509 extension at location loc.
@@ -802,7 +803,7 @@ static int s2n_parse_x509_extension(struct s2n_cert *cert, const uint8_t *oid,
          * The returned extension is an internal pointer which must not be freed up by the application.
          * Ref: https://www.openssl.org/docs/man1.1.0/man3/X509_get_ext.html.
          */
-        X509_EXTENSION *x509_ext = X509_get_ext(x509_cert, loc);
+        const X509_EXTENSION *x509_ext = X509_get_ext(x509_cert, loc);
         POSIX_ENSURE_REF(x509_ext);
 
         /* Retrieve the extension object/OID/extnId.
@@ -810,7 +811,7 @@ static int s2n_parse_x509_extension(struct s2n_cert *cert, const uint8_t *oid,
          * The returned pointer is an internal value which must not be freed up.
          * Ref: https://www.openssl.org/docs/man1.1.0/man3/X509_EXTENSION_get_object.html.
          */
-        ASN1_OBJECT *asn1_obj = X509_EXTENSION_get_object(x509_ext);
+        const ASN1_OBJECT *asn1_obj = X509_EXTENSION_get_object(x509_ext);
         POSIX_ENSURE_REF(asn1_obj);
 
         /* OBJ_cmp() compares two ASN1_OBJECT objects. If the two are identical 0 is returned.
@@ -833,11 +834,12 @@ static int s2n_parse_x509_extension(struct s2n_cert *cert, const uint8_t *oid,
             if (ext_value != NULL) {
                 POSIX_ENSURE_GTE(len, 0);
                 POSIX_ENSURE(*ext_value_len >= (uint32_t) len, S2N_ERR_INSUFFICIENT_MEM_SIZE);
-                /* ASN1_STRING_data() returns an internal pointer to the data.
-                 * Since this is an internal pointer it should not be freed or modified in any way.
-                 * Ref: https://www.openssl.org/docs/man1.0.2/man3/ASN1_STRING_data.html.
-                 */
-                unsigned char *internal_data = ASN1_STRING_data(asn1_str);
+		/* ASN1_STRING_get0_data(x) returns an internal pointer to the data of
+		 * x. Since this is an internal pointer it should not be freed or
+		 * modified in any way.
+		 * Ref: https://docs.openssl.org/master/man3/ASN1_STRING_length/
+		 */
+                const unsigned char *internal_data = ASN1_STRING_get0_data(asn1_str);
                 POSIX_ENSURE_REF(internal_data);
                 POSIX_CHECKED_MEMCPY(ext_value, internal_data, len);
             }
diff --git a/crt/s2n/tls/s2n_x509_validator.c b/crt/s2n/tls/s2n_x509_validator.c
index 1ce15c1ccdbd..4bdbda9a9f64 100644
--- a/crt/s2n/tls/s2n_x509_validator.c
+++ b/crt/s2n/tls/s2n_x509_validator.c
@@ -235,12 +235,12 @@ static S2N_RESULT s2n_verify_host_information_san_entry(struct s2n_connection *c
     if (current_name->type == GEN_DNS || current_name->type == GEN_URI) {
         *san_found = true;
 
-        const char *name = (const char *) ASN1_STRING_data(current_name->d.ia5);
+        const unsigned char *name = ASN1_STRING_get0_data(current_name->d.ia5);
         RESULT_ENSURE_REF(name);
         int name_len = ASN1_STRING_length(current_name->d.ia5);
         RESULT_ENSURE_GT(name_len, 0);
 
-        RESULT_ENSURE(conn->verify_host_fn(name, name_len, conn->data_for_verify_host), S2N_ERR_CERT_INVALID_HOSTNAME);
+        RESULT_ENSURE(conn->verify_host_fn((const char *)name, name_len, conn->data_for_verify_host), S2N_ERR_CERT_INVALID_HOSTNAME);
 
         return S2N_RESULT_OK;
     }
@@ -249,9 +249,9 @@ static S2N_RESULT s2n_verify_host_information_san_entry(struct s2n_connection *c
         *san_found = true;
 
         /* try to validate an IP address if it's in the subject alt name. */
-        const unsigned char *ip_addr = current_name->d.iPAddress->data;
+        const unsigned char *ip_addr = ASN1_STRING_get0_data(current_name->d.iPAddress);
         RESULT_ENSURE_REF(ip_addr);
-        int ip_addr_len = current_name->d.iPAddress->length;
+        int ip_addr_len = ASN1_STRING_length(current_name->d.iPAddress);
         RESULT_ENSURE_GT(ip_addr_len, 0);
 
         RESULT_STACK_BLOB(address, INET6_ADDRSTRLEN + 1, INET6_ADDRSTRLEN + 1);
@@ -317,7 +317,7 @@ static S2N_RESULT s2n_verify_host_information_common_name(struct s2n_connection
     RESULT_ENSURE_REF(public_cert);
     RESULT_ENSURE_REF(cn_found);
 
-    X509_NAME *subject_name = X509_get_subject_name(public_cert);
+    const X509_NAME *subject_name = X509_get_subject_name(public_cert);
     RESULT_ENSURE(subject_name, S2N_ERR_CERT_UNTRUSTED);
 
     int curr_idx = -1;
@@ -332,7 +332,7 @@ static S2N_RESULT s2n_verify_host_information_common_name(struct s2n_connection
 
     RESULT_ENSURE(curr_idx >= 0, S2N_ERR_CERT_UNTRUSTED);
 
-    ASN1_STRING *common_name = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject_name, curr_idx));
+    const ASN1_STRING *common_name = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject_name, curr_idx));
     RESULT_ENSURE(common_name, S2N_ERR_CERT_UNTRUSTED);
 
     /* X520CommonName allows the following ANSI string types per RFC 5280 Appendix A.1 */
@@ -351,7 +351,7 @@ static S2N_RESULT s2n_verify_host_information_common_name(struct s2n_connection
     RESULT_ENSURE_GT(cn_len, 0);
     uint32_t len = (uint32_t) cn_len;
     RESULT_ENSURE_LTE(len, s2n_array_len(peer_cn) - 1);
-    RESULT_CHECKED_MEMCPY(peer_cn, ASN1_STRING_data(common_name), len);
+    RESULT_CHECKED_MEMCPY(peer_cn, ASN1_STRING_get0_data(common_name), len);
 
     /* According to https://www.rfc-editor.org/rfc/rfc6125#section-6.4.4,
      * the CN fallback only applies to fully qualified DNS domain names.
-- 
2.55.0

Reply via email to