From: W.C.A. Wijngaards Date: Thu, 11 Jun 2026 15:31:01 +0000 (+0200) Subject: - Fix #1437: Fix compile with OpenSSL 4.0.1. X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=ecd41bef27eb7c4f9f82cd0a885a68c54b26a72f;p=thirdparty%2Funbound.git - Fix #1437: Fix compile with OpenSSL 4.0.1. --- diff --git a/config.h.in b/config.h.in index 50b7b54b1..b601dbe61 100644 --- a/config.h.in +++ b/config.h.in @@ -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 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 @@ -689,6 +695,9 @@ /* 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 @@ -860,6 +869,12 @@ /* Define to 1 if you have the 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 diff --git a/configure b/configure index f516cae8b..64c784fac 100755 --- 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" " diff --git a/configure.ac b/configure.ac index 57ca54f72..212b45f28 100644 --- a/configure.ac +++ b/configure.ac @@ -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], [], [], [ diff --git a/doc/Changelog b/doc/Changelog index 627319845..26c29b65a 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -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. diff --git a/services/outside_network.c b/services/outside_network.c index 38598ed48..3819b037c 100644 --- a/services/outside_network.c +++ b/services/outside_network.c @@ -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 diff --git a/smallapp/unbound-anchor.c b/smallapp/unbound-anchor.c index b8bc40506..93379d27f 100644 --- a/smallapp/unbound-anchor.c +++ b/smallapp/unbound-anchor.c @@ -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= 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 diff --git a/util/net_help.c b/util/net_help.c index 2d4ea83e9..2bf4f47ed 100644 --- a/util/net_help.c +++ b/util/net_help.c @@ -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