From 0fb05540b27f316f0ff16a05b412b555e9e6d03a Mon Sep 17 00:00:00 2001 From: Remi Tricot-Le Breton Date: Fri, 18 Apr 2025 17:26:54 +0200 Subject: [PATCH] MINOR: ssl: Add traces to verify callback Those traces allow to know which errors were met during certificate chain validation as well as which ones were ignored. --- include/haproxy/ssl_trace-t.h | 1 + src/ssl_sock.c | 22 +++++++++++++++++----- src/ssl_trace.c | 21 +++++++++++++++++++++ 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/include/haproxy/ssl_trace-t.h b/include/haproxy/ssl_trace-t.h index efd7dcbd7..0678fb68d 100644 --- a/include/haproxy/ssl_trace-t.h +++ b/include/haproxy/ssl_trace-t.h @@ -28,6 +28,7 @@ extern struct trace_source trace_ssl; #define SSL_EV_CONN_RECV_EARLY (1ULL << 7) #define SSL_EV_CONN_IO_CB (1ULL << 8) #define SSL_EV_CONN_HNDSHK (1ULL << 9) +#define SSL_EV_CONN_VFY_CB (1ULL << 10) #define TRACE_SOURCE &trace_ssl diff --git a/src/ssl_sock.c b/src/ssl_sock.c index 238d093c5..7d29d70eb 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -1471,6 +1471,7 @@ int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store) if (conn) { bind_conf = __objt_listener(conn->target)->bind_conf; ctx = __conn_get_ssl_sock_ctx(conn); + TRACE_ENTER(SSL_EV_CONN_VFY_CB, conn); } #ifdef USE_QUIC else { @@ -1488,8 +1489,10 @@ int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store) depth = X509_STORE_CTX_get_error_depth(x_store); err = X509_STORE_CTX_get_error(x_store); - if (ok) /* no errors */ + if (ok) { /* no errors */ + TRACE_LEAVE(SSL_EV_CONN_VFY_CB, conn); return ok; + } /* Keep a reference to the client's certificate in order to be able to * dump some fetches values in a log even when the verification process @@ -1526,12 +1529,16 @@ int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store) } if (err <= SSL_MAX_VFY_ERROR_CODE && - cert_ignerr_bitfield_get(bind_conf->ca_ignerr_bitfield, err)) + cert_ignerr_bitfield_get(bind_conf->ca_ignerr_bitfield, err)) { + TRACE_STATE("Ignored ca-related error", SSL_EV_CONN_VFY_CB, conn, ssl, NULL, &err); goto err_ignored; + } /* TODO: for QUIC connection, this error code is lost */ - if (conn) + if (conn) { conn->err_code = CO_ER_SSL_CA_FAIL; + TRACE_ERROR("Verify callback error (ca)", SSL_EV_CONN_VFY_CB|SSL_EV_CONN_ERR, conn, ssl, &conn->err_code, &err); + } return 0; } @@ -1540,17 +1547,22 @@ int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store) /* check if certificate error needs to be ignored */ if (err <= SSL_MAX_VFY_ERROR_CODE && - cert_ignerr_bitfield_get(bind_conf->crt_ignerr_bitfield, err)) + cert_ignerr_bitfield_get(bind_conf->crt_ignerr_bitfield, err)) { + TRACE_STATE("Ignored crt-related error", SSL_EV_CONN_VFY_CB, conn, ssl, NULL, &err); goto err_ignored; + } /* TODO: for QUIC connection, this error code is lost */ - if (conn) + if (conn) { conn->err_code = CO_ER_SSL_CRT_FAIL; + TRACE_ERROR("Verify callback error (crt)", SSL_EV_CONN_VFY_CB|SSL_EV_CONN_ERR, conn, ssl, &conn->err_code, &err); + } return 0; err_ignored: ssl_sock_dump_errors(conn, qc); ERR_clear_error(); + TRACE_LEAVE(SSL_EV_CONN_VFY_CB, conn); return 1; } diff --git a/src/ssl_trace.c b/src/ssl_trace.c index 558e10880..eaec5cf4c 100644 --- a/src/ssl_trace.c +++ b/src/ssl_trace.c @@ -36,6 +36,7 @@ static const struct trace_event ssl_trace_events[] = { { .mask = SSL_EV_CONN_RECV_EARLY, .name = "sslc_recv_early", .desc = "Rx on SSL connection (early data)" }, { .mask = SSL_EV_CONN_IO_CB, .name = "sslc_io_cb", .desc = "SSL io callback"}, { .mask = SSL_EV_CONN_HNDSHK, .name = "sslc_hndshk", .desc = "SSL handshake"}, + { .mask = SSL_EV_CONN_VFY_CB, .name = "sslc_vfy_cb", .desc = "SSL verify callback"}, { } }; @@ -159,5 +160,25 @@ static void ssl_trace(enum trace_level level, uint64_t mask, const struct trace_ } } + if (mask & SSL_EV_CONN_VFY_CB) { + if (mask & SSL_EV_CONN_ERR) { + if (a3) { + const unsigned int *err_code = a3; + chunk_appendf(&trace_buf, " err_code=%u err_str=\"%s\"", *err_code, conn_err_code_str(conn)); + } + if (a4) { + const unsigned int *ssl_err_code = a4; + chunk_appendf(&trace_buf, " ssl_err_code=%u ssl_err_str=\"%s\"", *ssl_err_code, + ERR_reason_error_string(*ssl_err_code)); + } + } else if (src->verbosity > SSL_VERB_SIMPLE) { + /* We faced an ignored error */ + if (a4) { + const unsigned int *ssl_err_code = a4; + chunk_appendf(&trace_buf, " ssl_err_code=%u ssl_err_str=\"%s\"", *ssl_err_code, + ERR_reason_error_string(*ssl_err_code)); + } + } + } }