From 7e1e68047ef990fbf85d769088479439e2538073 Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Sun, 13 Sep 2026 22:14:10 +0300 Subject: [PATCH] Add OpenSSL 4.0 support Rework TLS setup and X509 certificate checking code to handle OpenSSL 4.0 API changes. Upstream-Status: Pending Signed-off-by: Scott Murray --- src/os_auth/check_cert.c | 42 +++++++++++++++------------------------- src/os_auth/check_cert.h | 4 ++-- src/os_auth/ssl.c | 9 +++++++++ 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/os_auth/check_cert.c b/src/os_auth/check_cert.c index 365eecee..94fc7660 100644 --- a/src/os_auth/check_cert.c +++ b/src/os_auth/check_cert.c @@ -106,13 +106,13 @@ int check_subject_alt_names(X509 *cert, const char *manager) */ int check_subject_cn(X509 *cert, const char *manager) { - X509_NAME *name = NULL; + const X509_NAME *name = NULL; int result = VERIFY_FALSE; int i = 0; if ((name = X509_get_subject_name(cert))) { while ((i = X509_NAME_get_index_by_NID(name, NID_commonName, i)) >= 0 && result == VERIFY_FALSE) { - X509_NAME_ENTRY *ne = X509_NAME_get_entry(name, i); + const X509_NAME_ENTRY *ne = X509_NAME_get_entry(name, i); result = check_hostname(X509_NAME_ENTRY_get_data(ne), manager); } } @@ -127,7 +127,7 @@ int check_subject_cn(X509 *cert, const char *manager) * and compared. Matching is case insensitive and basic wildcard matching * is supported. */ -int check_hostname(ASN1_STRING *cert_astr, const char *manager) +int check_hostname(const ASN1_STRING *cert_astr, const char *manager) { label c_labels[DNS_MAX_LABELS]; label m_labels[DNS_MAX_LABELS]; @@ -135,7 +135,7 @@ int check_hostname(ASN1_STRING *cert_astr, const char *manager) int m_label_num = 0; int wildcard_cert = 0; int i = 0; - char *cert_cstr = NULL; + unsigned char *cert_cstr = NULL; if (!(cert_cstr = asn1_to_cstr(cert_astr))) { return VERIFY_FALSE; @@ -143,9 +143,9 @@ int check_hostname(ASN1_STRING *cert_astr, const char *manager) /* Convert domain names to arrays of labels separated by '.' */ - c_label_num = label_array(cert_cstr, c_labels); + c_label_num = label_array((char*) cert_cstr, c_labels); m_label_num = label_array(manager, m_labels); - free(cert_cstr); + OPENSSL_free(cert_cstr); /* Check that we have an appropriate number of labels and that the name * from the certificate and the name given on the command line have @@ -193,11 +193,11 @@ int check_ipaddr(const ASN1_STRING *cert_astr, const char *manager) memset(&iptest6, 0, sizeof(iptest6)); if (inet_pton(AF_INET, manager, &iptest.sin_addr) == 1) { - if (cert_astr->length == 4 && !memcmp(cert_astr->data, (const void *)&iptest.sin_addr, 4)) { + if (ASN1_STRING_length(cert_astr) == 4 && !memcmp(ASN1_STRING_get0_data(cert_astr), (const void *)&iptest.sin_addr, 4)) { return VERIFY_TRUE; } } else if (inet_pton(AF_INET6, manager, &iptest6.sin6_addr) == 1) { - if (cert_astr->length == 16 && !memcmp(cert_astr->data, (const void *)&iptest6.sin6_addr, 16)) { + if (ASN1_STRING_length(cert_astr) == 16 && !memcmp(ASN1_STRING_get0_data(cert_astr), (const void *)&iptest6.sin6_addr, 16)) { return VERIFY_TRUE; } } @@ -291,35 +291,25 @@ int label_match(const label *label1, const label *label2) /* Convert an ASN1 string which may not be null terminated into a * standard null terminated string. Also check for embedded null - * characters. + * characters. The returned string should be freed with + * OPENSSL_free. */ -char *asn1_to_cstr(ASN1_STRING *astr) +unsigned char *asn1_to_cstr(const ASN1_STRING *astr) { - unsigned int astr_len = 0; - char *tmp = NULL; - char *cstr = NULL; + size_t astr_len = 0; + unsigned char *cstr = NULL; - if (!(astr_len = (unsigned int) ASN1_STRING_length(astr))) { - return NULL; - } - - if (!(tmp = (char *)ASN1_STRING_data(astr))) { + if ((astr_len = ASN1_STRING_to_UTF8(&cstr, astr)) <= 0) { return NULL; } /* Verify that the string does not contain embedded null characters. */ - if (memchr(tmp, '\0', astr_len)) { + if (memchr(cstr, '\0', astr_len)) { + OPENSSL_free(cstr); return NULL; } - if ((cstr = (char *) malloc(astr_len + 1)) == NULL) { - return NULL; - } - - memcpy(cstr, tmp, astr_len); - cstr[astr_len] = '\0'; - return cstr; } diff --git a/src/os_auth/check_cert.h b/src/os_auth/check_cert.h index ff244dd9..fc804653 100644 --- a/src/os_auth/check_cert.h +++ b/src/os_auth/check_cert.h @@ -46,12 +46,12 @@ label; int check_x509_cert(const SSL *ssl, const char *manager); int check_subject_alt_names(X509 *cert, const char *manager); int check_subject_cn(X509 *cert, const char *manager); -int check_hostname(ASN1_STRING *cert_astr, const char *manager); +int check_hostname(const ASN1_STRING *cert_astr, const char *manager); int check_ipaddr(const ASN1_STRING *cert_astr, const char *manager); int label_array(const char *domain_name, label result[DNS_MAX_LABELS]); int label_valid(const label *label); int label_match(const label *label1, const label *label2); -char *asn1_to_cstr(ASN1_STRING *astr); +unsigned char *asn1_to_cstr(const ASN1_STRING *astr); #endif /* LIBOPENSSL_ENABLED */ #endif /* _CHECK_CERT_H */ diff --git a/src/os_auth/ssl.c b/src/os_auth/ssl.c index c9b017cc..ec579ef1 100644 --- a/src/os_auth/ssl.c +++ b/src/os_auth/ssl.c @@ -104,10 +104,19 @@ SSL_CTX *get_ssl_context(const char *ciphers) OpenSSL_add_all_algorithms(); /* Create our context */ +#if(OPENSSL_VERSION_NUMBER < 0x40000000L) sslmeth = TLSv1_2_method(); +#else + sslmeth = TLS_method(); +#endif if (!(ctx = SSL_CTX_new(sslmeth))) { goto CONTEXT_ERR; } +#if(OPENSSL_VERSION_NUMBER >= 0x40000000L) + if (!(SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION))) { + goto CONTEXT_ERR; + } +#endif /* Explicitly set options and cipher list */ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);