diff --git a/lib/transport/tls-context.c b/lib/transport/tls-context.c index 823c26bede..78d01b19db 100644 --- a/lib/transport/tls-context.c +++ b/lib/transport/tls-context.c @@ -897,6 +897,13 @@ tls_context_set_client_sigalgs(TLSContext *self, const gchar *sigalgs, GError ** #endif } +void +tls_context_set_fingerprint_alg(TLSContext *self, const gchar *fingerprint_alg) +{ + g_free(self->fingerprint_alg); + self->fingerprint_alg = g_strdup(fingerprint_alg); +} + gboolean tls_context_set_conf_cmds(TLSContext *self, GList *cmds, GError **error) { @@ -984,6 +991,7 @@ _tls_context_free(TLSContext *self) g_free(self->ecdh_curve_list); g_free(self->sni); g_free(self->keylog_file_path); + g_free(self->fingerprint_alg); if(self->keylog_file) fclose(self->keylog_file); diff --git a/lib/transport/tls-context.h b/lib/transport/tls-context.h index c074f4a78e..074584fb96 100644 --- a/lib/transport/tls-context.h +++ b/lib/transport/tls-context.h @@ -89,6 +89,7 @@ struct _TLSContext gchar *client_sigalgs; gchar *ecdh_curve_list; gchar *sni; + gchar *fingerprint_alg; gboolean ocsp_stapling_verify; SSL_CTX *ssl_ctx; @@ -138,6 +139,7 @@ void tls_context_set_ecdh_curve_list(TLSContext *self, const gchar *ecdh_curve_l void tls_context_set_dhparam_file(TLSContext *self, const gchar *dhparam_file); void tls_context_set_sni(TLSContext *self, const gchar *sni); void tls_context_set_ocsp_stapling_verify(TLSContext *self, gboolean ocsp_stapling_verify); +void tls_context_set_fingerprint_alg(TLSContext *self, const gchar *fingerprint_alg); const gchar *tls_context_get_key_file(TLSContext *self); EVTTAG *tls_context_format_tls_error_tag(TLSContext *self); EVTTAG *tls_context_format_location_tag(TLSContext *self); diff --git a/lib/transport/tls-session.c b/lib/transport/tls-session.c index e3eb307781..150898c3dd 100644 --- a/lib/transport/tls-session.c +++ b/lib/transport/tls-session.c @@ -48,19 +48,29 @@ tls_session_configure_allow_compress(TLSSession *tls_session, gboolean allow_com } static gboolean -tls_get_x509_digest(X509 *x, GString *hash_string) +tls_get_x509_digest(const gchar *fingerprint_alg, X509 *x, GString *hash_string) { gint j; unsigned int n; - unsigned char md[EVP_MAX_MD_SIZE]; + unsigned char buffer[EVP_MAX_MD_SIZE]; g_assert(hash_string); - if (!X509_digest(x, EVP_sha1(), md, &n)) + if (!fingerprint_alg) + fingerprint_alg = "sha1"; + const EVP_MD *md = EVP_get_digestbyname(fingerprint_alg); + if (!md) + { + msg_error("Error validating trusted-keys(), unknown fingerprint-alg() specified", + evt_tag_str("fingerprint-alg", fingerprint_alg)); + return FALSE; + } + + if (!X509_digest(x, md, buffer, &n)) return FALSE; - g_string_append(hash_string, "SHA1:"); + g_string_append(hash_string, EVP_MD_name(md)); for (j = 0; j < (int) n; j++) - g_string_append_printf(hash_string, "%02X%c", md[j], (j + 1 == (int) n) ?'\0' : ':'); + g_string_append_printf(hash_string, ":%02X", buffer[j]); return TRUE; } @@ -125,7 +135,7 @@ tls_session_verify_fingerprint(X509_STORE_CTX *ctx) hash = g_string_sized_new(EVP_MAX_MD_SIZE * 3); - if (tls_get_x509_digest(cert, hash)) + if (tls_get_x509_digest(self->ctx->fingerprint_alg, cert, hash)) { do { diff --git a/modules/afsocket/afsocket-grammar.ym b/modules/afsocket/afsocket-grammar.ym index d26ea8bd73..0d477ed286 100644 --- a/modules/afsocket/afsocket-grammar.ym +++ b/modules/afsocket/afsocket-grammar.ym @@ -199,6 +199,7 @@ systemd_syslog_grammar_set_source_driver(SystemDSyslogSourceDriver *sd) %token KW_KEYLOG_FILE %token KW_OCSP_STAPLING_VERIFY %token KW_CONF_CMDS +%token KW_FINGERPRINT_ALG /* INCLUDE_DECLS */ @@ -858,6 +859,10 @@ tls_option { tls_session_set_trusted_fingerprints(last_tls_context, $3); } + | KW_FINGERPRINT_ALG '(' string ')' + { + tls_context_set_fingerprint_alg(last_tls_context, $3); + } | KW_TRUSTED_DN '(' string_list ')' { tls_session_set_trusted_dn(last_tls_context, $3); diff --git a/modules/afsocket/afsocket-parser.c b/modules/afsocket/afsocket-parser.c index 43ebcb863c..4058748a0f 100644 --- a/modules/afsocket/afsocket-parser.c +++ b/modules/afsocket/afsocket-parser.c @@ -68,6 +68,7 @@ static CfgLexerKeyword afsocket_keywords[] = { "allow_compress", KW_ALLOW_COMPRESS }, { "ocsp_stapling_verify", KW_OCSP_STAPLING_VERIFY }, { "openssl_conf_cmds", KW_CONF_CMDS}, + { "fingerprint_alg", KW_FINGERPRINT_ALG }, { "localip", KW_LOCALIP }, { "ip", KW_IP }, diff --git a/news/feature-137.md b/news/feature-137.md new file mode 100644 index 0000000000..14f95a0455 --- /dev/null +++ b/news/feature-137.md @@ -0,0 +1,13 @@ +Add `fingerprint-alg()` option to `tls()` blocks: SSL peers can be validated +using the `trusted-keys()` option that takes a list of trusted public key +fingerprints. This was using the `sha1` algorithm, which is not considered +safe anymore. This option can be used to customize the message digest +algorithm and accepts any known algorithms supported by OpenSSL. As of +OpenSSL 3.0.10, the followings are supported (OpenSSL 3.0.10): + +Message Digest commands (see the `dgst' command for more details) +blake2b512 blake2s256 md4 md5 +rmd160 sha1 sha224 sha256 +sha3-224 sha3-256 sha3-384 sha3-512 +sha384 sha512 sha512-224 sha512-256 +shake128 shake256 sm3