From: Vsevolod Stakhov Date: Sun, 1 Feb 2026 15:44:31 +0000 (+0000) Subject: [Fix] Make unknown and broken DKIM keys behaviour conforming to RFC X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e9e6bac43a84fe6823a88b9c530823b212dd3571;p=thirdparty%2Frspamd.git [Fix] Make unknown and broken DKIM keys behaviour conforming to RFC --- diff --git a/src/libserver/dkim.c b/src/libserver/dkim.c index 121432a715..2a92069639 100644 --- a/src/libserver/dkim.c +++ b/src/libserver/dkim.c @@ -1648,10 +1648,11 @@ rspamd_dkim_parse_key(const char *txt, size_t *keylen, GError **err) } if (klen == 0 || key == NULL) { + /* Per RFC 6376, missing p= tag means key is revoked */ g_set_error(err, DKIM_ERROR, - DKIM_SIGERROR_KEYFAIL, - "key is missing"); + DKIM_SIGERROR_REVOKED, + "key is revoked"); return NULL; } @@ -1673,11 +1674,20 @@ rspamd_dkim_parse_key(const char *txt, size_t *keylen, GError **err) return rspamd_dkim_make_key(key, klen, RSPAMD_DKIM_KEY_EDDSA, err); } - else { - /* We assume RSA default in all cases */ + else if (alglen == 3 && rspamd_lc_cmp(alg, "rsa", alglen) == 0) { return rspamd_dkim_make_key(key, klen, RSPAMD_DKIM_KEY_RSA, err); } + else { + /* Unknown key type - per RFC must be ignored (PERMFAIL) */ + g_set_error(err, + DKIM_ERROR, + DKIM_SIGERROR_KEYTYPE, + "unknown key type: %.*s", + (int) alglen, alg); + + return NULL; + } g_assert_not_reached(); diff --git a/src/libserver/dkim.h b/src/libserver/dkim.h index 2b4122e709..348c073353 100644 --- a/src/libserver/dkim.h +++ b/src/libserver/dkim.h @@ -55,6 +55,8 @@ #define DKIM_SIGERROR_INVALID_H 32 /* h= missing req'd entries */ #define DKIM_SIGERROR_KEYHASHMISMATCH 37 /* sig-key hash mismatch */ #define DKIM_SIGERROR_EMPTY_V 45 /* v= tag empty */ +#define DKIM_SIGERROR_KEYTYPE 46 /* unknown key type */ +#define DKIM_SIGERROR_REVOKED 47 /* key revoked (no p= tag) */ #ifdef __cplusplus extern "C" { diff --git a/src/plugins/dkim_check.c b/src/plugins/dkim_check.c index 8cf0448f5e..edc388cf2f 100644 --- a/src/plugins/dkim_check.c +++ b/src/plugins/dkim_check.c @@ -1319,6 +1319,14 @@ dkim_module_key_handler(rspamd_dkim_key_t *key, res->res = rspamd_dkim_create_result(ctx, DKIM_TRYAGAIN, task); res->res->fail_reason = "DNS error when getting key"; } + else if (err->code == DKIM_SIGERROR_REVOKED) { + res->res = rspamd_dkim_create_result(ctx, DKIM_PERM_ERROR, task); + res->res->fail_reason = "key revoked"; + } + else if (err->code == DKIM_SIGERROR_KEYTYPE) { + res->res = rspamd_dkim_create_result(ctx, DKIM_PERM_ERROR, task); + res->res->fail_reason = "unknown key type"; + } else { res->res = rspamd_dkim_create_result(ctx, DKIM_PERM_ERROR, task); res->res->fail_reason = "invalid DKIM record"; diff --git a/test/functional/cases/116_dkim.robot b/test/functional/cases/116_dkim.robot index a8177d7277..6769e4a837 100644 --- a/test/functional/cases/116_dkim.robot +++ b/test/functional/cases/116_dkim.robot @@ -58,6 +58,14 @@ DKIM Verify ED25519 REJECT Scan File ${RSPAMD_TESTDIR}/messages/ed25519-broken.eml Expect Symbol R_DKIM_REJECT +DKIM Verify Unknown Key Type + Scan File ${RSPAMD_TESTDIR}/messages/dkim_broken_key.eml + Expect Symbol R_DKIM_PERMFAIL + +DKIM Verify Revoked Key (missing p=) + Scan File ${RSPAMD_TESTDIR}/messages/dkim_revoked_key.eml + Expect Symbol R_DKIM_PERMFAIL + DKIM Sign ED25519 PEM ${result} = Scan Message With Rspamc ${RSPAMD_TESTDIR}/messages/spam_message.eml --mime --header=dodkim=ed25519 Check Rspamc ${result} ed25519-sha256 diff --git a/test/functional/configs/plugins.conf b/test/functional/configs/plugins.conf index 79fc862a7b..71d82c717a 100644 --- a/test/functional/configs/plugins.conf +++ b/test/functional/configs/plugins.conf @@ -31,6 +31,16 @@ options = { type = "txt"; replies = ["v=DKIM1; k=ed25519; p=rVvHHYl6r4+aUpAejA9Cyj2EbMexUXl55Lq/DAoipck="]; }, + { + name = "broken._domainkey.brokenkey.za.org", + type = "txt"; + replies = ["v=DKIM1; k=ed2024; p=MCowBQYDK2VwAyEA8EXQo7Pdox7frzkAQi9gnze1veAyxuFfAjNwfn/iOYI="]; + }, + { + name = "revoked._domainkey.revokedkey.za.org", + type = "txt"; + replies = ["v=DKIM1; k=rsa;"]; + }, { name = "eddsa._domainkey.cacophony.za.org", type = "txt"; diff --git a/test/functional/messages/dkim_broken_key.eml b/test/functional/messages/dkim_broken_key.eml new file mode 100644 index 0000000000..3076891416 --- /dev/null +++ b/test/functional/messages/dkim_broken_key.eml @@ -0,0 +1,17 @@ +DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; + d=brokenkey.za.org; s=broken; + q=dns/txt; t=1528637909; h=from : to : subject : date; + bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=; + b=/gCrinpcQOoIfuHNQIbq4pgh9kyIK3AQUdt9OdqQehSwhEIug4D11Bus + Fa3bT3FY5OsU7ZbnKELq+eXdp1Q1Dw== +From: Joe SixPack +To: Suzie Q +Subject: Test broken key type +Date: Fri, 11 Jul 2003 21:00:37 -0700 (PDT) +Message-ID: <20030712040037.46341.5F8J@brokenkey.za.org> + +Hi. + +This message uses a broken DKIM key type (ed2014 instead of ed25519). + +Joe. diff --git a/test/functional/messages/dkim_revoked_key.eml b/test/functional/messages/dkim_revoked_key.eml new file mode 100644 index 0000000000..33bb4e2f53 --- /dev/null +++ b/test/functional/messages/dkim_revoked_key.eml @@ -0,0 +1,16 @@ +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=revokedkey.za.org; s=revoked; + q=dns/txt; t=1528637909; h=from : to : subject : date; + bh=7HkRgYnNru3SR2EWfgWU8yhM0MOH6ZZrPoEIgNIh8wc=; + b=kTIV4jcgv9sWFh2JFrS/+PcNxiloituqjmHHqeJOTfa+/9C+Er8BjnMysTJyYVq36Gnv0OZDgLr3Yy4YP5Lzbt1M9ZdN5cJqO7yn1N7wyaGfkt++b09rIYBy5Dkk7OWyP3cDThqDzv8C9heSvqBSEsirFsbt3Wx2g/hWiJlnjew= +From: Joe SixPack +To: Suzie Q +Subject: Test revoked key +Date: Fri, 11 Jul 2003 21:00:37 -0700 (PDT) +Message-ID: <20030712040037.46341.5F8J@revokedkey.za.org> + +Hi. + +This message uses a revoked DKIM key (no p= parameter). + +Joe.