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
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",
}
}
+/* 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)
{
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)
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
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;
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)