MEDIUM: ssl: introduce src/fips.c with TLS version check

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.
This commit is contained in:
William Lallemand 2026-06-30 12:38:31 +00:00
parent 9d64d390c8
commit 557f083cda
4 changed files with 91 additions and 0 deletions

View file

@ -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.

15
include/haproxy/fips.h Normal file
View file

@ -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 */

65
src/fips.c Normal file
View file

@ -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;
}

View 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);