]> git.kaiwu.me - haproxy.git/commitdiff
MEDIUM: ssl: introduce src/fips.c with TLS version check
authorWilliam Lallemand <wlallemand@haproxy.com>
Tue, 30 Jun 2026 12:38:31 +0000 (12:38 +0000)
committerWilliam Lallemand <wlallemand@haproxy.com>
Tue, 30 Jun 2026 13:54:52 +0000 (13:54 +0000)
Add src/fips.c and include/haproxy/fips.h to centralise FIPS compliance
checks for AWS-LC builds.

ssl_fips_check_version() verifies that ssl-min-ver is not set below
TLS 1.2, which AWS-LC in FIPS mode would refuse to negotiate.

The check accepts an enum obj_type * so it can resolve the owning
bind/server and produce a precise error message including the proxy
and object name in the standard HAProxy 'type proxy/name' form.

Makefile
include/haproxy/fips.h [new file with mode: 0644]
src/fips.c [new file with mode: 0644]
src/ssl_sock.c

index 95c11bbad9dc2fb653a3532fbe86fa6a4bc0327b..3c00af8d5d5b7abb0f5cbeed00416cab4c79a783 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -629,6 +629,7 @@ endif
 ifneq ($(USE_OPENSSL_AWSLC:0=),)
   # always automatically set USE_OPENSSL
   USE_OPENSSL     := $(if $(USE_OPENSSL:0=),$(USE_OPENSSL:0=),implicit)
+  OPTIONS_OBJS   += src/fips.o
 endif
 
 # This is for any variant of the OpenSSL API. By default it uses OpenSSL.
diff --git a/include/haproxy/fips.h b/include/haproxy/fips.h
new file mode 100644 (file)
index 0000000..5b6dcee
--- /dev/null
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#ifndef _HAPROXY_FIPS_H
+#define _HAPROXY_FIPS_H
+
+#ifdef USE_OPENSSL
+#include <haproxy/obj_type-t.h>
+#include <haproxy/openssl-compat.h>
+
+#if defined(OPENSSL_IS_AWSLC)
+int ssl_fips_check_version(int min_ver, const enum obj_type *obj);
+#endif
+
+#endif /* USE_OPENSSL */
+#endif /* _HAPROXY_FIPS_H */
diff --git a/src/fips.c b/src/fips.c
new file mode 100644 (file)
index 0000000..e24af8c
--- /dev/null
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/* FIPS compliance checks for AWS-LC builds */
+
+#include <stdlib.h>
+
+#include <haproxy/errors.h>
+#include <haproxy/obj_type.h>
+#include <haproxy/openssl-compat.h>
+#include <haproxy/ssl_sock-t.h>
+#include <haproxy/tools.h>
+
+/* Fill display fields from <obj> for use in error messages. */
+static void fips_obj_info(const enum obj_type *obj,
+                          const char **proxy_name, const char **type_str,
+                          const char **obj_name,
+                          const char **file, int *line)
+{
+       switch (obj_type(obj)) {
+       case OBJ_TYPE_SERVER: {
+               struct server *s = objt_server((enum obj_type *)obj);
+               *proxy_name = s->proxy->id ? s->proxy->id : "-";
+               *type_str   = "server";
+               *obj_name   = s->id ? s->id : "-";
+               *file       = s->conf.file;
+               *line       = s->conf.line;
+               break;
+       }
+       case OBJ_TYPE_LISTENER: {
+               struct listener *li = objt_listener((enum obj_type *)obj);
+               *proxy_name = li->bind_conf->frontend->id ? li->bind_conf->frontend->id : "-";
+               *type_str   = "bind";
+               *obj_name   = li->bind_conf->arg ? li->bind_conf->arg : "-";
+               *file       = li->bind_conf->file;
+               *line       = li->bind_conf->line;
+               break;
+       }
+       default:
+               *proxy_name = *type_str = *obj_name = *file = NULL;
+               *line = 0;
+               break;
+       }
+}
+
+/* Check that the minimum TLS version <min_ver> is FIPS-compliant. */
+int ssl_fips_check_version(int min_ver, const enum obj_type *obj)
+{
+       const char *proxy_name, *type_str, *obj_name, *file;
+       int line;
+
+       if (!FIPS_mode())
+               return 0;
+
+       if (min_ver && min_ver < CONF_TLSV12) {
+               fips_obj_info(obj, &proxy_name, &type_str, &obj_name, &file, &line);
+               if (file)
+                       ha_alert("[%s:%d] %s '%s/%s': FIPS mode active but ssl-min-ver is set below TLS 1.2.\n",
+                                file, line, type_str, proxy_name, obj_name);
+               else
+                       ha_alert("%s '%s/%s': FIPS mode active but ssl-min-ver is set below TLS 1.2.\n",
+                                type_str, proxy_name, obj_name);
+               return ERR_ALERT | ERR_ABORT | ERR_FATAL;
+       }
+       return 0;
+}
index 5e5329a22474b9b2ab55f35a79fefd0f46539aee..47583ffa9b0b1ede68b9680a9940ab95362ece38 100644 (file)
@@ -74,6 +74,7 @@
 #include <haproxy/shctx.h>
 #include <haproxy/ssl_ckch.h>
 #include <haproxy/ssl_crtlist.h>
+#include <haproxy/fips.h>
 #include <haproxy/ssl_gencert.h>
 #include <haproxy/ssl_sock.h>
 #include <haproxy/ssl_utils.h>
@@ -4042,6 +4043,11 @@ ssl_sock_initial_ctx(struct bind_conf *bind_conf)
        min = conf_ssl_methods->min;
        max = conf_ssl_methods->max;
 
+#if defined(OPENSSL_IS_AWSLC)
+       cfgerr += !!ssl_fips_check_version(min,
+                                          &LIST_ELEM(bind_conf->listeners.n, struct listener *, by_bind)->obj_type);
+#endif
+
        /* default minimum is TLSV12,  */
        if (!min) {
                if (!max || (max >= default_min_ver)) {
@@ -5117,6 +5123,10 @@ static int ssl_sock_prepare_srv_ssl_ctx(const struct server *srv, SSL_CTX *ctx)
        else
                flags = conf_ssl_methods->flags;
 
+#if defined(OPENSSL_IS_AWSLC)
+       cfgerr += !!ssl_fips_check_version(conf_ssl_methods->min, &srv->obj_type);
+#endif
+
        /* Real min and max should be determinate with configuration and openssl's capabilities */
        if (conf_ssl_methods->min)
                flags |= (methodVersions[conf_ssl_methods->min].flag - 1);