From: William Lallemand Date: Tue, 30 Jun 2026 12:39:50 +0000 (+0000) Subject: MEDIUM: ssl: add FIPS TLS 1.2 cipher check for AWS-LC X-Git-Url: http://git.kaiwu.me/postgresql/log/contrib/postgres_fdw/postgres_fdw.c?a=commitdiff_plain;h=4c420b57341e949afb22bd81bc75cb028ee3e15e;p=haproxy.git 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. --- diff --git a/include/haproxy/fips.h b/include/haproxy/fips.h index 5b6dcee2b..7cb70dcf6 100644 --- a/include/haproxy/fips.h +++ b/include/haproxy/fips.h @@ -8,6 +8,7 @@ #include #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 diff --git a/src/fips.c b/src/fips.c index e24af8c42..4fafe972a 100644 --- a/src/fips.c +++ b/src/fips.c @@ -10,6 +10,13 @@ #include #include +/* 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 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 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 is FIPS-compliant. */ int ssl_fips_check_version(int min_ver, const enum obj_type *obj) { diff --git a/src/ssl_sock.c b/src/ssl_sock.c index 47583ffa9..77f88e2d0 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -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);