if (set->cert_hash_algo != NULL && *set->cert_hash_algo != '\0') {
ctx->pcert_fp_algo = EVP_get_digestbyname(set->cert_hash_algo);
if (ctx->pcert_fp_algo == NULL) {
- *error_r = t_strdup_printf("Unsupported hash algorithm '%s'",
+ *error_r = t_strdup_printf("Unsupported hash algorithm '%s' "
+ "(ssl_peer_certificate_fingerprint_hash setting)",
set->cert_hash_algo);
return -1;
}
DEF(BOOL, ssl_client_require_valid_cert),
DEF(STR, ssl_options), /* parsed as a string to set bools */
+ DEF(STR, ssl_peer_certificate_fingerprint_hash),
SETTING_DEFINE_LIST_END
};
.ssl_client_require_valid_cert = TRUE,
.ssl_options = "",
+
+ .ssl_peer_certificate_fingerprint_hash = "",
};
static const struct setting_keyvalue ssl_default_settings_keyvalue[] = {
}
}
+ /* Hashing algorithms considered unsafe for
+ fingerprinting purposes. */
+ static const char *const unsafe_hash_algos[] = {
+ "md4", "md5", "sha1", "rmd160", "sm3", NULL
+ };
+
+ if (str_array_icase_find(unsafe_hash_algos,
+ set->ssl_peer_certificate_fingerprint_hash)) {
+ *error_r = t_strdup_printf(
+ "ssl_peer_certificate_fingerprint_hash: "
+ "Unsafe hash algorithm '%s' used",
+ set->ssl_peer_certificate_fingerprint_hash);
+ return FALSE;
+ }
+
return TRUE;
}
set->compression = ssl_set->parsed_opts.compression;
set->tickets = ssl_set->parsed_opts.tickets;
set->curve_list = ssl_set->ssl_curve_list;
+ set->cert_hash_algo = ssl_set->ssl_peer_certificate_fingerprint_hash;
+
return set;
}