]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: ssl: Add traces to verify callback
authorRemi Tricot-Le Breton <rlebreton@haproxy.com>
Fri, 18 Apr 2025 15:26:54 +0000 (17:26 +0200)
committerWilliam Lallemand <wlallemand@haproxy.com>
Wed, 30 Apr 2025 09:11:26 +0000 (11:11 +0200)
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
src/ssl_sock.c
src/ssl_trace.c

index efd7dcbd784343ce98f72241e13b9e7b6e17f0c0..0678fb68d4b37439ba1ad22d511dd9bb8f95604b 100644 (file)
@@ -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
 
index 238d093c523211be625dd471f08a0c16f0409d91..7d29d70eb19977e4ae1b1ea83f71d91cb24583e8 100644 (file)
@@ -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;
 }
 
index 558e1088047ce019f111573c72a2eeb63c98d361..eaec5cf4c20989b38e1f982a23c15d7992d133b7 100644 (file)
@@ -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));
+                       }
+               }
+       }
 }