From: Remi Tricot-Le Breton Date: Tue, 15 Jul 2025 08:45:07 +0000 (+0200) Subject: MINOR: ssl: Add ciphers in ssl traces X-Git-Tag: v3.3-dev4~58 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f00d9bf12d9613b7a8910f383cf643a94083423e;p=thirdparty%2Fhaproxy.git MINOR: ssl: Add ciphers in ssl traces Decode the contents of the ClientHello ciphers extension and dump a human readable list in the ssl traces. --- diff --git a/include/haproxy/ssl_trace.h b/include/haproxy/ssl_trace.h index cd22ffc47..c7ffd5a52 100644 --- a/include/haproxy/ssl_trace.h +++ b/include/haproxy/ssl_trace.h @@ -22,6 +22,14 @@ extern struct trace_source trace_ssl; #define SSL_EV_CONN_SWITCHCTX_CB (1ULL << 12) #define SSL_EV_CONN_CHOOSE_SNI_CTX (1ULL << 13) #define SSL_EV_CONN_SIGALG_EXT (1ULL << 14) +#define SSL_EV_CONN_CIPHERS_EXT (1ULL << 15) + + +#define SSL_VERB_CLEAN 1 +#define SSL_VERB_MINIMAL 2 +#define SSL_VERB_SIMPLE 3 +#define SSL_VERB_ADVANCED 4 +#define SSL_VERB_COMPLETE 5 #define TRACE_SOURCE &trace_ssl diff --git a/src/ssl_clienthello.c b/src/ssl_clienthello.c index 9f7ec16d9..daa950626 100644 --- a/src/ssl_clienthello.c +++ b/src/ssl_clienthello.c @@ -345,6 +345,21 @@ int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg) TRACE_DEVEL("Sigalg parsing: has_rsa_sig (default)", SSL_EV_CONN_SWITCHCTX_CB, conn); has_rsa_sig = 1; } + + if ((TRACE_SOURCE)->verbosity > SSL_VERB_ADVANCED && + TRACE_ENABLED(TRACE_LEVEL_DATA, SSL_EV_CONN_CIPHERS_EXT, conn, 0, 0, 0)) { + const uint8_t *cipher_suites; + size_t len; + +#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC) + len = ctx->cipher_suites_len; + cipher_suites = ctx->cipher_suites; +#else + len = SSL_client_hello_get0_ciphers(ssl, &cipher_suites); +#endif + TRACE_DATA("Ciphers value", SSL_EV_CONN_CIPHERS_EXT, conn, ssl, cipher_suites, &len); + } + if (has_ecdsa_sig) { /* in very rare case: has ecdsa sign but not a ECDSA cipher */ const SSL_CIPHER *cipher; STACK_OF(SSL_CIPHER) *ha_ciphers; /* haproxy side ciphers */ diff --git a/src/ssl_trace.c b/src/ssl_trace.c index 47332b5d9..6a1a8a966 100644 --- a/src/ssl_trace.c +++ b/src/ssl_trace.c @@ -41,6 +41,7 @@ static const struct trace_event ssl_trace_events[] = { { .mask = SSL_EV_CONN_SWITCHCTX_CB, .name = "sslc_switchctx_cb", .desc = "SSL switchctx callback"}, { .mask = SSL_EV_CONN_CHOOSE_SNI_CTX, .name = "sslc_choose_sni_ctx", .desc = "SSL choose sni context"}, { .mask = SSL_EV_CONN_SIGALG_EXT, .name = "sslc_sigalg_ext", .desc = "SSL sigalg extension parsing"}, + { .mask = SSL_EV_CONN_CIPHERS_EXT, .name = "sslc_ciphers_ext", .desc = "SSL ciphers extension parsing"}, { } }; @@ -53,15 +54,10 @@ static const struct name_desc ssl_trace_lockon_args[4] = { }; static const struct name_desc ssl_trace_decoding[] = { -#define SSL_VERB_CLEAN 1 { .name="clean", .desc="only user-friendly stuff, generally suitable for level \"user\"" }, -#define SSL_VERB_MINIMAL 2 { .name="minimal", .desc="report only conn, no real decoding" }, -#define SSL_VERB_SIMPLE 3 { .name="simple", .desc="add error messages" }, -#define SSL_VERB_ADVANCED 4 { .name="advanced", .desc="add handshake-related details" }, -#define SSL_VERB_COMPLETE 5 { .name="complete", .desc="add full data dump when available" }, { /* end */ } }; @@ -247,5 +243,37 @@ static void ssl_trace(enum trace_level level, uint64_t mask, const struct trace_ } } } + + if (mask & SSL_EV_CONN_CIPHERS_EXT && src->verbosity > SSL_VERB_ADVANCED) { + if (a2 && a3 && a4) { + SSL *ssl = (SSL*)a2; + const uint16_t *extension_data = a3; + size_t extension_len = *((size_t*)a4); + int first = 1; + + chunk_appendf(&trace_buf, " value="); + + while (extension_len > 1) { + const char *str; + const SSL_CIPHER *cipher; + uint16_t id = ntohs(*extension_data); +#if defined(OPENSSL_IS_BORINGSSL) + cipher = SSL_get_cipher_by_value(id); +#else + cipher = SSL_CIPHER_find(ssl, (unsigned char*)extension_data); +#endif + str = SSL_CIPHER_get_name(cipher); + if (!str || strcmp(str, "(NONE)") == 0) + chunk_appendf(&trace_buf, "%sUNKNOWN(%04x)", first ? "" : ",", id); + else + chunk_appendf(&trace_buf, "%s%s", first ? "" : ",", str); + + first = 0; + + extension_len-=sizeof(*extension_data); + ++extension_data; + } + } + } }