From: Viktor Szakats Date: Thu, 21 Aug 2025 10:09:17 +0000 (+0200) Subject: gnutls: fix building with older supported GnuTLS versions X-Git-Tag: curl-8_16_0~134 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7956a2a7568ed6fff6e993767300aeaf39789272;p=thirdparty%2Fcurl.git gnutls: fix building with older supported GnuTLS versions Also: - GHA/linux-old: switch jobs from OpenSSL 1.0.2 to GnuTLS 3.5.8. Ref: https://gitlab.com/gnutls/gnutls/blob/master/NEWS Follow-up to fa0ccd9f1fbbbd77bf50b26e3ba231ea6c729474 #15774 Follow-up to 68bd759c2bfe74799c3355ad29265b795a7e6c62 #15667 Cherry-picked from #18330 Closes #18335 --- diff --git a/.github/workflows/linux-old.yml b/.github/workflows/linux-old.yml index ea80e37431..352986eb04 100644 --- a/.github/workflows/linux-old.yml +++ b/.github/workflows/linux-old.yml @@ -70,7 +70,7 @@ jobs: dpkg -i freexian-archive-keyring_2022.06.08_all.deb echo 'deb http://deb.freexian.com/extended-lts stretch-lts main contrib non-free' | tee /etc/apt/sources.list.d/extended-lts.list apt-get -o Dpkg::Use-Pty=0 update - apt-get -o Dpkg::Use-Pty=0 install -y --no-install-suggests --no-install-recommends cmake make automake autoconf libtool gcc pkg-config libpsl-dev libzstd-dev zlib1g-dev libssl1.0-dev libssh-dev libssh2-1-dev libc-ares-dev heimdal-dev libldap2-dev librtmp-dev stunnel4 groff + apt-get -o Dpkg::Use-Pty=0 install -y --no-install-suggests --no-install-recommends cmake make automake autoconf libtool gcc pkg-config libpsl-dev libzstd-dev zlib1g-dev libgnutls28-dev libssh-dev libssh2-1-dev libc-ares-dev heimdal-dev libldap2-dev librtmp-dev stunnel4 groff # GitHub's actions/checkout needs newer glibc and libstdc++. The latter also depends on # gcc-8-base, but it doesn't actually seem used in our situation and isn't available in # the main repo, so force the install. @@ -87,7 +87,7 @@ jobs: mkdir bld-1 cd bld-1 cmake .. -DCMAKE_UNITY_BUILD=ON -DCURL_WERROR=ON -DBUILD_SHARED_LIBS=ON \ - -DENABLE_ARES=OFF -DCURL_ZSTD=OFF -DCURL_USE_GSSAPI=OFF -DCURL_USE_LIBSSH2=ON -DCURL_USE_LIBSSH=OFF -DUSE_LIBRTMP=ON + -DCURL_USE_GNUTLS=ON -DENABLE_ARES=OFF -DCURL_ZSTD=OFF -DCURL_USE_GSSAPI=OFF -DCURL_USE_LIBSSH2=ON -DCURL_USE_LIBSSH=OFF -DUSE_LIBRTMP=ON make install src/curl --disable --version @@ -103,7 +103,7 @@ jobs: mkdir bld-cares cd bld-cares cmake .. -DCMAKE_UNITY_BUILD=ON -DCURL_WERROR=ON -DBUILD_SHARED_LIBS=ON \ - -DENABLE_ARES=ON -DCURL_USE_GSSAPI=ON -DCURL_USE_LIBSSH2=OFF -DCURL_USE_LIBSSH=OFF -DUSE_LIBRTMP=ON \ + -DCURL_USE_GNUTLS=ON -DENABLE_ARES=ON -DCURL_USE_GSSAPI=ON -DCURL_USE_LIBSSH2=OFF -DCURL_USE_LIBSSH=OFF -DUSE_LIBRTMP=ON \ -DCURL_LIBCURL_VERSIONED_SYMBOLS=ON - name: 'cmake curl_config.h' @@ -136,7 +136,7 @@ jobs: mkdir bld-am cd bld-am ../configure --disable-dependency-tracking --enable-unity --enable-warnings --enable-werror \ - --with-openssl --enable-ares --with-libssh2 --with-zstd --with-gssapi --with-librtmp \ + --with-gnutls --enable-ares --with-libssh2 --with-zstd --with-gssapi --with-librtmp \ --prefix="$PWD"/../curl-install-am - name: 'autotools curl_config.h' diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c index 7ecf0f0507..3c572806e2 100644 --- a/lib/vtls/gtls.c +++ b/lib/vtls/gtls.c @@ -77,7 +77,12 @@ static bool gtls_inited = FALSE; #error "too old GnuTLS version" #endif -# include +#undef CURL_GNUTLS_EARLY_DATA +#if GNUTLS_VERSION_NUMBER >= 0x03060d +#define CURL_GNUTLS_EARLY_DATA +#endif + +#include struct gtls_ssl_backend_data { struct gtls_ctx gtls; @@ -655,6 +660,7 @@ CURLcode Curl_gtls_client_trust_setup(struct Curl_cfilter *cf, return CURLE_OK; } +#ifdef CURL_GNUTLS_EARLY_DATA CURLcode Curl_gtls_cache_session(struct Curl_cfilter *cf, struct Curl_easy *data, const char *ssl_peer_key, @@ -715,6 +721,7 @@ CURLcode Curl_gtls_cache_session(struct Curl_cfilter *cf, } return result; } +#endif int Curl_glts_get_ietf_proto(gnutls_session_t session) { @@ -727,13 +734,16 @@ int Curl_glts_get_ietf_proto(gnutls_session_t session) return CURL_IETF_PROTO_TLS1_1; case GNUTLS_TLS1_2: return CURL_IETF_PROTO_TLS1_2; +#if GNUTLS_VERSION_NUMBER >= 0x030603 case GNUTLS_TLS1_3: return CURL_IETF_PROTO_TLS1_3; +#endif default: return CURL_IETF_PROTO_UNKNOWN; } } +#ifdef CURL_GNUTLS_EARLY_DATA static CURLcode cf_gtls_update_session_id(struct Curl_cfilter *cf, struct Curl_easy *data, gnutls_session_t session) @@ -769,6 +779,7 @@ static int gtls_handshake_cb(gnutls_session_t session, unsigned int htype, } return 0; } +#endif static CURLcode gtls_set_priority(struct Curl_cfilter *cf, struct Curl_easy *data, @@ -883,6 +894,7 @@ static CURLcode gtls_client_init(struct Curl_cfilter *cf, /* Initialize TLS session as a client */ init_flags = GNUTLS_CLIENT; +#ifdef CURL_GNUTLS_EARLY_DATA if(peer->transport == TRNSPRT_QUIC && earlydata_max > 0) init_flags |= GNUTLS_ENABLE_EARLY_DATA | GNUTLS_NO_END_OF_EARLY_DATA; else if(earlydata_max > 0 && earlydata_max != 0xFFFFFFFFUL) @@ -891,13 +903,14 @@ static CURLcode gtls_client_init(struct Curl_cfilter *cf, * and one announcing 0xFFFFFFFFUL. On TCP+TLS, this is unlikely, but * on QUIC this is common. */ init_flags |= GNUTLS_ENABLE_EARLY_DATA; +#endif #ifdef GNUTLS_FORCE_CLIENT_CERT init_flags |= GNUTLS_FORCE_CLIENT_CERT; #endif #ifdef GNUTLS_NO_TICKETS_TLS12 - init_flags |= GNUTLS_NO_TICKETS_TLS12; + init_flags |= GNUTLS_NO_TICKETS_TLS12; #endif #ifdef GNUTLS_NO_STATUS_REQUEST @@ -1032,6 +1045,7 @@ static CURLcode gtls_client_init(struct Curl_cfilter *cf, return CURLE_OK; } +#ifdef CURL_GNUTLS_EARLY_DATA static int keylog_callback(gnutls_session_t session, const char *label, const gnutls_datum_t *secret) { @@ -1080,6 +1094,7 @@ static CURLcode gtls_on_session_reuse(struct Curl_cfilter *cf, } return result; } +#endif CURLcode Curl_gtls_ctx_init(struct gtls_ctx *gctx, struct Curl_cfilter *cf, @@ -1158,11 +1173,13 @@ CURLcode Curl_gtls_ctx_init(struct gtls_ctx *gctx, goto out; } +#ifdef CURL_GNUTLS_EARLY_DATA /* Open the file if a TLS or QUIC backend has not done this before. */ Curl_tls_keylog_open(); if(Curl_tls_keylog_enabled()) { gnutls_session_set_keylog_function(gctx->session, keylog_callback); } +#endif /* convert the ALPN string from our arguments to a list of strings that * gnutls wants and will convert internally back to this string for sending @@ -1207,7 +1224,13 @@ gtls_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) result = Curl_gtls_ctx_init(&backend->gtls, cf, data, &connssl->peer, connssl->alpn, NULL, NULL, cf, - gtls_on_session_reuse); +#ifdef CURL_GNUTLS_EARLY_DATA + gtls_on_session_reuse +#else + NULL +#endif + ); + if(result) return result; @@ -1218,9 +1241,11 @@ gtls_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data); } +#ifdef CURL_GNUTLS_EARLY_DATA gnutls_handshake_set_hook_function(backend->gtls.session, GNUTLS_HANDSHAKE_ANY, GNUTLS_HOOK_POST, gtls_handshake_cb); +#endif /* register callback functions and handle to send and receive data. */ gnutls_transport_set_ptr(backend->gtls.session, cf); @@ -1793,15 +1818,18 @@ static CURLcode gtls_verifyserver(struct Curl_cfilter *cf, if(result) goto out; +#ifdef CURL_GNUTLS_EARLY_DATA /* Only on TLSv1.2 or lower do we have the session id now. For * TLSv1.3 we get it via a SESSION_TICKET message that arrives later. */ if(gnutls_protocol_get_version(session) < GNUTLS_TLS1_3) result = cf_gtls_update_session_id(cf, data, session); +#endif out: return result; } +#ifdef CURL_GNUTLS_EARLY_DATA static CURLcode gtls_send_earlydata(struct Curl_cfilter *cf, struct Curl_easy *data) { @@ -1840,6 +1868,7 @@ static CURLcode gtls_send_earlydata(struct Curl_cfilter *cf, out: return result; } +#endif /* * This function is called after the TCP connect has completed. Setup the TLS @@ -1876,6 +1905,7 @@ static CURLcode gtls_connect_common(struct Curl_cfilter *cf, } if(connssl->connecting_state == ssl_connect_2) { +#ifdef CURL_GNUTLS_EARLY_DATA if(connssl->earlydata_state == ssl_earlydata_await) { goto out; } @@ -1887,7 +1917,7 @@ static CURLcode gtls_connect_common(struct Curl_cfilter *cf, } DEBUGASSERT((connssl->earlydata_state == ssl_earlydata_none) || (connssl->earlydata_state == ssl_earlydata_sent)); - +#endif result = handshake(cf, data); if(result) goto out; @@ -1918,6 +1948,7 @@ static CURLcode gtls_connect_common(struct Curl_cfilter *cf, if(result) goto out; +#ifdef CURL_GNUTLS_EARLY_DATA if(connssl->earlydata_state > ssl_earlydata_none) { /* We should be in this state by now */ DEBUGASSERT(connssl->earlydata_state == ssl_earlydata_sent); @@ -1926,6 +1957,7 @@ static CURLcode gtls_connect_common(struct Curl_cfilter *cf, GNUTLS_SFLAGS_EARLY_DATA) ? ssl_earlydata_accepted : ssl_earlydata_rejected; } +#endif connssl->connecting_state = ssl_connect_done; } @@ -1947,6 +1979,7 @@ static CURLcode gtls_connect(struct Curl_cfilter *cf, struct Curl_easy *data, bool *done) { +#ifdef CURL_GNUTLS_EARLY_DATA struct ssl_connect_data *connssl = cf->ctx; if((connssl->state == ssl_connection_deferred) && (connssl->earlydata_state == ssl_earlydata_await)) { @@ -1954,6 +1987,7 @@ static CURLcode gtls_connect(struct Curl_cfilter *cf, *done = TRUE; return CURLE_OK; } +#endif return gtls_connect_common(cf, data, done); } diff --git a/tests/http/testenv/env.py b/tests/http/testenv/env.py index 0e1ce389d5..ad1173a984 100644 --- a/tests/http/testenv/env.py +++ b/tests/http/testenv/env.py @@ -464,7 +464,9 @@ class Env: @staticmethod def curl_can_early_data() -> bool: - return Env.curl_uses_any_libs(['gnutls', 'wolfssl', 'quictls', 'openssl']) + if Env.curl_uses_lib('gnutls'): + return Env.curl_lib_version_at_least('gnutls', '3.6.13') + return Env.curl_uses_any_libs(['wolfssl', 'quictls', 'openssl']) @staticmethod def curl_can_h3_early_data() -> bool: