From: Viktor Szakats Date: Sat, 23 Aug 2025 08:48:12 +0000 (+0200) Subject: build: support LibreSSL native crypto lib with ngtcp2 1.15.0+ X-Git-Tag: curl-8_16_0~101 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=31e6798544bf8aafbd8aef61b08623b92312aa42;p=thirdparty%2Fcurl.git build: support LibreSSL native crypto lib with ngtcp2 1.15.0+ In ngtcp2 1.15.0 the LibreSSL crypto interface library got its own name: `libngtcp2_crypto_libressl`. In previous versions it used `libngtcp2_crypto_quictls`, shared with quictls itself (but not compatible with). Adapt autotools and cmake scripts to look for the new name first, and fall back to the old one if not found. Fallback to quictls tested OK in CI with both autotools and cmake: https://github.com/curl/curl/actions/runs/17174994908?pr=18377 Ref: https://github.com/ngtcp2/ngtcp2/releases/tag/v1.15.0 Ref: https://github.com/ngtcp2/ngtcp2/pull/1716 Closes #18377 --- diff --git a/CMake/FindNGTCP2.cmake b/CMake/FindNGTCP2.cmake index 02e7652ab3..700017f859 100644 --- a/CMake/FindNGTCP2.cmake +++ b/CMake/FindNGTCP2.cmake @@ -26,11 +26,12 @@ # This module accepts optional COMPONENTS to control the crypto library (these are # mutually exclusive): # -# - quictls: Use `libngtcp2_crypto_quictls`. (choose this for LibreSSL) -# - BoringSSL: Use `libngtcp2_crypto_boringssl`. (choose this for AWS-LC) -# - wolfSSL: Use `libngtcp2_crypto_wolfssl`. +# - BoringSSL: Use `libngtcp2_crypto_boringssl`. (also for AWS-LC) # - GnuTLS: Use `libngtcp2_crypto_gnutls`. +# - LibreSSL: Use `libngtcp2_crypto_libressl`. (requires ngtcp2 1.15.0+) # - ossl: Use `libngtcp2_crypto_ossl`. +# - quictls: Use `libngtcp2_crypto_quictls`. (also for LibreSSL with ngtcp2 <1.15.0) +# - wolfSSL: Use `libngtcp2_crypto_wolfssl`. # # Input variables: # @@ -38,6 +39,7 @@ # - `NGTCP2_LIBRARY`: Path to `ngtcp2` library. # - `NGTCP2_CRYPTO_BORINGSSL_LIBRARY`: Path to `ngtcp2_crypto_boringssl` library. # - `NGTCP2_CRYPTO_GNUTLS_LIBRARY`: Path to `ngtcp2_crypto_gnutls` library. +# - `NGTCP2_CRYPTO_LIBRESSL_LIBRARY`: Path to `ngtcp2_crypto_libressl` library. # - `NGTCP2_CRYPTO_OSSL_LIBRARY`: Path to `ngtcp2_crypto_ossl` library. # - `NGTCP2_CRYPTO_QUICTLS_LIBRARY`: Path to `ngtcp2_crypto_quictls` library. # - `NGTCP2_CRYPTO_WOLFSSL_LIBRARY`: Path to `ngtcp2_crypto_wolfssl` library. @@ -55,7 +57,7 @@ if(NGTCP2_FIND_COMPONENTS) set(_ngtcp2_crypto_backend "") foreach(_component IN LISTS NGTCP2_FIND_COMPONENTS) - if(_component MATCHES "^(BoringSSL|GnuTLS|ossl|quictls|wolfSSL)") + if(_component MATCHES "^(BoringSSL|GnuTLS|LibreSSL|ossl|quictls|wolfSSL)") if(_ngtcp2_crypto_backend) message(FATAL_ERROR "NGTCP2: Only one crypto library can be selected") endif() @@ -74,11 +76,13 @@ if(_ngtcp2_crypto_backend) list(APPEND NGTCP2_PC_REQUIRES "lib${_crypto_library_lower}") endif() +set(_tried_pkgconfig FALSE) if(CURL_USE_PKGCONFIG AND NOT DEFINED NGTCP2_INCLUDE_DIR AND NOT DEFINED NGTCP2_LIBRARY) find_package(PkgConfig QUIET) pkg_check_modules(NGTCP2 ${NGTCP2_PC_REQUIRES}) + set(_tried_pkgconfig TRUE) endif() if(NGTCP2_FOUND) @@ -125,4 +129,9 @@ else() endif() mark_as_advanced(NGTCP2_INCLUDE_DIR NGTCP2_LIBRARY NGTCP2_CRYPTO_LIBRARY) + + if(NOT NGTCP2_FOUND AND _tried_pkgconfig) # reset variables to allow another round of detection + unset(NGTCP2_INCLUDE_DIR CACHE) + unset(NGTCP2_LIBRARY CACHE) + endif() endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index a1bc875285..81287f61aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1100,20 +1100,23 @@ if(USE_NGTCP2) message(FATAL_ERROR "MultiSSL cannot be enabled with HTTP/3 and vice versa.") elseif(USE_OPENSSL OR USE_WOLFSSL) if(USE_WOLFSSL) - find_package(NGTCP2 REQUIRED "wolfSSL") + find_package(NGTCP2 REQUIRED COMPONENTS "wolfSSL") elseif(HAVE_BORINGSSL OR HAVE_AWSLC) - find_package(NGTCP2 REQUIRED "BoringSSL") + find_package(NGTCP2 REQUIRED COMPONENTS "BoringSSL") elseif(OPENSSL_VERSION VERSION_GREATER_EQUAL 3.5.0 AND NOT USE_OPENSSL_QUIC) - find_package(NGTCP2 REQUIRED "ossl") + find_package(NGTCP2 REQUIRED COMPONENTS "ossl") if(NGTCP2_VERSION VERSION_LESS 1.12.0) message(FATAL_ERROR "ngtcp2 1.12.0 or upper required for OpenSSL") endif() set(OPENSSL_QUIC_API2 1) - else() - find_package(NGTCP2 REQUIRED "quictls") - if(NOT HAVE_LIBRESSL) - set(_openssl "quictls") + elseif(HAVE_LIBRESSL) + find_package(NGTCP2 COMPONENTS "LibreSSL") + if(NOT NGTCP2_FOUND) + find_package(NGTCP2 REQUIRED COMPONENTS "quictls") # for ngtcp2 <1.15.0 endif() + else() + find_package(NGTCP2 REQUIRED COMPONENTS "quictls") + set(_openssl "quictls") endif() curl_openssl_check_quic() elseif(USE_GNUTLS) diff --git a/configure.ac b/configure.ac index 1deb4f56b0..2755bf9018 100644 --- a/configure.ac +++ b/configure.ac @@ -3241,7 +3241,66 @@ if test X"$want_tcp2" != Xno; then fi fi -if test "x$USE_NGTCP2" = "x1" -a "x$OPENSSL_ENABLED" = "x1" -a \ +if test "x$USE_NGTCP2" = "x1" -a "x$OPENSSL_ENABLED" = "x1" -a "$HAVE_LIBRESSL" = "1"; then + dnl backup the pre-ngtcp2_crypto_libressl variables + CLEANLDFLAGS="$LDFLAGS" + CLEANLDFLAGSPC="$LDFLAGSPC" + CLEANCPPFLAGS="$CPPFLAGS" + CLEANLIBS="$LIBS" + + CURL_CHECK_PKGCONFIG(libngtcp2_crypto_libressl, $want_tcp2_path) + + if test "$PKGCONFIG" != "no"; then + LIB_NGTCP2_CRYPTO_LIBRESSL=`CURL_EXPORT_PCDIR([$want_tcp2_path]) + $PKGCONFIG --libs-only-l libngtcp2_crypto_libressl` + AC_MSG_NOTICE([-l is $LIB_NGTCP2_CRYPTO_LIBRESSL]) + + CPP_NGTCP2_CRYPTO_LIBRESSL=`CURL_EXPORT_PCDIR([$want_tcp2_path]) dnl + $PKGCONFIG --cflags-only-I libngtcp2_crypto_libressl` + AC_MSG_NOTICE([-I is $CPP_NGTCP2_CRYPTO_LIBRESSL]) + + LD_NGTCP2_CRYPTO_LIBRESSL=`CURL_EXPORT_PCDIR([$want_tcp2_path]) + $PKGCONFIG --libs-only-L libngtcp2_crypto_libressl` + AC_MSG_NOTICE([-L is $LD_NGTCP2_CRYPTO_LIBRESSL]) + + LDFLAGS="$LDFLAGS $LD_NGTCP2_CRYPTO_LIBRESSL" + LDFLAGSPC="$LDFLAGSPC $LD_NGTCP2_CRYPTO_LIBRESSL" + CPPFLAGS="$CPPFLAGS $CPP_NGTCP2_CRYPTO_LIBRESSL" + LIBS="$LIB_NGTCP2_CRYPTO_LIBRESSL $LIBS" + + if test "x$cross_compiling" != "xyes"; then + DIR_NGTCP2_CRYPTO_LIBRESSL=`echo $LD_NGTCP2_CRYPTO_LIBRESSL | $SED -e 's/^-L//'` + fi + AC_CHECK_LIB(ngtcp2_crypto_libressl, ngtcp2_crypto_recv_client_initial_cb, + [ + AC_CHECK_HEADERS(ngtcp2/ngtcp2_crypto.h, + USE_NGTCP2=1 + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_NGTCP2_CRYPTO_LIBRESSL" + export CURL_LIBRARY_PATH + AC_MSG_NOTICE([Added $DIR_NGTCP2_CRYPTO_LIBRESSL to CURL_LIBRARY_PATH]) + LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libngtcp2_crypto_libressl" + ) + ], + dnl not found, revert back to clean variables + LDFLAGS=$CLEANLDFLAGS + LDFLAGSPC=$CLEANLDFLAGSPC + CPPFLAGS=$CLEANCPPFLAGS + LIBS=$CLEANLIBS + ) + + else + dnl no ngtcp2_crypto_libressl pkg-config found, deal with it + if test X"$want_tcp2" != Xdefault; then + dnl To avoid link errors, we do not allow --with-ngtcp2 without + dnl a pkgconfig file + AC_MSG_WARN([--with-ngtcp2 was specified but could not find ngtcp2_crypto_libressl pkg-config file.]) + dnl Pretend to be quictls to fall back to using ngtcp2_crypto_quictls + fi + HAVE_LIBRESSL=0 + fi +fi + +if test "x$USE_NGTCP2" = "x1" -a "x$OPENSSL_ENABLED" = "x1" -a "$HAVE_LIBRESSL" != "1" -a \ "x$OPENSSL_IS_BORINGSSL" != "x1" -a "x$OPENSSL_QUIC_API2" != "x1"; then dnl backup the pre-ngtcp2_crypto_quictls variables CLEANLDFLAGS="$LDFLAGS" diff --git a/docs/INSTALL-CMAKE.md b/docs/INSTALL-CMAKE.md index 956bd104f0..ea761fa99a 100644 --- a/docs/INSTALL-CMAKE.md +++ b/docs/INSTALL-CMAKE.md @@ -434,10 +434,11 @@ Details via CMake - `NGHTTP3_LIBRARY`: Path to `nghttp3` library. - `NGTCP2_INCLUDE_DIR`: The ngtcp2 include directory. - `NGTCP2_LIBRARY`: Path to `ngtcp2` library. -- `NGTCP2_CRYPTO_BORINGSSL_LIBRARY`: Path to `ngtcp2_crypto_boringssl` library. +- `NGTCP2_CRYPTO_BORINGSSL_LIBRARY`: Path to `ngtcp2_crypto_boringssl` library. (also for AWS-LC) - `NGTCP2_CRYPTO_GNUTLS_LIBRARY`: Path to `ngtcp2_crypto_gnutls` library. +- `NGTCP2_CRYPTO_LIBRESSL_LIBRARY`: Path to `ngtcp2_crypto_libressl` library. (requires ngtcp2 1.15.0+) - `NGTCP2_CRYPTO_OSSL_LIBRARY`: Path to `ngtcp2_crypto_ossl` library. -- `NGTCP2_CRYPTO_QUICTLS_LIBRARY`: Path to `ngtcp2_crypto_quictls` library. +- `NGTCP2_CRYPTO_QUICTLS_LIBRARY`: Path to `ngtcp2_crypto_quictls` library. (also for LibreSSL with ngtcp2 <1.15.0) - `NGTCP2_CRYPTO_WOLFSSL_LIBRARY`: Path to `ngtcp2_crypto_wolfssl` library. - `NETTLE_INCLUDE_DIR`: The nettle include directory. - `NETTLE_LIBRARY`: Path to `nettle` library. diff --git a/m4/curl-openssl.m4 b/m4/curl-openssl.m4 index 20e3284189..c421fbae88 100644 --- a/m4/curl-openssl.m4 +++ b/m4/curl-openssl.m4 @@ -292,6 +292,7 @@ if test "x$OPT_OPENSSL" != xno; then ],[ AC_MSG_RESULT([yes]) ssl_msg="LibreSSL" + HAVE_LIBRESSL=1 ],[ AC_MSG_RESULT([no]) ])