Gitweb:
https://git.exim.org/exim.git/commitdiff/042e558f346b01902dd414206a047fa47b686f0b
Commit: 042e558f346b01902dd414206a047fa47b686f0b
Parent: dbbf21a75d225871cb7a44878ece42c5d79a1a2c
Author: Jeremy Harris <jgh146exb@???>
AuthorDate: Sat Aug 10 17:58:22 2019 +0100
Committer: Jeremy Harris <jgh146exb@???>
CommitDate: Sun Aug 11 19:26:43 2019 +0100
DKIM: preferences for verify algorithms
---
doc/doc-docbook/spec.xfpt | 60 ++++++++++++++++++++----
doc/doc-txt/NewStuff | 2 +
doc/doc-txt/OptionLists.txt | 3 ++
src/src/globals.c | 3 ++
src/src/globals.h | 3 ++
src/src/pdkim/pdkim.c | 93 +++++++++++++++++++++++++++++++------
src/src/pdkim/pdkim.h | 5 +-
src/src/readconf.c | 3 ++
test/confs/4509 | 28 +++++++++++
test/confs/4520 | 3 ++
test/confs/4541 | 1 +
test/log/4509 | 5 ++
test/log/4541 | 28 +++++++++++
test/mail/4541.a | 26 +++++++++++
test/mail/4541.b | 26 +++++++++++
test/scripts/4500-DKIM/4509 | 41 ++++++++++++++++
test/scripts/4540-DKIM-Ed25519/4541 | 30 ++++++++++++
17 files changed, 331 insertions(+), 29 deletions(-)
diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index aa39965..8bba6fe 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -14347,7 +14347,9 @@ listed in more than one group.
See also the &'Policy controls'& section above.
.table2
-.row &%dkim_verify_signers%& "DKIM domain for which DKIM ACL is run"
+.row &%dkim_verify_hashes%& "DKIM hash methods accepted for signatures"
+.row &%dkim_verify_keytypes%& "DKIM key types accepted for signatures"
+.row &%dkim_verify_signers%& "DKIM domains for which DKIM ACL is run"
.row &%host_lookup%& "host name looked up for these hosts"
.row &%host_lookup_order%& "order of DNS and local name lookups"
.row &%recipient_unqualified_hosts%& "may send unqualified recipients"
@@ -15092,6 +15094,27 @@ etc. are ignored. If IP literals are enabled, the &(ipliteral)& router declines
to handle IPv6 literal addresses.
+.new
+.option dkim_verify_hashes main "string list" "sha256 : sha512 : sha1"
+.cindex DKIM "selecting signature algorithms"
+This option gives a list of hash types which are acceptable in signatures,
+and an order of processing.
+Signatures with algorithms not in the list will be ignored.
+
+Note that the presence of sha1 violates RFC 8301.
+Signatures using the rsa-sha1 are however (as of writing) still common.
+The default inclusion of sha1 may be dropped in a future release.
+
+.option dkim_verify_keytypes main "string list" "ed25519 : rsa"
+This option gives a list of key types which are acceptable in signatures,
+and an order of processing.
+Signatures with algorithms not in the list will be ignored.
+
+.option dkim_verify_minimal main boolean false
+If set to true, verification of signatures will terminate after the
+first success.
+.wen
+
.option dkim_verify_signers main "domain list&!!" $dkim_signers
.cindex DKIM "controlling calls to the ACL"
This option gives a list of DKIM domains for which the DKIM ACL is run.
@@ -39913,15 +39936,28 @@ RFC 6376 lists these tags as RECOMMENDED.
Verification of DKIM signatures in SMTP incoming email is done for all
messages for which an ACL control &%dkim_disable_verify%& has not been set.
+.new
+.cindex DKIM "selecting signature algorithms"
+Individual classes of signature algorithm can be ignored by changing
+the main options &%dkim_verify_hashes%& or &%dkim_verify_keytypes%&.
+The &%dkim_verify_minimal%& option can be set to cease verification
+processing for a message once the first passing signature is found.
+.wen
+
.cindex authentication "expansion item"
Performing verification sets up information used by the
&$authresults$& expansion item.
-The results of that verification are then made available to the
+.new
+For most purposes the default option settings suffice and the remainder
+of this section can be ignored.
+.wen
+
+The results of verification are made available to the
&%acl_smtp_dkim%& ACL, which can examine and modify them.
-By default, this ACL is called once for each
-syntactically(!) correct signature in the incoming message.
A missing ACL definition defaults to accept.
+By default, the ACL is called once for each
+syntactically(!) correct signature in the incoming message.
If any ACL call does not accept, the message is not accepted.
If a cutthrough delivery was in progress for the message, that is
summarily dropped (having wasted the transmission effort).
@@ -39932,11 +39968,11 @@ containing the signature status and its details are set up during the
runtime of the ACL.
Calling the ACL only for existing signatures is not sufficient to build
-more advanced policies. For that reason, the global option
-&%dkim_verify_signers%&, and a global expansion variable
+more advanced policies. For that reason, the main option
+&%dkim_verify_signers%&, and an expansion variable
&%$dkim_signers%& exist.
-The global option &%dkim_verify_signers%& can be set to a colon-separated
+The main option &%dkim_verify_signers%& can be set to a colon-separated
list of DKIM domains or identities for which the ACL &%acl_smtp_dkim%& is
called. It is expanded when the message has been received. At this point,
the expansion variable &%$dkim_signers%& already contains a colon-separated
@@ -39974,7 +40010,7 @@ If multiple signatures match a domain (or identity), the ACL is called once
for each matching signature.
-Inside the &%acl_smtp_dkim%&, the following expansion variables are
+Inside the DKIM ACL, the following expansion variables are
available (from most to least important):
@@ -40068,8 +40104,12 @@ DKIM signatures identified as having been signed with historic
algorithms (currently, rsa-sha1) have permanently failed evaluation
.endd
-To enforce this you must have a DKIM ACL which checks this variable
-and overwrites the &$dkim_verify_status$& variable as discussed above.
+To enforce this you must either have a DKIM ACL which checks this variable
+and overwrites the &$dkim_verify_status$& variable as discussed above,
+.new
+or have set the main option &%dkim_verify_hashes%& to exclude
+processing of such signatures.
+.wen
.vitem &%$dkim_canon_body%&
The body canonicalization method. One of 'relaxed' or 'simple'.
diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff
index bcfbe7c..8577f6d 100644
--- a/doc/doc-txt/NewStuff
+++ b/doc/doc-txt/NewStuff
@@ -33,6 +33,8 @@ Version 4.93
10. The spf lookup now supports IPv6.
+11. Main options for DKIM verify to filter hash and key types.
+
Version 4.92
--------------
diff --git a/doc/doc-txt/OptionLists.txt b/doc/doc-txt/OptionLists.txt
index 1622467..abc09ec 100644
--- a/doc/doc-txt/OptionLists.txt
+++ b/doc/doc-txt/OptionLists.txt
@@ -171,6 +171,9 @@ dkim_selector string* unset smtp
dkim_sign_headers string* (RFC4871) smtp 4.70
dkim_strict string* unset smtp 4.70
dkim_timestamps integer* unset smtp 4.92
+dkim_verify_hashes string sha256:sha512:sha1 main 4.93
+dkim_verify_keytypes string ed25519:rsa main 4.93
+dkim_verify_minimal boolean false main 4.93
dkim_verify_signers string* $dkim_signers main 4.70
directory string* unset appendfile
directory_file string* + appendfile
diff --git a/src/src/globals.c b/src/src/globals.c
index 15fb089..61a9c97 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -830,6 +830,9 @@ void *dkim_signatures = NULL;
uschar *dkim_signers = NULL;
uschar *dkim_signing_domain = NULL;
uschar *dkim_signing_selector = NULL;
+uschar *dkim_verify_hashes = US"sha256:sha512:sha1";
+uschar *dkim_verify_keytypes = US"ed25519:rsa";
+BOOL dkim_verify_minimal = FALSE;
uschar *dkim_verify_overall = NULL;
uschar *dkim_verify_signers = US"$dkim_signers";
uschar *dkim_verify_status = NULL;
diff --git a/src/src/globals.h b/src/src/globals.h
index c226004..4ab43ca 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -503,6 +503,9 @@ extern void *dkim_signatures; /* Actually a (pdkim_signature *) but mos
extern uschar *dkim_signers; /* Expansion variable, holds colon-separated list of domains and identities that have signed a message */
extern uschar *dkim_signing_domain; /* Expansion variable, domain used for signing a message. */
extern uschar *dkim_signing_selector; /* Expansion variable, selector used for signing a message. */
+extern uschar *dkim_verify_hashes; /* Preference order for signatures */
+extern uschar *dkim_verify_keytypes; /* Preference order for signatures */
+extern BOOL dkim_verify_minimal; /* Shortcircuit signture verification */
extern uschar *dkim_verify_overall; /* First successful domain verified, or null */
extern uschar *dkim_verify_signers; /* Colon-separated list of domains for each of which we call the DKIM ACL */
extern uschar *dkim_verify_status; /* result for this signature */
diff --git a/src/src/pdkim/pdkim.c b/src/src/pdkim/pdkim.c
index f10f206..79e7c63 100644
--- a/src/src/pdkim/pdkim.c
+++ b/src/src/pdkim/pdkim.c
@@ -121,6 +121,14 @@ return string_sprintf("%s-%s",
}
+static int
+pdkim_keyname_to_keytype(const uschar * s)
+{
+for (int i = 0; i < nelem(pdkim_keytypes); i++)
+ if (Ustrcmp(s, pdkim_keytypes[i]) == 0) return i;
+return -1;
+}
+
int
pdkim_hashname_to_hashtype(const uschar * s, unsigned len)
{
@@ -561,9 +569,7 @@ for (uschar * p = raw_hdr; ; p++)
uschar * elem;
if ((elem = string_nextinlist(&list, &sep, NULL, 0)))
- for (int i = 0; i < nelem(pdkim_keytypes); i++)
- if (Ustrcmp(elem, pdkim_keytypes[i]) == 0)
- { sig->keytype = i; break; }
+ sig->keytype = pdkim_keyname_to_keytype(elem);
if ((elem = string_nextinlist(&list, &sep, NULL, 0)))
for (int i = 0; i < nelem(pdkim_hashes); i++)
if (Ustrcmp(elem, pdkim_hashes[i].dkim_hashname) == 0)
@@ -1411,16 +1417,13 @@ time we do not have a signature so we must interpret the pubkey k= tag
instead. Assume writing on the sig is ok in that case. */
if (sig->keytype < 0)
- {
- for(int i = 0; i < nelem(pdkim_keytypes); i++)
- if (Ustrcmp(p->keytype, pdkim_keytypes[i]) == 0)
- { sig->keytype = i; goto k_ok; }
- DEBUG(D_acl) debug_printf("verify_init: unhandled keytype %s\n", p->keytype);
- sig->verify_status = PDKIM_VERIFY_INVALID;
- sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
- return NULL;
- }
-k_ok:
+ if ((sig->keytype = pdkim_keyname_to_keytype(p->keytype)) < 0)
+ {
+ DEBUG(D_acl) debug_printf("verify_init: unhandled keytype %s\n", p->keytype);
+ sig->verify_status = PDKIM_VERIFY_INVALID;
+ sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
+ return NULL;
+ }
if (sig->keytype == KEYTYPE_ED25519)
check_bare_ed25519_pubkey(p);
@@ -1441,6 +1444,61 @@ return p;
/* -------------------------------------------------------------------------- */
+/* Sort and filter the sigs developed from the message */
+
+static pdkim_signature *
+sort_sig_methods(pdkim_signature * siglist)
+{
+pdkim_signature * yield, ** ss;
+const uschar * prefs;
+uschar * ele;
+int sep;
+
+if (!siglist) return NULL;
+
+/* first select in order of hashtypes */
+DEBUG(D_acl) debug_printf("PDKIM: dkim_verify_hashes '%s'\n", dkim_verify_hashes);
+for (prefs = dkim_verify_hashes, sep = 0, yield = NULL, ss = &yield;
+ ele = string_nextinlist(&prefs, &sep, NULL, 0); )
+ {
+ int i = pdkim_hashname_to_hashtype(CUS ele, 0);
+ for (pdkim_signature * s = siglist, * next, ** prev = &siglist; s;
+ s = next)
+ {
+ next = s->next;
+ if (s->hashtype == i)
+ { *prev = next; s->next = NULL; *ss = s; ss = &s->next; }
+ else
+ prev = &s->next;
+ }
+ }
+
+/* then in order of keytypes */
+siglist = yield;
+DEBUG(D_acl) debug_printf("PDKIM: dkim_verify_keytypes '%s'\n", dkim_verify_keytypes);
+for (prefs = dkim_verify_keytypes, sep = 0, yield = NULL, ss = &yield;
+ ele = string_nextinlist(&prefs, &sep, NULL, 0); )
+ {
+ int i = pdkim_keyname_to_keytype(CUS ele);
+ for (pdkim_signature * s = siglist, * next, ** prev = &siglist; s;
+ s = next)
+ {
+ next = s->next;
+ if (s->keytype == i)
+ { *prev = next; s->next = NULL; *ss = s; ss = &s->next; }
+ else
+ prev = &s->next;
+ }
+ }
+
+DEBUG(D_acl) for (pdkim_signature * s = yield; s; s = s->next)
+ debug_printf(" retain d=%s s=%s a=%s\n",
+ s->domain, s->selector, dkim_sig_to_a_tag(s));
+return yield;
+}
+
+
+/* -------------------------------------------------------------------------- */
DLLEXPORT int
pdkim_feed_finish(pdkim_ctx * ctx, pdkim_signature ** return_signatures,
@@ -1472,6 +1530,11 @@ have a hash to do for ARC. */
pdkim_finish_bodyhash(ctx);
+/* Sort and filter the recived signatures */
+
+if (!(ctx->flags & PDKIM_MODE_SIGN))
+ ctx->sig = sort_sig_methods(ctx->sig);
+
if (!ctx->sig)
{
DEBUG(D_acl) debug_printf("PDKIM: no signatures\n");
@@ -1496,7 +1559,7 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next)
}
/*XXX The hash of the headers is needed for GCrypt (for which we can do RSA
- suging only, as it happens) and for either GnuTLS and OpenSSL when we are
+ signing only, as it happens) and for either GnuTLS and OpenSSL when we are
signing with EC (specifically, Ed25519). The former is because the GCrypt
signing operation is pure (does not do its own hash) so we must hash. The
latter is because we (stupidly, but this is what the IETF draft is saying)
@@ -1550,7 +1613,6 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next)
/* Import private key, including the keytype which we need for building
the signature header */
-/*XXX extend for non-RSA algos */
if ((*err = exim_dkim_signing_init(CUS sig->privkey, &sctx)))
{
log_write(0, LOG_MAIN|LOG_PANIC, "signing_init: %s", *err);
@@ -1831,6 +1893,7 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next)
{
sig->verify_status = PDKIM_VERIFY_PASS;
verify_pass = TRUE;
+ if (dkim_verify_minimal) break;
}
NEXT_VERIFY:
diff --git a/src/src/pdkim/pdkim.h b/src/src/pdkim/pdkim.h
index b2f586c..0c9d46d 100644
--- a/src/src/pdkim/pdkim.h
+++ b/src/src/pdkim/pdkim.h
@@ -74,9 +74,6 @@
/* Some parameter values */
#define PDKIM_QUERYMETHOD_DNS_TXT 0
-/*#define PDKIM_ALGO_RSA_SHA256 0 */
-/*#define PDKIM_ALGO_RSA_SHA1 1 */
-
#define PDKIM_CANON_SIMPLE 0
#define PDKIM_CANON_RELAXED 1
@@ -142,7 +139,7 @@ typedef struct pdkim_signature {
/* (v=) The version, as an integer. Currently, always "1" */
int version;
- /* (a=) The signature algorithm. Either PDKIM_ALGO_RSA_SHA256 */
+ /* (a=) The signature algorithm. */
int keytype; /* pdkim_keytypes index */
int hashtype; /* pdkim_hashes index */
diff --git a/src/src/readconf.c b/src/src/readconf.c
index a5482f7..05d3077 100644
--- a/src/src/readconf.c
+++ b/src/src/readconf.c
@@ -117,6 +117,9 @@ static optionlist optionlist_config[] = {
#endif
{ "disable_ipv6", opt_bool, &disable_ipv6 },
#ifndef DISABLE_DKIM
+ { "dkim_verify_hashes", opt_stringptr, &dkim_verify_hashes },
+ { "dkim_verify_keytypes", opt_stringptr, &dkim_verify_keytypes },
+ { "dkim_verify_minimal", opt_bool, &dkim_verify_minimal },
{ "dkim_verify_signers", opt_stringptr, &dkim_verify_signers },
#endif
#ifdef EXPERIMENTAL_DMARC
diff --git a/test/confs/4509 b/test/confs/4509
new file mode 100644
index 0000000..5c64a49
--- /dev/null
+++ b/test/confs/4509
@@ -0,0 +1,28 @@
+# Exim test configuration 4509
+
+SERVER=
+
+.include DIR/aux-var/std_conf_prefix
+
+primary_hostname = myhost.test.ex
+
+# ----- Main settings -----
+
+acl_smtp_rcpt = accept
+acl_smtp_data = check_data
+
+log_selector = +dkim_verbose
+
+# No sha1 !
+dkim_verify_hashes = sha256 : sha512
+
+queue_only
+queue_run_in_order
+
+
+begin acl
+
+check_data:
+ accept logwrite = ${authresults {$primary_hostname}}
+
+# End
diff --git a/test/confs/4520 b/test/confs/4520
index f345b91..1f31623 100644
--- a/test/confs/4520
+++ b/test/confs/4520
@@ -15,6 +15,9 @@ acl_smtp_dkim = accept logwrite = dkim_acl: signer: $dkim_cur_signer bits: $dkim
acl_smtp_data = accept logwrite = data acl: dkim status $dkim_verify_status
dkim_verify_signers = $dkim_signers
+.ifdef FILTER
+dkim_verify_minimal = true
+.endif
DDIR=DIR/aux-fixed/dkim
diff --git a/test/confs/4541 b/test/confs/4541
new file mode 120000
index 0000000..072f5fa
--- /dev/null
+++ b/test/confs/4541
@@ -0,0 +1 @@
+4520
\ No newline at end of file
diff --git a/test/log/4509 b/test/log/4509
new file mode 100644
index 0000000..0ab1a76
--- /dev/null
+++ b/test/log/4509
@@ -0,0 +1,5 @@
+
+******** SERVER ********
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
+1999-03-02 09:44:33 10HmaX-0005vi-00 Authentication-Results: myhost.test.ex
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@??? H=(xxx) [127.0.0.1] P=smtp S=sss id=qwerty1234@???
diff --git a/test/log/4541 b/test/log/4541
new file mode 100644
index 0000000..b8a5f33
--- /dev/null
+++ b/test/log/4541
@@ -0,0 +1,28 @@
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss for a@???
+1999-03-02 09:44:33 10HmaX-0005vi-00 => a@??? R=client T=send_to_server H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] C="250 OK id=10HmaY-0005vi-00"
+1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss for b@???
+1999-03-02 09:44:33 10HmaZ-0005vi-00 => b@??? R=client T=send_to_server H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] C="250 OK id=10HmbA-0005vi-00"
+1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
+
+******** SERVER ********
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
+1999-03-02 09:44:33 rcpt acl: macro: From:Sender:Reply-To:Subject:Date:Message-ID:To:Cc:MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive
+1999-03-02 09:44:33 10HmaY-0005vi-00 dkim_acl: signer: test.ex bits: 512 h=From
+1999-03-02 09:44:33 10HmaY-0005vi-00 DKIM: d=test.ex s=sed c=relaxed/relaxed a=ed25519-sha256 b=512 [verification succeeded]
+1999-03-02 09:44:33 10HmaY-0005vi-00 dkim_acl: signer: test.ex bits: 1024 h=From
+1999-03-02 09:44:33 10HmaY-0005vi-00 DKIM: d=test.ex s=sel c=relaxed/relaxed a=rsa-sha256 b=1024 [verification succeeded]
+1999-03-02 09:44:33 10HmaY-0005vi-00 data acl: dkim status pass:pass
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@??? H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp S=sss id=E10HmaX-0005vi-00@??? for a@???
+1999-03-02 09:44:33 10HmaY-0005vi-00 => a <a@???> R=server_store T=file
+1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
+1999-03-02 09:44:33 rcpt acl: macro: From:Sender:Reply-To:Subject:Date:Message-ID:To:Cc:MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive
+1999-03-02 09:44:33 10HmbA-0005vi-00 dkim_acl: signer: test.ex bits: 512 h=From
+1999-03-02 09:44:33 10HmbA-0005vi-00 DKIM: d=test.ex s=sed c=relaxed/relaxed a=ed25519-sha256 b=512 [verification succeeded]
+1999-03-02 09:44:33 10HmbA-0005vi-00 dkim_acl: signer: test.ex bits: 1024 h=From
+1999-03-02 09:44:33 10HmbA-0005vi-00 DKIM: d=test.ex s=sel c=relaxed/relaxed a=rsa-sha256 b=1024 [not verified]
+1999-03-02 09:44:33 10HmbA-0005vi-00 data acl: dkim status pass:none
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@??? H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp S=sss id=E10HmaZ-0005vi-00@??? for b@???
+1999-03-02 09:44:33 10HmbA-0005vi-00 => b <b@???> R=server_store T=file
+1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
diff --git a/test/mail/4541.a b/test/mail/4541.a
new file mode 100644
index 0000000..e1c95f0
--- /dev/null
+++ b/test/mail/4541.a
@@ -0,0 +1,26 @@
+From CALLER@??? Tue Mar 02 09:44:33 1999
+Received: from the.local.host.name ([ip4.ip4.ip4.ip4] helo=myhost.test.ex)
+ by myhost.test.ex with esmtp (Exim x.yz)
+ (envelope-from <CALLER@???>)
+ id 10HmaY-0005vi-00
+ for a@???; Tue, 2 Mar 1999 09:44:33 +0000
+DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=test.ex;
+ s=sel; h=From; bh=/Ab0giHZitYQbDhFszoqQRUkgqueaX9zatJttIU/plc=; b=toy5chxow6W
+ 7Nn3qMvjZs+i0H00bQfi+6nakV6i36cRrZM/oWziHrc5IfYZuQunWNUA9UHnatK35Nsl7ZJRBU4em
+ wtzdO60jXnH7ZVyYjKxqTow9uCuuBKCgXdKxt1hpEfY0m7uUKt9OaqA0464NH5wEC4o/pt1aReidE
+ hvI6IY=;
+DKIM-Signature: v=1; a=ed25519-sha256; q=dns/txt; c=relaxed/relaxed; d=test.ex
+ ; s=sed; h=From; bh=/Ab0giHZitYQbDhFszoqQRUkgqueaX9zatJttIU/plc=; b=IKNwoUbCe
+ ayHoA7j2L0IU1IFuapa3DrlNx9wPlBodM1iKJ57WGibKzefQNdTjymHPsMlQ9fS+h9ZSsHmVNBdDA
+ ==;
+Received: from CALLER by myhost.test.ex with local (Exim x.yz)
+ (envelope-from <CALLER@???>)
+ id 10HmaX-0005vi-00
+ for a@???; Tue, 2 Mar 1999 09:44:33 +0000
+From: nobody@???
+Message-Id: <E10HmaX-0005vi-00@???>
+Sender: CALLER_NAME <CALLER@???>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+content
+
diff --git a/test/mail/4541.b b/test/mail/4541.b
new file mode 100644
index 0000000..7927bbc
--- /dev/null
+++ b/test/mail/4541.b
@@ -0,0 +1,26 @@
+From CALLER@??? Tue Mar 02 09:44:33 1999
+Received: from the.local.host.name ([ip4.ip4.ip4.ip4] helo=myhost.test.ex)
+ by myhost.test.ex with esmtp (Exim x.yz)
+ (envelope-from <CALLER@???>)
+ id 10HmbA-0005vi-00
+ for b@???; Tue, 2 Mar 1999 09:44:33 +0000
+DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=test.ex;
+ s=sel; h=From; bh=/Ab0giHZitYQbDhFszoqQRUkgqueaX9zatJttIU/plc=; b=toy5chxow6W
+ 7Nn3qMvjZs+i0H00bQfi+6nakV6i36cRrZM/oWziHrc5IfYZuQunWNUA9UHnatK35Nsl7ZJRBU4em
+ wtzdO60jXnH7ZVyYjKxqTow9uCuuBKCgXdKxt1hpEfY0m7uUKt9OaqA0464NH5wEC4o/pt1aReidE
+ hvI6IY=;
+DKIM-Signature: v=1; a=ed25519-sha256; q=dns/txt; c=relaxed/relaxed; d=test.ex
+ ; s=sed; h=From; bh=/Ab0giHZitYQbDhFszoqQRUkgqueaX9zatJttIU/plc=; b=IKNwoUbCe
+ ayHoA7j2L0IU1IFuapa3DrlNx9wPlBodM1iKJ57WGibKzefQNdTjymHPsMlQ9fS+h9ZSsHmVNBdDA
+ ==;
+Received: from CALLER by myhost.test.ex with local (Exim x.yz)
+ (envelope-from <CALLER@???>)
+ id 10HmaZ-0005vi-00
+ for b@???; Tue, 2 Mar 1999 09:44:33 +0000
+From: nobody@???
+Message-Id: <E10HmaZ-0005vi-00@???>
+Sender: CALLER_NAME <CALLER@???>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+content
+
diff --git a/test/scripts/4500-DKIM/4509 b/test/scripts/4500-DKIM/4509
new file mode 100644
index 0000000..c450d65
--- /dev/null
+++ b/test/scripts/4500-DKIM/4509
@@ -0,0 +1,41 @@
+# DKIM verify, dkim_verify_hashes option
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# This should not ve verified, as the config ignores the sha1 sig
+# - sha1, 1024b
+# Mail original in aux-fixed/4500.msg1.txt
+# Sig generated by: perl aux-fixed/dkim/sign.pl --method=simple/simple < aux-fixed/4500.msg1.txt
+client 127.0.0.1 PORT_D
+??? 220
+HELO xxx
+??? 250
+MAIL FROM:<CALLER@???>
+??? 250
+RCPT TO:<a@???>
+??? 250
+DATA
+??? 354
+DKIM-Signature: v=1; a=rsa-sha1; c=simple/simple; d=test.ex; h=from:to
+ :date:message-id:subject; s=sel; bh=OB9dZVu7+5/ufs3TH9leIcEpXSo=; b=
+ PeUA8iBGfStWv+9/BBKkvCEYj/AVMl4e9k+AqWOXKyuEUfHxqAnV+sPnOejpmvT8
+ 41kuM4u0bICvK371YvB/yO61vtliRhyqU76Y2e55p2uvMADb3UyDhLyzpco4+yBo
+ 1w0AuIxu0VU4TK8UmOLyCw/1hxrh1DcEInbEMEKJ7kI=
+From: mrgus@???
+To: bakawolf@???
+Date: Thu, 19 Nov 2015 17:00:07 -0700
+Message-ID: <qwerty1234@???>
+Subject: simple test
+
+This is a simple test.
+.
+??? 250
+QUIT
+??? 221
+****
+#
+killdaemon
+#
+no_stdout_check
+no_msglog_check
diff --git a/test/scripts/4540-DKIM-Ed25519/4541 b/test/scripts/4540-DKIM-Ed25519/4541
new file mode 100644
index 0000000..cec41df
--- /dev/null
+++ b/test/scripts/4540-DKIM-Ed25519/4541
@@ -0,0 +1,30 @@
+# DKIM verify, multiple and dkim_verify_minimal
+# This relies on multiple-signing working (4545 tests that)
+#
+# Verify both
+exim -bd -DSERVER=server -oX PORT_D
+****
+#
+exim -DSELECTOR=sel:sed -DOPT=From: -odf a@???
+From: nobody@???
+
+content
+****
+#
+millisleep 500
+killdaemon
+#
+#
+# Verify only EC sig
+exim -bd -DSERVER=server -DFILTER=y -oX PORT_D
+****
+#
+exim -DSELECTOR=sel:sed -DOPT=From: -odf b@???
+From: nobody@???
+
+content
+****
+#
+millisleep 500
+killdaemon
+no_msglog_check