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]) ])