From: Stefan Eissing Date: Mon, 14 Jul 2025 07:33:53 +0000 (+0200) Subject: http/3: report handshake with version and cipher as for TCP connections X-Git-Tag: curl-8_15_0~19 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=674ad27f7738b726edce0ab2b3c664dbf84d5837;p=thirdparty%2Fcurl.git http/3: report handshake with version and cipher as for TCP connections Make reporting into separate functions, to be called from QUIC handshakes as well. Closes #17922 --- diff --git a/lib/vquic/curl_ngtcp2.c b/lib/vquic/curl_ngtcp2.c index 8d99e02211..69d54ecce2 100644 --- a/lib/vquic/curl_ngtcp2.c +++ b/lib/vquic/curl_ngtcp2.c @@ -468,6 +468,7 @@ static int cf_ngtcp2_handshake_completed(ngtcp2_conn *tconn, void *user_data) ctx->handshake_at = curlx_now(); ctx->tls_handshake_complete = TRUE; cf->conn->bits.multiplex = TRUE; /* at least potentially multiplexed */ + Curl_vquic_report_handshake(&ctx->tls, cf, data); ctx->tls_vrfy_result = Curl_vquic_tls_verify_peer(&ctx->tls, cf, data, &ctx->peer); diff --git a/lib/vquic/vquic-tls.c b/lib/vquic/vquic-tls.c index e6160b3902..8a53c83b33 100644 --- a/lib/vquic/vquic-tls.c +++ b/lib/vquic/vquic-tls.c @@ -221,4 +221,22 @@ bool Curl_vquic_tls_get_ssl_info(struct curl_tls_ctx *ctx, #endif } +void Curl_vquic_report_handshake(struct curl_tls_ctx *ctx, + struct Curl_cfilter *cf, + struct Curl_easy *data) +{ + (void)cf; +#ifdef USE_OPENSSL + (void)cf; + Curl_ossl_report_handshake(data, &ctx->ossl); +#elif defined(USE_GNUTLS) + Curl_gtls_report_handshake(data, &ctx->gtls); +#elif defined(USE_WOLFSSL) + Curl_wssl_report_handshake(data, &ctx->wssl); +#else + (void)data; + (void)ctx; +#endif +} + #endif /* !USE_HTTP3 && (USE_OPENSSL || USE_GNUTLS || USE_WOLFSSL) */ diff --git a/lib/vquic/vquic-tls.h b/lib/vquic/vquic-tls.h index 49b923a4e4..c694e23e4e 100644 --- a/lib/vquic/vquic-tls.h +++ b/lib/vquic/vquic-tls.h @@ -111,6 +111,10 @@ bool Curl_vquic_tls_get_ssl_info(struct curl_tls_ctx *ctx, bool give_ssl_ctx, struct curl_tlssessioninfo *info); +void Curl_vquic_report_handshake(struct curl_tls_ctx *ctx, + struct Curl_cfilter *cf, + struct Curl_easy *data); + #endif /* !USE_HTTP3 && (USE_OPENSSL || USE_GNUTLS || USE_WOLFSSL) */ #endif /* HEADER_CURL_VQUIC_TLS_H */ diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c index d1f5f62117..f5e02975a0 100644 --- a/lib/vtls/gtls.c +++ b/lib/vtls/gtls.c @@ -1307,6 +1307,28 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, return result; } +void Curl_gtls_report_handshake(struct Curl_easy *data, + struct gtls_ctx *gctx) +{ +#ifndef CURL_DISABLE_VERBOSE_STRINGS + if(Curl_trc_is_verbose(data)) { + const char *ptr; + gnutls_protocol_t version = gnutls_protocol_get_version(gctx->session); + + /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */ + ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(gctx->session), + gnutls_cipher_get(gctx->session), + gnutls_mac_get(gctx->session)); + + infof(data, "SSL connection using %s / %s", + gnutls_protocol_get_name(version), ptr); + } +#else + (void)data; + (void)gctx; +#endif +} + CURLcode Curl_gtls_verifyserver(struct Curl_easy *data, gnutls_session_t session, @@ -1327,23 +1349,11 @@ Curl_gtls_verifyserver(struct Curl_easy *data, int rc; CURLcode result = CURLE_OK; #ifndef CURL_DISABLE_VERBOSE_STRINGS - const char *ptr; int algo; unsigned int bits; - gnutls_protocol_t version = gnutls_protocol_get_version(session); #endif long * const certverifyresult = &ssl_config->certverifyresult; -#ifndef CURL_DISABLE_VERBOSE_STRINGS - /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */ - ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session), - gnutls_cipher_get(session), - gnutls_mac_get(session)); - - infof(data, "SSL connection using %s / %s", - gnutls_protocol_get_name(version), ptr); -#endif - /* This function will return the peer's raw certificate (chain) as sent by the peer. These certificates are in raw format (DER encoded for X.509). In case of a X.509 then a certificate list may be present. The @@ -1876,6 +1886,9 @@ static CURLcode gtls_connect_common(struct Curl_cfilter *cf, if(connssl->connecting_state == ssl_connect_3) { gnutls_datum_t proto; int rc; + + Curl_gtls_report_handshake(data, &backend->gtls); + result = gtls_verifyserver(cf, data, backend->gtls.session); if(result) goto out; diff --git a/lib/vtls/gtls.h b/lib/vtls/gtls.h index 35af9db139..01f8b43ac8 100644 --- a/lib/vtls/gtls.h +++ b/lib/vtls/gtls.h @@ -117,6 +117,10 @@ CURLcode Curl_gtls_cache_session(struct Curl_cfilter *cf, unsigned char *quic_tp, size_t quic_tp_len); +/* Report properties of a successful handshake */ +void Curl_gtls_report_handshake(struct Curl_easy *data, + struct gtls_ctx *gctx); + extern const struct Curl_ssl Curl_ssl_gnutls; #endif /* USE_GNUTLS */ diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c index 3b23149c73..08e15e289a 100644 --- a/lib/vtls/openssl.c +++ b/lib/vtls/openssl.c @@ -4334,6 +4334,38 @@ static CURLcode ossl_on_session_reuse(struct Curl_cfilter *cf, return result; } +void Curl_ossl_report_handshake(struct Curl_easy *data, + struct ossl_ctx *octx) +{ +#ifndef CURL_DISABLE_VERBOSE_STRINGS + if(Curl_trc_is_verbose(data)) { + int psigtype_nid = NID_undef; + const char *negotiated_group_name = NULL; + +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + SSL_get_peer_signature_type_nid(octx->ssl, &psigtype_nid); +#if (OPENSSL_VERSION_NUMBER >= 0x30200000L) + negotiated_group_name = SSL_get0_group_name(octx->ssl); +#else + negotiated_group_name = + OBJ_nid2sn(SSL_get_negotiated_group(octx->ssl) & 0x0000FFFF); +#endif +#endif + + /* Informational message */ + infof(data, "SSL connection using %s / %s / %s / %s", + SSL_get_version(octx->ssl), + SSL_get_cipher(octx->ssl), + negotiated_group_name ? negotiated_group_name : "[blank]", + OBJ_nid2sn(psigtype_nid)); + } +#else + (void)data; + (void)octx; +#endif /* CURL_DISABLE_VERBOSE_STRINGS */ + +} + static CURLcode ossl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) { @@ -4599,28 +4631,9 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf, } } else { - int psigtype_nid = NID_undef; - const char *negotiated_group_name = NULL; - /* we connected fine, we are not waiting for anything else. */ connssl->connecting_state = ssl_connect_3; - -#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) - SSL_get_peer_signature_type_nid(octx->ssl, &psigtype_nid); -#if (OPENSSL_VERSION_NUMBER >= 0x30200000L) - negotiated_group_name = SSL_get0_group_name(octx->ssl); -#else - negotiated_group_name = - OBJ_nid2sn(SSL_get_negotiated_group(octx->ssl) & 0x0000FFFF); -#endif -#endif - - /* Informational message */ - infof(data, "SSL connection using %s / %s / %s / %s", - SSL_get_version(octx->ssl), - SSL_get_cipher(octx->ssl), - negotiated_group_name ? negotiated_group_name : "[blank]", - OBJ_nid2sn(psigtype_nid)); + Curl_ossl_report_handshake(data, octx); #ifdef USE_ECH_OPENSSL # if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC) @@ -4677,10 +4690,10 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf, infof(data, "ECH: ech-hard failed"); return CURLE_SSL_CONNECT_ERROR; } - } - else { + } + else { infof(data, "ECH: result: status is not attempted"); - } + } # endif /* !OPENSSL_IS_BORINGSSL && !OPENSSL_IS_AWSLC */ #endif /* USE_ECH_OPENSSL */ diff --git a/lib/vtls/openssl.h b/lib/vtls/openssl.h index 8d063e25ac..1338eafb58 100644 --- a/lib/vtls/openssl.h +++ b/lib/vtls/openssl.h @@ -142,5 +142,9 @@ CURLcode Curl_oss_check_peer_cert(struct Curl_cfilter *cf, struct ossl_ctx *octx, struct ssl_peer *peer); +/* Report properties of a successful handshake */ +void Curl_ossl_report_handshake(struct Curl_easy *data, + struct ossl_ctx *octx); + #endif /* USE_OPENSSL */ #endif /* HEADER_CURL_SSLUSE_H */ diff --git a/lib/vtls/wolfssl.c b/lib/vtls/wolfssl.c index 2ef3d250e6..8005fa3f59 100644 --- a/lib/vtls/wolfssl.c +++ b/lib/vtls/wolfssl.c @@ -2087,6 +2087,18 @@ static bool wssl_data_pending(struct Curl_cfilter *cf, return FALSE; } +void Curl_wssl_report_handshake(struct Curl_easy *data, + struct wssl_ctx *wssl) +{ +#if (LIBWOLFSSL_VERSION_HEX >= 0x03009010) + infof(data, "SSL connection using %s / %s", + wolfSSL_get_version(wssl->ssl), + wolfSSL_get_cipher_name(wssl->ssl)); +#else + infof(data, "SSL connected"); +#endif +} + static CURLcode wssl_connect(struct Curl_cfilter *cf, struct Curl_easy *data, bool *done) @@ -2160,16 +2172,9 @@ static CURLcode wssl_connect(struct Curl_cfilter *cf, } #endif /* HAVE_ALPN */ -#if (LIBWOLFSSL_VERSION_HEX >= 0x03009010) - infof(data, "SSL connection using %s / %s", - wolfSSL_get_version(wssl->ssl), - wolfSSL_get_cipher_name(wssl->ssl)); -#else - infof(data, "SSL connected"); -#endif - connssl->connecting_state = ssl_connect_done; connssl->state = ssl_connection_complete; + Curl_wssl_report_handshake(data, wssl); #ifdef WOLFSSL_EARLY_DATA if(connssl->earlydata_state > ssl_earlydata_none) { diff --git a/lib/vtls/wolfssl.h b/lib/vtls/wolfssl.h index 0ddbee9ed9..19ca609c84 100644 --- a/lib/vtls/wolfssl.h +++ b/lib/vtls/wolfssl.h @@ -88,6 +88,8 @@ CURLcode Curl_wssl_verify_pinned(struct Curl_cfilter *cf, struct Curl_easy *data, struct wssl_ctx *wssl); +void Curl_wssl_report_handshake(struct Curl_easy *data, + struct wssl_ctx *wssl); #endif /* USE_WOLFSSL */ #endif /* HEADER_CURL_WOLFSSL_H */