From: Vsevolod Stakhov Date: Tue, 7 Jul 2020 21:20:41 +0000 (+0100) Subject: [Fix] Distinguish DKIM keys by md5 X-Git-Tag: 2.6~256 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=7e1c77638f6fd4adf10f6e76d5d4f30d33c3183f;p=rspamd.git [Fix] Distinguish DKIM keys by md5 --- diff --git a/src/libserver/dkim.c b/src/libserver/dkim.c index daa0c380f..390d3fb21 100644 --- a/src/libserver/dkim.c +++ b/src/libserver/dkim.c @@ -146,7 +146,7 @@ struct rspamd_dkim_context_s { const gchar *dkim_header; }; -#define RSPAMD_DKIM_KEY_ID_LEN 8 +#define RSPAMD_DKIM_KEY_ID_LEN 16 struct rspamd_dkim_key_s { guint8 *keydata; @@ -1292,10 +1292,32 @@ rspamd_dkim_make_key (const gchar *keydata, key->keylen = keylen; key->type = type; - rspamd_strlcpy (key->key_id, keydata, MIN (keylen, sizeof (key->key_id))); + if (!rspamd_cryptobox_base64_decode (keydata, keylen, key->keydata, + &key->decoded_len)) { + REF_RELEASE (key); + g_set_error (err, + DKIM_ERROR, + DKIM_SIGERROR_KEYFAIL, + "DKIM key is not a valid base64 string"); + + return NULL; + } + + /* Calculate ID -> md5 */ + EVP_MD_CTX *mdctx = EVP_MD_CTX_create (); + +#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW + EVP_MD_CTX_set_flags (mdctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); +#endif + + if (EVP_DigestInit_ex (mdctx, EVP_md5 (), NULL) == 1) { + guint dlen = sizeof (key->key_id); + + EVP_DigestUpdate (mdctx, key->keydata, key->decoded_len); + EVP_DigestFinal_ex (mdctx, key->key_id, &dlen); + } - rspamd_cryptobox_base64_decode (keydata, keylen, key->keydata, - &key->decoded_len); + EVP_MD_CTX_destroy (mdctx); if (key->type == RSPAMD_DKIM_KEY_EDDSA) { key->key.key_eddsa = key->keydata; @@ -1367,7 +1389,7 @@ rspamd_dkim_make_key (const gchar *keydata, return key; } -const gchar * +const guchar * rspamd_dkim_key_id (rspamd_dkim_key_t *key) { if (key) { @@ -2632,12 +2654,12 @@ rspamd_dkim_check (rspamd_dkim_context_t *ctx, msg_info_dkim ( "%s: headers RSA verification failure; " - "body length %d->%d; headers length %d; d=%s; s=%s; key=%s; orig header: %s", + "body length %d->%d; headers length %d; d=%s; s=%s; key=%*xs; orig header: %s", rspamd_dkim_type_to_string (ctx->common.type), (gint)(body_end - body_start), ctx->common.body_canonicalised, ctx->common.headers_canonicalised, ctx->domain, ctx->selector, - rspamd_dkim_key_id (key), + RSPAMD_DKIM_KEY_ID_LEN, rspamd_dkim_key_id (key), ctx->dkim_header); } break; @@ -2646,12 +2668,12 @@ rspamd_dkim_check (rspamd_dkim_context_t *ctx, key->key.key_ecdsa) != 1) { msg_info_dkim ( "%s: headers ECDSA verification failure; " - "body length %d->%d; headers length %d; d=%s; s=%s; key=%s; orig header: %s", + "body length %d->%d; headers length %d; d=%s; s=%s; key=%*xs; orig header: %s", rspamd_dkim_type_to_string (ctx->common.type), (gint)(body_end - body_start), ctx->common.body_canonicalised, ctx->common.headers_canonicalised, ctx->domain, ctx->selector, - rspamd_dkim_key_id (key), + RSPAMD_DKIM_KEY_ID_LEN, rspamd_dkim_key_id (key), ctx->dkim_header); msg_debug_dkim ("headers ecdsa verify failed"); res->rcode = DKIM_REJECT; @@ -2663,12 +2685,12 @@ rspamd_dkim_check (rspamd_dkim_context_t *ctx, key->key.key_eddsa, RSPAMD_CRYPTOBOX_MODE_25519)) { msg_info_dkim ( "%s: headers EDDSA verification failure; " - "body length %d->%d; headers length %d; d=%s; s=%s; key=%s; orig header: %s", + "body length %d->%d; headers length %d; d=%s; s=%s; key=%*xs; orig header: %s", rspamd_dkim_type_to_string (ctx->common.type), (gint)(body_end - body_start), ctx->common.body_canonicalised, ctx->common.headers_canonicalised, ctx->domain, ctx->selector, - rspamd_dkim_key_id (key), + RSPAMD_DKIM_KEY_ID_LEN, rspamd_dkim_key_id (key), ctx->dkim_header); msg_debug_dkim ("headers eddsa verify failed"); res->rcode = DKIM_REJECT; diff --git a/src/libserver/dkim.h b/src/libserver/dkim.h index 6245dc512..afd272028 100644 --- a/src/libserver/dkim.h +++ b/src/libserver/dkim.h @@ -268,12 +268,14 @@ rspamd_dkim_key_t *rspamd_dkim_make_key (const gchar *keydata, guint keylen, enum rspamd_dkim_key_type type, GError **err); +#define RSPAMD_DKIM_KEY_ID_LEN 16 /** - * Returns key id for dkim key (first 7 bytes of base64 representation) + * Returns key id for dkim key (raw md5 of RSPAMD_DKIM_KEY_ID_LEN) + * NOT ZERO TERMINATED, use RSPAMD_DKIM_KEY_ID_LEN for length * @param key * @return */ -const gchar *rspamd_dkim_key_id (rspamd_dkim_key_t *key); +const guchar *rspamd_dkim_key_id (rspamd_dkim_key_t *key); /** * Parse DKIM public key from a TXT record