]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-ssl-iostream: Add ssl_peer_certificate_fingerprint_hash setting
authorAki Tuomi <aki.tuomi@open-xchange.com>
Tue, 31 Dec 2024 10:04:00 +0000 (12:04 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Mon, 26 May 2025 05:39:13 +0000 (05:39 +0000)
src/lib-ssl-iostream/iostream-openssl-context.c
src/lib-ssl-iostream/ssl-settings.c
src/lib-ssl-iostream/ssl-settings.h

index 9f6c77132de57566054b04feec42b565b316eb01..01de485b57b2c4e925ecab99db0b05d6ad1f2f61 100644 (file)
@@ -847,7 +847,8 @@ ssl_iostream_context_init_common(struct ssl_iostream_context *ctx,
        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;
                }
index deb30942e85fc860f8c770e055c7b95a8b483dc2..9572f978ef769094db42034d34530f8a62c6473f 100644 (file)
@@ -32,6 +32,7 @@ static const struct setting_define ssl_setting_defines[] = {
 
        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
 };
@@ -51,6 +52,8 @@ const struct ssl_settings ssl_default_settings = {
 
        .ssl_client_require_valid_cert = TRUE,
        .ssl_options = "",
+
+       .ssl_peer_certificate_fingerprint_hash = "",
 };
 
 static const struct setting_keyvalue ssl_default_settings_keyvalue[] = {
@@ -152,6 +155,21 @@ ssl_settings_check(void *_set, pool_t pool ATTR_UNUSED,
                }
        }
 
+       /* 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;
 }
 
@@ -222,6 +240,8 @@ ssl_common_settings_to_iostream_set(const struct ssl_settings *ssl_set)
        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;
 }
 
index 91d7137c6e43cda5e6fcb637d0984952870973f3..83b08155254fbbf927280501b761951a6977dd34 100644 (file)
@@ -18,6 +18,7 @@ struct ssl_settings {
        const char *ssl_min_protocol;
        const char *ssl_crypto_device;
        const char *ssl_options;
+       const char *ssl_peer_certificate_fingerprint_hash;
 
        bool ssl_client_require_valid_cert;