mirror of
https://github.com/haproxy/haproxy.git
synced 2026-07-15 03:56:56 -04:00
MEDIUM: ssl: add FIPS TLS 1.2 cipher check for AWS-LC
Add ssl_fips_check_ciphers() to check the cipher list already loaded into an SSL_CTX against the FIPS-approved bulk cipher NID allowlist (AES-128-GCM, AES-256-GCM). The check is run unconditionally after SSL_CTX_set_cipher_list() for both bind and server contexts. The function reuses the fips_obj_info() helper introduced with the version check to emit precise 'type proxy/name [file:line]' error messages and returns ERR_ALERT|ERR_ABORT|ERR_FATAL on violation.
This commit is contained in:
parent
557f083cda
commit
4c420b5734
3 changed files with 60 additions and 0 deletions
|
|
@ -8,6 +8,7 @@
|
|||
#include <haproxy/openssl-compat.h>
|
||||
|
||||
#if defined(OPENSSL_IS_AWSLC)
|
||||
int ssl_fips_check_ciphers(SSL_CTX *ctx, const enum obj_type *obj);
|
||||
int ssl_fips_check_version(int min_ver, const enum obj_type *obj);
|
||||
#endif
|
||||
|
||||
|
|
|
|||
50
src/fips.c
50
src/fips.c
|
|
@ -10,6 +10,13 @@
|
|||
#include <haproxy/ssl_sock-t.h>
|
||||
#include <haproxy/tools.h>
|
||||
|
||||
/* FIPS-approved bulk cipher NIDs (TLS 1.2). NID_undef terminates the list. */
|
||||
static const int fips_approved_cipher_nids[] = {
|
||||
NID_aes_128_gcm,
|
||||
NID_aes_256_gcm,
|
||||
NID_undef
|
||||
};
|
||||
|
||||
/* 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,
|
||||
|
|
@ -42,6 +49,49 @@ static void fips_obj_info(const enum obj_type *obj,
|
|||
}
|
||||
}
|
||||
|
||||
/* Check that the TLS 1.2 cipher list configured on <ctx> is FIPS-compliant. */
|
||||
int ssl_fips_check_ciphers(SSL_CTX *ctx, const enum obj_type *obj)
|
||||
{
|
||||
const char *proxy_name, *type_str, *obj_name, *file;
|
||||
STACK_OF(SSL_CIPHER) *cipher_list;
|
||||
const SSL_CIPHER *cipher;
|
||||
int i, j, cipher_nid, line;
|
||||
char *list = NULL;
|
||||
|
||||
if (!FIPS_mode())
|
||||
return 0;
|
||||
|
||||
cipher_list = SSL_CTX_get_ciphers(ctx);
|
||||
if (!cipher_list)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < sk_SSL_CIPHER_num(cipher_list); i++) {
|
||||
cipher = sk_SSL_CIPHER_value(cipher_list, i);
|
||||
cipher_nid = SSL_CIPHER_get_cipher_nid(cipher);
|
||||
|
||||
for (j = 0; fips_approved_cipher_nids[j] != NID_undef; j++) {
|
||||
if (cipher_nid == fips_approved_cipher_nids[j])
|
||||
goto next;
|
||||
}
|
||||
memprintf(&list, "%s%s'%s'", list ? list : "",
|
||||
list ? ", " : "", SSL_CIPHER_get_name(cipher));
|
||||
next:;
|
||||
}
|
||||
|
||||
if (list) {
|
||||
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 non-FIPS cipher(s) configured: %s.\n",
|
||||
file, line, type_str, proxy_name, obj_name, list);
|
||||
else
|
||||
ha_alert("%s '%s/%s': FIPS mode active but non-FIPS cipher(s) configured: %s.\n",
|
||||
type_str, proxy_name, obj_name, list);
|
||||
free(list);
|
||||
return ERR_ALERT | ERR_ABORT | ERR_FATAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check that the minimum TLS version <min_ver> is FIPS-compliant. */
|
||||
int ssl_fips_check_version(int min_ver, const enum obj_type *obj)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4732,6 +4732,11 @@ static int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, struct ssl_bind_con
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_IS_AWSLC)
|
||||
cfgerr |= ssl_fips_check_ciphers(ctx,
|
||||
&LIST_ELEM(bind_conf->listeners.n, struct listener *, by_bind)->obj_type);
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_DH
|
||||
if (!local_dh_1024)
|
||||
local_dh_1024 = ssl_get_dh_1024();
|
||||
|
|
@ -5275,6 +5280,10 @@ static int ssl_sock_prepare_srv_ssl_ctx(const struct server *srv, SSL_CTX *ctx)
|
|||
cfgerr++;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_IS_AWSLC)
|
||||
cfgerr += !!ssl_fips_check_ciphers(ctx, &srv->obj_type);
|
||||
#endif
|
||||
#if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
|
||||
if (srv->ssl_ctx.npn_str)
|
||||
SSL_CTX_set_next_proto_select_cb(ctx, ssl_sock_srv_select_protos, (struct server*)srv);
|
||||
|
|
|
|||
Loading…
Reference in a new issue