summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2020-04-25 20:50:07 +0100
committerJeremy Harris <jgh146exb@wizmail.org>2020-04-26 12:40:34 +0100
commitbe24b950ae0db88b1c9811b3a028e95133c55efa (patch)
treedf0508c57dab4c921320107da467c7cb45bcd4cb /src
parenta841a6eca79ff08b36f2225dcf89c1c162bb8777 (diff)
DKIM: dkim_verify_min_keysizes option
Diffstat (limited to 'src')
-rw-r--r--src/src/dkim.c9
-rw-r--r--src/src/expand.c4
-rw-r--r--src/src/functions.h2
-rw-r--r--src/src/globals.c1
-rw-r--r--src/src/globals.h1
-rw-r--r--src/src/pdkim/pdkim.c14
-rw-r--r--src/src/pdkim/pdkim.h5
-rw-r--r--src/src/readconf.c1
8 files changed, 33 insertions, 4 deletions
diff --git a/src/src/dkim.c b/src/src/dkim.c
index 9c8458b87..17eb61603 100644
--- a/src/src/dkim.c
+++ b/src/src/dkim.c
@@ -268,6 +268,11 @@ else
"(headers probably modified in transit)]");
break;
+ case PDKIM_VERIFY_INVALID_PUBKEY_KEYSIZE:
+ logmsg = string_cat(logmsg,
+ US"signature invalid (key too short)]");
+ break;
+
default:
logmsg = string_cat(logmsg, US"unspecified reason]");
}
@@ -560,6 +565,7 @@ switch (what)
return US"pubkey_unavailable";
case PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD:return US"pubkey_dns_syntax";
case PDKIM_VERIFY_INVALID_PUBKEY_IMPORT: return US"pubkey_der_syntax";
+ case PDKIM_VERIFY_INVALID_PUBKEY_KEYSIZE: return US"pubkey_too_short";
case PDKIM_VERIFY_FAIL_BODY: return US"bodyhash_mismatch";
case PDKIM_VERIFY_FAIL_MESSAGE: return US"signature_incorrect";
}
@@ -854,6 +860,9 @@ for (pdkim_signature * sig = dkim_signatures; sig; sig = sig->next)
g = string_cat(g,
US"fail (signature did not verify; headers probably modified in transit)\n\t\t");
break;
+ case PDKIM_VERIFY_INVALID_PUBKEY_KEYSIZE: /* should this really be "polcy"? */
+ g = string_fmt_append(g, "fail (public key too short: %u bits)\n\t\t", sig->keybits);
+ break;
default:
g = string_cat(g, US"fail (unspecified reason)\n\t\t");
break;
diff --git a/src/src/expand.c b/src/src/expand.c
index 5ae74ef52..500b73916 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -1172,8 +1172,8 @@ Returns: NULL if the subfield was not found, or
a pointer to the subfield's data
*/
-static uschar *
-expand_getkeyed(uschar * key, const uschar * s)
+uschar *
+expand_getkeyed(const uschar * key, const uschar * s)
{
int length = Ustrlen(key);
Uskip_whitespace(&s);
diff --git a/src/src/functions.h b/src/src/functions.h
index 8ea5e4ef6..bb81655c2 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -242,6 +242,8 @@ extern BOOL expand_check_condition(uschar *, uschar *, uschar *);
extern uschar *expand_file_big_buffer(const uschar *);
extern uschar *expand_string(uschar *); /* public, cannot make const */
extern const uschar *expand_cstring(const uschar *); /* ... so use this one */
+extern uschar *expand_getkeyed(const uschar *, const uschar *);
+
extern uschar *expand_hide_passwords(uschar * );
extern uschar *expand_string_copy(const uschar *);
extern int_eximarith_t expand_string_integer(uschar *, BOOL);
diff --git a/src/src/globals.c b/src/src/globals.c
index b8bf7ced2..36ac24955 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -845,6 +845,7 @@ uschar *dkim_signing_domain = NULL;
uschar *dkim_signing_selector = NULL;
uschar *dkim_verify_hashes = US"sha256:sha512";
uschar *dkim_verify_keytypes = US"ed25519:rsa";
+uschar *dkim_verify_min_keysizes = US"rsa=1024 ed25519=250";
BOOL dkim_verify_minimal = FALSE;
uschar *dkim_verify_overall = NULL;
uschar *dkim_verify_signers = US"$dkim_signers";
diff --git a/src/src/globals.h b/src/src/globals.h
index b46e20be4..6b69fd66a 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -515,6 +515,7 @@ extern uschar *dkim_signing_domain; /* Expansion variable, domain used for si
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 uschar *dkim_verify_min_keysizes; /* list of minimum key sizes, keyed by algo */
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 */
diff --git a/src/src/pdkim/pdkim.c b/src/src/pdkim/pdkim.c
index 0d2674f50..f6d70bfc9 100644
--- a/src/src/pdkim/pdkim.c
+++ b/src/src/pdkim/pdkim.c
@@ -181,6 +181,7 @@ switch(ext_status)
case PDKIM_VERIFY_INVALID_BUFFER_SIZE: return "PDKIM_VERIFY_INVALID_BUFFER_SIZE";
case PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD: return "PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD";
case PDKIM_VERIFY_INVALID_PUBKEY_IMPORT: return "PDKIM_VERIFY_INVALID_PUBKEY_IMPORT";
+ case PDKIM_VERIFY_INVALID_PUBKEY_KEYSIZE: return "PDKIM_VERIFY_INVALID_PUBKEY_KEYSIZE";
case PDKIM_VERIFY_INVALID_SIGNATURE_ERROR: return "PDKIM_VERIFY_INVALID_SIGNATURE_ERROR";
case PDKIM_VERIFY_INVALID_DKIM_VERSION: return "PDKIM_VERIFY_INVALID_DKIM_VERSION";
default: return "PDKIM_VERIFY_UNKNOWN";
@@ -1886,6 +1887,19 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next)
sig->verify_ext_status = PDKIM_VERIFY_FAIL_MESSAGE;
goto NEXT_VERIFY;
}
+ if (*dkim_verify_min_keysizes)
+ {
+ unsigned minbits;
+ uschar * ss = expand_getkeyed(US pdkim_keytypes[sig->keytype],
+ dkim_verify_min_keysizes);
+ if (ss && (minbits = atoi(CS ss)) > sig->keybits)
+ {
+ DEBUG(D_acl) debug_printf("Key too short: Actual: %s %u Minima '%s'\n",
+ pdkim_keytypes[sig->keytype], sig->keybits, dkim_verify_min_keysizes);
+ sig->verify_status = PDKIM_VERIFY_FAIL;
+ sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_KEYSIZE;
+ }
+ }
/* We have a winner! (if bodyhash was correct earlier) */
diff --git a/src/src/pdkim/pdkim.h b/src/src/pdkim/pdkim.h
index 0b21df8ab..e79d71e6e 100644
--- a/src/src/pdkim/pdkim.h
+++ b/src/src/pdkim/pdkim.h
@@ -76,8 +76,9 @@
#define PDKIM_VERIFY_INVALID_BUFFER_SIZE 5
#define PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD 6
#define PDKIM_VERIFY_INVALID_PUBKEY_IMPORT 7
-#define PDKIM_VERIFY_INVALID_SIGNATURE_ERROR 8
-#define PDKIM_VERIFY_INVALID_DKIM_VERSION 9
+#define PDKIM_VERIFY_INVALID_PUBKEY_KEYSIZE 8
+#define PDKIM_VERIFY_INVALID_SIGNATURE_ERROR 9
+#define PDKIM_VERIFY_INVALID_DKIM_VERSION 10
/* -------------------------------------------------------------------------- */
/* Some parameter values */
diff --git a/src/src/readconf.c b/src/src/readconf.c
index 04b3e1161..a44f3223b 100644
--- a/src/src/readconf.c
+++ b/src/src/readconf.c
@@ -119,6 +119,7 @@ static optionlist optionlist_config[] = {
#ifndef DISABLE_DKIM
{ "dkim_verify_hashes", opt_stringptr, {&dkim_verify_hashes} },
{ "dkim_verify_keytypes", opt_stringptr, {&dkim_verify_keytypes} },
+ { "dkim_verify_min_keysizes", opt_stringptr, {&dkim_verify_min_keysizes} },
{ "dkim_verify_minimal", opt_bool, {&dkim_verify_minimal} },
{ "dkim_verify_signers", opt_stringptr, {&dkim_verify_signers} },
#endif