]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
build: support LibreSSL native crypto lib with ngtcp2 1.15.0+
authorViktor Szakats <commit@vsz.me>
Sat, 23 Aug 2025 08:48:12 +0000 (10:48 +0200)
committerViktor Szakats <commit@vsz.me>
Sat, 23 Aug 2025 13:45:36 +0000 (15:45 +0200)
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

CMake/FindNGTCP2.cmake
CMakeLists.txt
configure.ac
docs/INSTALL-CMAKE.md
m4/curl-openssl.m4

index 02e7652ab3a215e48d07f05687b7158e6e512f66..700017f859f7eda885c845312daa79a8d258bd4d 100644 (file)
 # 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()
index a1bc875285f91fb2bc231ada1eefb112d02a7726..81287f61aa77e595d6307e5e1aae548dd9c1fa2c 100644 (file)
@@ -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)
index 1deb4f56b0cbf60de6a4272bc8e3016d53f5c954..2755bf9018a97dff35ee5478d021725157bb061f 100644 (file)
@@ -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"
index 956bd104f08750cb60cc178dffa2ba33036ca353..ea761fa99a0e2e56609a0ff2767012fd8806c160 100644 (file)
@@ -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.
index 20e3284189ea24783a3353bf574e4f5c5fc913f0..c421fbae883c1329325c056e791832dabaa6dc4a 100644 (file)
@@ -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])
     ])