]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix #1437: Fix compile with OpenSSL 4.0.1.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Thu, 11 Jun 2026 15:31:01 +0000 (17:31 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Thu, 11 Jun 2026 15:31:01 +0000 (17:31 +0200)
config.h.in
configure
configure.ac
doc/Changelog
services/outside_network.c
smallapp/unbound-anchor.c
util/net_help.c

index 50b7b54b130de0096827aa65f32b3ac5d9244481..b601dbe61d5ce78da0af4d767756ce6b29132dda 100644 (file)
@@ -31,6 +31,9 @@
 /* Whether daemon is deprecated */
 #undef DEPRECATED_DAEMON
 
+/* Whether X509_NAME_get_text_by_NID is deprecated */
+#undef DEPRECATED_X509_NAME_GET_TEXT_BY_NID
+
 /* Deprecate RSA 1024 bit length, makes that an unsupported key */
 #undef DEPRECATE_RSA_1024
 
@@ -60,6 +63,9 @@
 /* Define to 1 if you have the <arpa/inet.h> header file. */
 #undef HAVE_ARPA_INET_H
 
+/* Define to 1 if you have the `ASN1_STRING_get0_data' function. */
+#undef HAVE_ASN1_STRING_GET0_DATA
+
 /* Whether the C compiler accepts the "fallthrough" attribute */
 #undef HAVE_ATTR_FALLTHROUGH
 
 /* Define to 1 if you have the `SSL_is_quic' function. */
 #undef HAVE_SSL_IS_QUIC
 
+/* Define to 1 if you have the `SSL_set1_dnsname' function. */
+#undef HAVE_SSL_SET1_DNSNAME
+
 /* Define to 1 if you have the `SSL_set1_host' function. */
 #undef HAVE_SSL_SET1_HOST
 
 /* Define to 1 if you have the <ws2tcpip.h> header file. */
 #undef HAVE_WS2TCPIP_H
 
+/* Define to 1 if you have the `X509_get_key_usage' function. */
+#undef HAVE_X509_GET_KEY_USAGE
+
+/* Define to 1 if you have the `X509_NAME_get_text_by_NID' function. */
+#undef HAVE_X509_NAME_GET_TEXT_BY_NID
+
 /* Define to 1 if you have the `X509_VERIFY_PARAM_set1_host' function. */
 #undef HAVE_X509_VERIFY_PARAM_SET1_HOST
 
index f516cae8bc8558ebaa7ee16b5c6d576c0d7ef5e9..64c784fac77814b49bc7fdcaf71a1b58b35005f1 100755 (executable)
--- a/configure
+++ b/configure
@@ -21089,6 +21089,24 @@ if test "x$ac_cv_func_SSL_get0_peername" = xyes
 then :
   printf "%s\n" "#define HAVE_SSL_GET0_PEERNAME 1" >>confdefs.h
 
+fi
+ac_fn_c_check_func "$LINENO" "SSL_set1_dnsname" "ac_cv_func_SSL_set1_dnsname"
+if test "x$ac_cv_func_SSL_set1_dnsname" = xyes
+then :
+  printf "%s\n" "#define HAVE_SSL_SET1_DNSNAME 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "X509_get_key_usage" "ac_cv_func_X509_get_key_usage"
+if test "x$ac_cv_func_X509_get_key_usage" = xyes
+then :
+  printf "%s\n" "#define HAVE_X509_GET_KEY_USAGE 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "ASN1_STRING_get0_data" "ac_cv_func_ASN1_STRING_get0_data"
+if test "x$ac_cv_func_ASN1_STRING_get0_data" = xyes
+then :
+  printf "%s\n" "#define HAVE_ASN1_STRING_GET0_DATA 1" >>confdefs.h
+
 fi
 ac_fn_c_check_func "$LINENO" "X509_VERIFY_PARAM_set1_host" "ac_cv_func_X509_VERIFY_PARAM_set1_host"
 if test "x$ac_cv_func_X509_VERIFY_PARAM_set1_host" = xyes
@@ -21133,6 +21151,54 @@ then :
 
 fi
 
+ac_fn_c_check_func "$LINENO" "X509_NAME_get_text_by_NID" "ac_cv_func_X509_NAME_get_text_by_NID"
+if test "x$ac_cv_func_X509_NAME_get_text_by_NID" = xyes
+then :
+  printf "%s\n" "#define HAVE_X509_NAME_GET_TEXT_BY_NID 1" >>confdefs.h
+
+fi
+
+if test $ac_cv_func_X509_NAME_get_text_by_NID = yes; then
+
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if X509_NAME_get_text_by_NID is deprecated" >&5
+printf %s "checking if X509_NAME_get_text_by_NID is deprecated... " >&6; }
+cache=`echo X509_NAME_get_text_by_NID | sed 'y%.=/+-%___p_%'`
+if eval test \${cv_cc_deprecated_$cache+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+
+echo '
+#include "openssl/x509.h"
+' >conftest.c
+echo 'void f(void){
+               (void)X509_NAME_get_text_by_NID(NULL, 0, NULL, 0); }' >>conftest.c
+if test -z "`$CC $CPPFLAGS $CFLAGS -c conftest.c 2>&1 | grep -e deprecated -e unavailable`"; then
+eval "cv_cc_deprecated_$cache=no"
+else
+eval "cv_cc_deprecated_$cache=yes"
+fi
+rm -f conftest conftest.o conftest.c
+
+fi
+
+if eval "test \"`echo '$cv_cc_deprecated_'$cache`\" = yes"; then
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+
+printf "%s\n" "#define DEPRECATED_X509_NAME_GET_TEXT_BY_NID 1" >>confdefs.h
+
+:
+
+else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+:
+
+fi
+
+fi
 LIBS="$BAKLIBS"
 
 ac_fn_check_decl "$LINENO" "SSL_COMP_get_compression_methods" "ac_cv_have_decl_SSL_COMP_get_compression_methods" "
index 57ca54f7228423f52c0b54ab2f1cfbc4762afbcd..212b45f28c80c7ec0d23b58f71c3b37c1ed50795 100644 (file)
@@ -1085,7 +1085,14 @@ AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_defa
 # these check_funcs need -lssl
 BAKLIBS="$LIBS"
 LIBS="-lssl $LIBS"
-AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_tlsext_ticket_key_evp_cb SSL_CTX_set_alpn_select_cb SSL_get0_alpn_selected SSL_CTX_set_alpn_protos SSL_get1_peer_certificate])
+AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername SSL_set1_dnsname X509_get_key_usage ASN1_STRING_get0_data X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_tlsext_ticket_key_evp_cb SSL_CTX_set_alpn_select_cb SSL_get0_alpn_selected SSL_CTX_set_alpn_protos SSL_get1_peer_certificate])
+AC_CHECK_FUNCS([X509_NAME_get_text_by_NID])
+if test $ac_cv_func_X509_NAME_get_text_by_NID = yes; then
+       ACX_FUNC_DEPRECATED([X509_NAME_get_text_by_NID], [
+               (void)X509_NAME_get_text_by_NID(NULL, 0, NULL, 0);], [
+#include "openssl/x509.h"
+])
+fi
 LIBS="$BAKLIBS"
 
 AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto,SSL_CTX_set_tmp_ecdh], [], [], [
index 62731984563c92f6e98fd6c56e60c79eeef3113a..26c29b65a10979c3b5ec8de76f9dc410cd2293f9 100644 (file)
@@ -4,6 +4,7 @@
          SSL_set_quic_early_data_enabled, so the correct one is used.
        - Fix for #1306: configure checks if the ngtcp2_crypto_ossl
          header file is available, and prints an error otherwise.
+       - Fix #1437: Fix compile with OpenSSL 4.0.1.
 
 10 June 2026: Wouter
        - Fix pythonmod script read for numeric overflow.
index 38598ed48b9f2ccc7fdc6156df1a58f23c1b327a..3819b037cea3820772c006e6e12ff7cfe0c83c7b 100644 (file)
@@ -3756,7 +3756,33 @@ setup_comm_ssl(struct comm_point* cp, struct outside_network* outnet,
                (void)SSL_set_tlsext_host_name(cp->ssl, host);
        }
 #endif
-#ifdef HAVE_SSL_SET1_HOST
+#ifdef HAVE_SSL_SET1_DNSNAME
+       if((SSL_CTX_get_verify_mode(outnet->sslctx)&SSL_VERIFY_PEER)) {
+               /* because we set SSL_VERIFY_PEER, in netevent in
+                * ssl_handshake, it'll check if the certificate
+                * verification has succeeded */
+               /* SSL_VERIFY_PEER is set on the sslctx */
+               /* and the certificates to verify with are loaded into
+                * it with SSL_load_verify_locations or
+                * SSL_CTX_set_default_verify_paths */
+               /* setting the hostname makes openssl verify the
+                * host name in the x509 certificate in the
+                * SSL connection*/
+               struct sockaddr_storage tmpaddr;
+               socklen_t tmpaddrlen = (socklen_t)sizeof(tmpaddr);
+               if(ipstrtoaddr(host, UNBOUND_DNS_PORT, &tmpaddr, &tmpaddrlen)) {
+                       if(!SSL_set1_ipaddr(cp->ssl, host)) {
+                               log_err("SSL_set1_ipaddr failed");
+                               return 0;
+                       }
+               } else {
+                       if(!SSL_set1_dnsname(cp->ssl, host)) {
+                               log_err("SSL_set1_dnsname failed");
+                               return 0;
+                       }
+               }
+       }
+#elif defined(HAVE_SSL_SET1_HOST)
        if((SSL_CTX_get_verify_mode(outnet->sslctx)&SSL_VERIFY_PEER)) {
                /* because we set SSL_VERIFY_PEER, in netevent in
                 * ssl_handshake, it'll check if the certificate
index b8bc40506b5c485185f8f082ca7c269dc07ff473..93379d27f0c19f4b84bfbaf43b4247b92f8a8b32 100644 (file)
@@ -1708,18 +1708,116 @@ static unsigned long
 get_usage_of_ex(X509* cert)
 {
        unsigned long val = 0;
+#ifdef HAVE_X509_GET_KEY_USAGE
+       val = X509_get_key_usage(cert);
+       if (val == UINT32_MAX)
+               return 0;
+#else
        ASN1_BIT_STRING* s;
        if((s=X509_get_ext_d2i(cert, NID_key_usage, NULL, NULL))) {
-               if(s->length > 0) {
-                       val = s->data[0];
-                       if(s->length > 1)
-                               val |= s->data[1] << 8;
+#  ifdef HAVE_ASN1_STRING_GET0_DATA
+               const unsigned char *data = ASN1_STRING_get0_data(s);
+#  else
+               const unsigned char *data = ASN1_STRING_data(s);
+#  endif
+               int len = ASN1_STRING_length(s);
+               if(len > 0) {
+                       val = data[0];
+                       if(len > 1)
+                               val |= data[1] << 8;
                }
                ASN1_BIT_STRING_free(s);
        }
+#endif
        return val;
 }
 
+#if !defined(HAVE_X509_NAME_GET_TEXT_BY_NID) || defined(DEPRECATED_X509_NAME_GET_TEXT_BY_NID)
+/** print verbose output about name extension data. */
+static void
+print_name_ext(
+#if OPENSSL_VERSION_NUMBER >= 0x40000000
+       const
+#endif
+       X509_NAME* nm, int nid, const char* str)
+{
+       int lastpos = -1;
+       for(;;) {
+#if OPENSSL_VERSION_NUMBER >= 0x40000000
+               const
+#endif
+               X509_NAME_ENTRY* ne;
+#if OPENSSL_VERSION_NUMBER >= 0x40000000
+               const
+#endif
+               ASN1_STRING *asn;
+               const unsigned char *data;
+               char buf[1024];
+
+               lastpos = X509_NAME_get_index_by_NID(nm, nid, lastpos);
+               if(lastpos == -1 || lastpos == -2)
+                       break;
+               ne = X509_NAME_get_entry(nm, lastpos);
+               if(!ne) continue;
+               asn = X509_NAME_ENTRY_get_data(ne);
+               if(!asn) continue;
+#  ifdef HAVE_ASN1_STRING_GET0_DATA
+               data = ASN1_STRING_get0_data(asn);
+#  else
+               data = ASN1_STRING_data(asn);
+#  endif
+               if(!data) continue;
+               if(ASN1_STRING_length(asn) > (int)sizeof(buf)-1) continue;
+               memcpy(buf, data, ASN1_STRING_length(asn));
+               buf[ASN1_STRING_length(asn)]=0;
+               printf("%s: %s\n", str, buf);
+       }
+}
+#endif /* X509_NAME_GET_TEXT_BY_NID */
+
+#if !defined(HAVE_X509_NAME_GET_TEXT_BY_NID) || defined(DEPRECATED_X509_NAME_GET_TEXT_BY_NID)
+/** see if the valid emailaddr is present. */
+static int
+has_valid_emailaddr(
+#if OPENSSL_VERSION_NUMBER >= 0x40000000
+       const
+#endif
+       X509_NAME* nm, const char* p7signer)
+{
+       int lastpos = -1;
+       for(;;) {
+#if OPENSSL_VERSION_NUMBER >= 0x40000000
+               const
+#endif
+               X509_NAME_ENTRY* ne;
+#if OPENSSL_VERSION_NUMBER >= 0x40000000
+               const
+#endif
+               ASN1_STRING *asn;
+               const unsigned char *data;
+
+               lastpos = X509_NAME_get_index_by_NID(nm,
+                       NID_pkcs9_emailAddress, lastpos);
+               if(lastpos == -1 || lastpos == -2)
+                       break;
+               ne = X509_NAME_get_entry(nm, lastpos);
+               if(!ne) continue;
+               asn = X509_NAME_ENTRY_get_data(ne);
+               if(!asn) continue;
+#  ifdef HAVE_ASN1_STRING_GET0_DATA
+               data = ASN1_STRING_get0_data(asn);
+#  else
+               data = ASN1_STRING_data(asn);
+#  endif
+               if(!data) continue;
+               if(ASN1_STRING_length(asn) == (int)strlen(p7signer) &&
+                       strncmp((char*)data, p7signer, strlen(p7signer)) == 0)
+                       return 1; /* match */
+       }
+       return 0;
+}
+#endif /* X509_NAME_GET_TEXT_BY_NID */
+
 /** get valid signers from the list of signers in the signature */
 static STACK_OF(X509)*
 get_valid_signers(PKCS7* p7, const char* p7signer)
@@ -1739,6 +1837,9 @@ get_valid_signers(PKCS7* p7, const char* p7signer)
                return NULL;
        }
        for(i=0; i<sk_X509_num(signers); i++) {
+#if OPENSSL_VERSION_NUMBER >= 0x40000000
+               const
+#endif
                X509_NAME* nm = X509_get_subject_name(
                        sk_X509_value(signers, i));
                char buf[1024];
@@ -1751,17 +1852,29 @@ get_valid_signers(PKCS7* p7, const char* p7signer)
                                (int)sizeof(buf));
                        printf("signer %d: Subject: %s\n", i,
                                nmline?nmline:"no subject");
+#if !defined(HAVE_X509_NAME_GET_TEXT_BY_NID) || defined(DEPRECATED_X509_NAME_GET_TEXT_BY_NID)
+                       if(verb >= 3) {
+                               print_name_ext(nm, NID_commonName,
+                                       "commonName");
+                               print_name_ext(nm, NID_pkcs9_emailAddress,
+                                       "emailAddress");
+                       }
+#else
                        if(verb >= 3 && X509_NAME_get_text_by_NID(nm,
                                NID_commonName, buf, (int)sizeof(buf)))
                                printf("commonName: %s\n", buf);
                        if(verb >= 3 && X509_NAME_get_text_by_NID(nm,
                                NID_pkcs9_emailAddress, buf, (int)sizeof(buf)))
                                printf("emailAddress: %s\n", buf);
+#endif
                }
                if(verb) {
                        int ku_loc = X509_get_ext_by_NID(
                                sk_X509_value(signers, i), NID_key_usage, -1);
                        if(verb >= 3 && ku_loc >= 0) {
+#if OPENSSL_VERSION_NUMBER >= 0x40000000
+                               const
+#endif
                                X509_EXTENSION *ex = X509_get_ext(
                                        sk_X509_value(signers, i), ku_loc);
                                if(ex) {
@@ -1775,6 +1888,12 @@ get_valid_signers(PKCS7* p7, const char* p7signer)
                        /* there is no name to check, return all records */
                        if(verb) printf("did not check commonName of signer\n");
                } else {
+#if !defined(HAVE_X509_NAME_GET_TEXT_BY_NID) || defined(DEPRECATED_X509_NAME_GET_TEXT_BY_NID)
+                       if(!has_valid_emailaddr(nm, p7signer)) {
+                               if(verb) printf("removed cert with wrong name\n");
+                               continue; /* wrong name, skip it */
+                       }
+#else
                        if(!X509_NAME_get_text_by_NID(nm,
                                NID_pkcs9_emailAddress,
                                buf, (int)sizeof(buf))) {
@@ -1785,6 +1904,7 @@ get_valid_signers(PKCS7* p7, const char* p7signer)
                                if(verb) printf("removed cert with wrong name\n");
                                continue; /* wrong name, skip it */
                        }
+#endif
                }
 
                /* check that the key usage allows digital signatures
index 2d4ea83e98daca893a0ca0474bb8092082fc42ef..2bf4f47edff76fad1308dfb75d0fbf446b5cfae4 100644 (file)
@@ -1446,6 +1446,8 @@ void* listen_sslctx_create(const char* key, const char* pem,
                SSL_CTX_set_alpn_select_cb(ctx, doh_alpn_select_cb, NULL);
 #endif
        }
+#else /* HAVE_SSL_CTX_SET_ALPN_SELECT_CB */
+       (void)is_dot; (void)is_doh;
 #endif /* HAVE_SSL_CTX_SET_ALPN_SELECT_CB */
        return ctx;
 #else
@@ -1705,6 +1707,10 @@ int check_auth_name_for_ssl(char* auth_name)
 /** set the authname on an SSL structure, SSL* ssl */
 int set_auth_name_on_ssl(void* ssl, char* auth_name, int use_sni)
 {
+#ifdef HAVE_SSL_SET1_DNSNAME
+       struct sockaddr_storage tmpaddr;
+       socklen_t tmpaddrlen = (socklen_t)sizeof(tmpaddr);
+#endif
        if(!auth_name) return 1;
 #ifdef HAVE_SSL
        if(use_sni) {
@@ -1714,7 +1720,20 @@ int set_auth_name_on_ssl(void* ssl, char* auth_name, int use_sni)
        (void)ssl;
        (void)use_sni;
 #endif
-#ifdef HAVE_SSL_SET1_HOST
+#ifdef HAVE_SSL_SET1_DNSNAME
+       SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL);
+       if(ipstrtoaddr(auth_name, UNBOUND_DNS_PORT, &tmpaddr, &tmpaddrlen)) {
+               if(!SSL_set1_ipaddr(ssl, auth_name)) {
+                       log_err("SSL_set1_ipaddr failed");
+                       return 0;
+               }
+       } else {
+               if(!SSL_set1_dnsname(ssl, auth_name)) {
+                       log_err("SSL_set1_dnsname failed");
+                       return 0;
+               }
+       }
+#elif defined(HAVE_SSL_SET1_HOST)
        SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL);
        /* setting the hostname makes openssl verify the
         * host name in the x509 certificate in the