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

