From 5223f92a8472489acb427552317b160facccec2b Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Tue, 16 Jun 2026 13:16:05 +0200 Subject: [PATCH 1/2] Support OpenSSL 4.0 This patch was added to the Fedora source RPM as part of the OpenSSL 4.0 change by Yaakov Selkowitz . The description of that patch follows: Includes backports of upstream neon changes: https://github.com/notroj/neon/commit/a8aa87dcebf0b69370907c66a498fd746fdfeb48 https://github.com/notroj/neon/commit/eb476102bf7b26d2d287d089b3da8925acd5319e --- deps/libneon/src/ne_openssl.c | 60 ++++++++++++------- src/auth/davix_openssl.cpp | 2 +- .../copy/delegation/GRSTx509MakeProxyCert.cpp | 9 +-- src/modules/copy/delegation/delegation.cpp | 2 +- 4 files changed, 44 insertions(+), 29 deletions(-) diff --git a/deps/libneon/src/ne_openssl.c b/deps/libneon/src/ne_openssl.c index e95a6ae9..538c9436 100644 --- a/deps/libneon/src/ne_openssl.c +++ b/deps/libneon/src/ne_openssl.c @@ -64,23 +64,25 @@ typedef const unsigned char ne_d2i_uchar; /* Append an ASN.1 DirectoryString STR to buffer BUF as UTF-8. * Returns zero on success or non-zero on error. */ -static int append_dirstring(ne_buffer *buf, ASN1_STRING *str) +static int append_dirstring(ne_buffer *buf, const ASN1_STRING *str) { unsigned char *tmp = (unsigned char *)""; /* initialize to workaround 0.9.6 bug */ - int len; + const unsigned char *data = ASN1_STRING_get0_data(str); + int len = ASN1_STRING_length(str); + int type = ASN1_STRING_type(str); - switch (str->type) { + switch (type) { case V_ASN1_IA5STRING: /* definitely ASCII */ case V_ASN1_VISIBLESTRING: /* probably ASCII */ case V_ASN1_PRINTABLESTRING: /* subset of ASCII */ - ne_buffer_qappend(buf, str->data, str->length); + ne_buffer_qappend(buf, data, len); break; case V_ASN1_UTF8STRING: /* Fail for embedded NUL bytes. */ - if (strlen((char *)str->data) != (size_t)str->length) { + if (strlen((const char *)data) != (size_t)len) { return -1; } - ne_buffer_append(buf, (char *)str->data, str->length); + ne_buffer_append(buf, (char *)data, len); break; case V_ASN1_UNIVERSALSTRING: case V_ASN1_T61STRING: /* let OpenSSL convert it as ISO-8859-1 */ @@ -104,7 +106,7 @@ static int append_dirstring(ne_buffer *buf, ASN1_STRING *str) break; default: NE_DEBUG(NE_DBG_SSL, "Could not convert DirectoryString type %d", - str->type); + type); return -1; } return 0; @@ -114,7 +116,10 @@ static int append_dirstring(ne_buffer *buf, ASN1_STRING *str) * safety. */ static char *dup_ia5string(const ASN1_IA5STRING *as) { - return ne_strnqdup(as->data, as->length); + const unsigned char *data = ASN1_STRING_get0_data(as); + int length = ASN1_STRING_length(as); + + return ne_strnqdup(data, length); } char *ne_ssl_readable_dname(const ne_ssl_dname *name) @@ -125,7 +130,7 @@ char *ne_ssl_readable_dname(const ne_ssl_dname *name) * const email = OBJ_nid2obj(NID_pkcs9_emailAddress); for (n = X509_NAME_entry_count(name->dn); n > 0; n--) { - X509_NAME_ENTRY *ent = X509_NAME_get_entry(name->dn, n-1); + const X509_NAME_ENTRY *ent = X509_NAME_get_entry(name->dn, n-1); /* Skip commonName or emailAddress except if there is no other * attribute in dname. */ @@ -169,9 +174,11 @@ static time_t asn1time_to_timet(const ASN1_TIME *atm) struct tm tm; memset(&tm, 0, sizeof(struct tm)); - int i = atm->length; - - if (i < 10) +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + if (ASN1_TIME_to_tm(atm, &tm) != 1) + return (time_t)-1; +#else + if (atm->length < 10) return (time_t )-1; tm.tm_year = (atm->data[0]-'0') * 10 + (atm->data[1]-'0'); @@ -185,9 +192,14 @@ static time_t asn1time_to_timet(const ASN1_TIME *atm) tm.tm_hour = (atm->data[6]-'0') * 10 + (atm->data[7]-'0'); tm.tm_min = (atm->data[8]-'0') * 10 + (atm->data[9]-'0'); tm.tm_sec = (atm->data[10]-'0') * 10 + (atm->data[11]-'0'); +#endif -#ifdef HAVE_TIMEZONE - /* ANSI C time handling is... interesting. */ +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + /* BSD/GNU; convert directly to GMT */ + return timegm(&tm); +#elif defined(HAVE_TIMEZONE) + /* ASN1_TIME_to_tm already converts to GMT, otherwise + * use the timezone global offset to do so. */ return mktime(&tm) - timezone; #else return mktime(&tm); @@ -235,11 +247,14 @@ static int check_identity(const ne_uri *server, X509 *cert, char **identity) } else if (nm->type == GEN_IPADD) { /* compare IP address with server IP address. */ + const unsigned char *data = ASN1_STRING_get0_data(nm->d.ip); + int len = ASN1_STRING_length(nm->d.ip); ne_inet_addr *ia; - if (nm->d.ip->length == 4) - ia = ne_iaddr_make(ne_iaddr_ipv4, nm->d.ip->data); - else if (nm->d.ip->length == 16) - ia = ne_iaddr_make(ne_iaddr_ipv6, nm->d.ip->data); + + if (len == 4) + ia = ne_iaddr_make(ne_iaddr_ipv4, data); + else if (len == 16) + ia = ne_iaddr_make(ne_iaddr_ipv6, data); else ia = NULL; /* ne_iaddr_make returns NULL if address type is unsupported */ @@ -252,8 +267,7 @@ static int check_identity(const ne_uri *server, X509 *cert, char **identity) ne_iaddr_free(ia); } else { NE_DEBUG(NE_DBG_SSL, "iPAddress name with unsupported " - "address type (length %d), skipped.\n", - nm->d.ip->length); + "address type (length %d), skipped.\n", len); } } else if (nm->type == GEN_URI) { @@ -289,8 +303,8 @@ static int check_identity(const ne_uri *server, X509 *cert, char **identity) /* Check against the commonName if no DNS alt. names were found, * as per RFC3280. */ if (!found) { - X509_NAME *subj = X509_get_subject_name(cert); - X509_NAME_ENTRY *entry; + const X509_NAME *subj = X509_get_subject_name(cert); + const X509_NAME_ENTRY *entry; ne_buffer *cname = ne_buffer_ncreate(30); int idx = -1, lastidx; @@ -888,7 +902,7 @@ ne_ssl_client_cert *ne_ssl_clicert_read(const char *filename) if (PKCS12_parse(p12, NULL, &pkey, &cert, &chain) == 1) { /* Success - no password needed for decryption. */ int len = 0; - unsigned char *name; + const unsigned char *name; if (!cert || !pkey) { PKCS12_free(p12); diff --git a/src/auth/davix_openssl.cpp b/src/auth/davix_openssl.cpp index 85f089e0..05058f3a 100644 --- a/src/auth/davix_openssl.cpp +++ b/src/auth/davix_openssl.cpp @@ -101,7 +101,7 @@ ne_ssl_client_cert *SSL_X509_Pem_Read(const std::string & pkeyfile_str, const st ne_ssl_client_cert *cc=NULL; int len, errcode; const char * pkeyfile = pkeyfile_str.c_str(), *credfile = credfile_str.c_str(), *password = password_str.c_str(); - unsigned char* name; + const unsigned char* name; if( pkeyfile ==NULL || credfile ==NULL || ((in = BIO_new(BIO_s_file())) == NULL)){ diff --git a/src/modules/copy/delegation/GRSTx509MakeProxyCert.cpp b/src/modules/copy/delegation/GRSTx509MakeProxyCert.cpp index 8e1174f4..68882f46 100644 --- a/src/modules/copy/delegation/GRSTx509MakeProxyCert.cpp +++ b/src/modules/copy/delegation/GRSTx509MakeProxyCert.cpp @@ -118,7 +118,8 @@ int GRSTx509MakeProxyCert(char **proxychain, FILE *debugfp, const EVP_MD *digest; X509 **certs = NULL; X509_REQ *req; - X509_NAME *name, *CAsubject, *newsubject; + const X509_NAME *name, *CAsubject; + X509_NAME *newsubject; X509_NAME_ENTRY *ent; ASN1_OBJECT *pci_obj = NULL, *kyu_obj; ASN1_OCTET_STRING *pci_oct, *kyu_oct; @@ -306,16 +307,16 @@ int GRSTx509MakeProxyCert(char **proxychain, FILE *debugfp, pci_obj = OBJ_txt2obj(GRST_PROXYCERTINFO_OID, 0); notAfter = - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(certs[0])), 0); + GRSTasn1TimeToTimeT(ASN1_STRING_get0_data(X509_get_notAfter(certs[0])), 0); for (i=1; i < ncerts; ++i) { if (notAfter > - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(certs[i])), + GRSTasn1TimeToTimeT(ASN1_STRING_get0_data(X509_get_notAfter(certs[i])), 0)) { notAfter = - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(certs[i])), + GRSTasn1TimeToTimeT(ASN1_STRING_get0_data(X509_get_notAfter(certs[i])), 0); ASN1_UTCTIME_set(X509_get_notAfter(certs[0]), notAfter); diff --git a/src/modules/copy/delegation/delegation.cpp b/src/modules/copy/delegation/delegation.cpp index a0e2c9d8..729b4089 100644 --- a/src/modules/copy/delegation/delegation.cpp +++ b/src/modules/copy/delegation/delegation.cpp @@ -52,7 +52,7 @@ SOAP_NMAC struct Namespace namespaces[] = // Timestamp from ASN1 representation static int get_timestamp_from_asn1(ASN1_TIME* asn1) { - char* data = (char*) ASN1_STRING_data(asn1); + char* data = (char*) ASN1_STRING_get0_data(asn1); size_t len = strlen(data); struct tm time_tm; char zone = 0; From 447b45e61ccc80f16bdfed043e89439dcd4fd5c0 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 17 Jun 2026 21:44:42 +0200 Subject: [PATCH 2/2] Small tweak to the patch to still work for EPEL 8 --- src/modules/copy/delegation/GRSTx509MakeProxyCert.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/modules/copy/delegation/GRSTx509MakeProxyCert.cpp b/src/modules/copy/delegation/GRSTx509MakeProxyCert.cpp index 68882f46..a7af5e2c 100644 --- a/src/modules/copy/delegation/GRSTx509MakeProxyCert.cpp +++ b/src/modules/copy/delegation/GRSTx509MakeProxyCert.cpp @@ -118,7 +118,11 @@ int GRSTx509MakeProxyCert(char **proxychain, FILE *debugfp, const EVP_MD *digest; X509 **certs = NULL; X509_REQ *req; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L const X509_NAME *name, *CAsubject; +#else + X509_NAME *name, *CAsubject; +#endif X509_NAME *newsubject; X509_NAME_ENTRY *ent; ASN1_OBJECT *pci_obj = NULL, *kyu_obj;