MEDIUM: ssl: add FIPS signature algorithm check for AWS-LC

Add ssl_fips_check_sigalgs() which validates the configured signature
algorithm list against the FIPS-approved set: ECDSA on NIST P-curves
with SHA-256/384/512, RSA-PSS (rsae and pss variants) with SHA-256/
384/512, and RSA-PKCS1 with SHA-256/384/512.  SHA-1 based algorithms
and non-FIPS primitives (ed25519, ed448) are rejected.

The check uses the same strchr-based string parsing as
ssl_fips_check_ciphersuites().  A NULL list is silently accepted since
the global defaults were already overwritten with FIPS values at init
time.

The check is called right after SSL_CTX_set1_sigalgs_list() and
SSL_CTX_set1_client_sigalgs_list() in both the bind
(ssl_sock_prepare_ctx) and server (ssl_sock_prepare_srv_ssl_ctx)
configuration paths.
This commit is contained in:
William Lallemand 2026-06-30 13:39:14 +00:00
parent 1aee4ccd25
commit e411ea32a4
3 changed files with 74 additions and 0 deletions

View file

@ -11,6 +11,7 @@
int ssl_fips_check_ciphers(SSL_CTX *ctx, const enum obj_type *obj);
int ssl_fips_check_ciphersuites(const char *ciphersuites, const enum obj_type *obj);
int ssl_fips_check_curves(const char *curves, const enum obj_type *obj);
int ssl_fips_check_sigalgs(const char *sigalgs, const enum obj_type *obj);
int ssl_fips_check_version(int min_ver, const enum obj_type *obj);
#endif

View file

@ -27,6 +27,23 @@ static const int fips_approved_curve_nids[] = {
NID_undef
};
/* FIPS-approved signature algorithm names. NULL terminates the list. */
static const char *fips_approved_sigalgs[] = {
"ecdsa_secp256r1_sha256",
"ecdsa_secp384r1_sha384",
"ecdsa_secp521r1_sha512",
"rsa_pss_rsae_sha256",
"rsa_pss_rsae_sha384",
"rsa_pss_rsae_sha512",
"rsa_pss_pss_sha256",
"rsa_pss_pss_sha384",
"rsa_pss_pss_sha512",
"rsa_pkcs1_sha256",
"rsa_pkcs1_sha384",
"rsa_pkcs1_sha512",
NULL
};
/* FIPS-approved TLS 1.3 ciphersuite names. NULL terminates the list. */
static const char *fips_approved_ciphersuites[] = {
"TLS_AES_128_GCM_SHA256",
@ -66,6 +83,48 @@ static void fips_obj_info(const enum obj_type *obj,
}
}
/* Check that the signature algorithm list <sigalgs> is FIPS-compliant. */
int ssl_fips_check_sigalgs(const char *sigalgs, const enum obj_type *obj)
{
const char *proxy_name, *type_str, *obj_name, *file;
const char *p, *end;
char *list = NULL;
int i, line;
size_t len;
if (!FIPS_mode() || !sigalgs)
return 0;
p = sigalgs;
while (p && *p) {
end = strchr(p, ':');
len = end ? (size_t)(end - p) : strlen(p);
for (i = 0; fips_approved_sigalgs[i]; i++) {
if (strlen(fips_approved_sigalgs[i]) == len &&
strncmp(p, fips_approved_sigalgs[i], len) == 0)
goto next;
}
memprintf(&list, "%s%s'%.*s'", list ? list : "",
list ? ", " : "", (int)len, p);
next:
p = end ? end + 1 : NULL;
}
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 signature algorithm(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 signature algorithm(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 TLS 1.3 ciphersuite list <ciphersuites> is FIPS-compliant. */
int ssl_fips_check_ciphersuites(const char *ciphersuites, const enum obj_type *obj)
{

View file

@ -4839,6 +4839,10 @@ static int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, struct ssl_bind_con
cfgerr |= ERR_ALERT | ERR_FATAL;
}
}
#if defined(OPENSSL_IS_AWSLC)
cfgerr |= ssl_fips_check_sigalgs(conf_sigalgs,
&LIST_ELEM(bind_conf->listeners.n, struct listener *, by_bind)->obj_type);
#endif
#endif
#if defined(SSL_CTX_set1_client_sigalgs_list)
@ -4850,6 +4854,10 @@ static int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, struct ssl_bind_con
cfgerr |= ERR_ALERT | ERR_FATAL;
}
}
#if defined(OPENSSL_IS_AWSLC)
cfgerr |= ssl_fips_check_sigalgs(conf_client_sigalgs,
&LIST_ELEM(bind_conf->listeners.n, struct listener *, by_bind)->obj_type);
#endif
#endif
#ifdef USE_QUIC_OPENSSL_COMPAT
@ -5313,6 +5321,9 @@ static int ssl_sock_prepare_srv_ssl_ctx(const struct server *srv, SSL_CTX *ctx)
cfgerr++;
}
}
#if defined(OPENSSL_IS_AWSLC)
cfgerr += !!ssl_fips_check_sigalgs(conf_sigalgs, &srv->obj_type);
#endif
#endif
#if defined(SSL_CTX_set1_client_sigalgs_list)
conf_client_sigalgs = srv->ssl_ctx.client_sigalgs;
@ -5323,6 +5334,9 @@ static int ssl_sock_prepare_srv_ssl_ctx(const struct server *srv, SSL_CTX *ctx)
cfgerr++;
}
}
#if defined(OPENSSL_IS_AWSLC)
cfgerr += !!ssl_fips_check_sigalgs(conf_client_sigalgs, &srv->obj_type);
#endif
#endif
#if defined(SSL_CTX_set1_curves_list)