mirror of
https://github.com/haproxy/haproxy.git
synced 2026-07-14 19:43:29 -04:00
MEDIUM: ssl: add FIPS TLS 1.3 ciphersuite check for AWS-LC
AWS-LC does not expose TLS 1.3 ciphersuites set via SSL_CTX_set_ciphersuites() through SSL_CTX_get_ciphers(), so the existing NID-based cipher check in ssl_fips_check_ciphers() cannot catch non-FIPS TLS 1.3 suites. This is further compounded by a defect in the AWS-LC-FIPS 3.x branch where TLS 1.3 ciphers are missing from SSL_get_ciphers() entirely (fixed in https://github.com/aws/aws-lc/pull/2092), making any SSL_CTX-based inspection unreliable across versions. Add ssl_fips_check_ciphersuites() which validates the ciphersuite string directly against a FIPS-approved allowlist (TLS_AES_128_GCM_SHA256 and TLS_AES_256_GCM_SHA384). A NULL string is silently accepted since the global defaults were already overwritten with FIPS values at init time. The new check is called right after SSL_CTX_set_ciphersuites() in both the bind (ssl_sock_prepare_ctx) and server (ssl_sock_prepare_srv_ssl_ctx) configuration paths.
This commit is contained in:
parent
e1d78ce5c3
commit
0ce28bf35e
3 changed files with 59 additions and 0 deletions
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#if defined(OPENSSL_IS_AWSLC)
|
||||
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_version(int min_ver, const enum obj_type *obj);
|
||||
#endif
|
||||
|
||||
|
|
|
|||
51
src/fips.c
51
src/fips.c
|
|
@ -20,6 +20,15 @@ static const int fips_approved_cipher_nids[] = {
|
|||
NID_undef
|
||||
};
|
||||
|
||||
/* FIPS-approved TLS 1.3 ciphersuite names. NULL terminates the list.
|
||||
* TLS_AES_128_CCM_SHA256 is FIPS-approved but not implemented by AWS-LC. */
|
||||
static const char *fips_approved_ciphersuites[] = {
|
||||
"TLS_AES_128_GCM_SHA256",
|
||||
"TLS_AES_256_GCM_SHA384",
|
||||
"TLS_AES_128_CCM_SHA256",
|
||||
NULL
|
||||
};
|
||||
|
||||
/* 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,
|
||||
|
|
@ -52,6 +61,48 @@ static void fips_obj_info(const enum obj_type *obj,
|
|||
}
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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() || !ciphersuites)
|
||||
return 0;
|
||||
|
||||
p = ciphersuites;
|
||||
while (p && *p) {
|
||||
end = strchr(p, ':');
|
||||
len = end ? (size_t)(end - p) : strlen(p);
|
||||
|
||||
for (i = 0; fips_approved_ciphersuites[i]; i++) {
|
||||
if (strlen(fips_approved_ciphersuites[i]) == len &&
|
||||
strncmp(p, fips_approved_ciphersuites[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 ciphersuite(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 ciphersuite(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.2 cipher list configured on <ctx> is FIPS-compliant. */
|
||||
int ssl_fips_check_ciphers(SSL_CTX *ctx, const enum obj_type *obj)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4730,6 +4730,10 @@ static int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, struct ssl_bind_con
|
|||
err && *err ? *err : "", curproxy->id, conf_ciphersuites, bind_conf->arg, bind_conf->file, bind_conf->line);
|
||||
cfgerr |= ERR_ALERT | ERR_FATAL;
|
||||
}
|
||||
#if defined(OPENSSL_IS_AWSLC)
|
||||
cfgerr |= ssl_fips_check_ciphersuites(conf_ciphersuites,
|
||||
&LIST_ELEM(bind_conf->listeners.n, struct listener *, by_bind)->obj_type);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_IS_AWSLC)
|
||||
|
|
@ -5279,6 +5283,9 @@ static int ssl_sock_prepare_srv_ssl_ctx(const struct server *srv, SSL_CTX *ctx)
|
|||
srv->ssl_ctx.ciphersuites);
|
||||
cfgerr++;
|
||||
}
|
||||
#if defined(OPENSSL_IS_AWSLC)
|
||||
cfgerr += !!ssl_fips_check_ciphersuites(srv->ssl_ctx.ciphersuites, &srv->obj_type);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_IS_AWSLC)
|
||||
|
|
|
|||
Loading…
Reference in a new issue