+/* Check that the signature algorithm list <sigalgs> is FIPS-compliant. */
+int ssl_fips_check_sigalgs(const char *sigalgs, const enum obj_type *obj, char **err)
+{
+ 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)
+ memprintf(err, "%s[%s:%d] %s '%s/%s': FIPS mode active but non-FIPS signature algorithm(s) configured: %s.\n",
+ (err && *err) ? *err : "", file, line, type_str, proxy_name, obj_name, list);
+ else
+ memprintf(err, "%s%s '%s/%s': FIPS mode active but non-FIPS signature algorithm(s) configured: %s.\n",
+ (err && *err) ? *err : "", type_str, proxy_name, obj_name, list);
+ free(list);
+ return ERR_ALERT | ERR_ABORT | ERR_FATAL;
+ }
+ return 0;
+}
+