diff options
author | Jeremy Harris <jgh146exb@wizmail.org> | 2020-04-25 20:50:07 +0100 |
---|---|---|
committer | Jeremy Harris <jgh146exb@wizmail.org> | 2020-04-26 12:40:34 +0100 |
commit | be24b950ae0db88b1c9811b3a028e95133c55efa (patch) | |
tree | df0508c57dab4c921320107da467c7cb45bcd4cb /src | |
parent | a841a6eca79ff08b36f2225dcf89c1c162bb8777 (diff) |
DKIM: dkim_verify_min_keysizes option
Diffstat (limited to 'src')
-rw-r--r-- | src/src/dkim.c | 9 | ||||
-rw-r--r-- | src/src/expand.c | 4 | ||||
-rw-r--r-- | src/src/functions.h | 2 | ||||
-rw-r--r-- | src/src/globals.c | 1 | ||||
-rw-r--r-- | src/src/globals.h | 1 | ||||
-rw-r--r-- | src/src/pdkim/pdkim.c | 14 | ||||
-rw-r--r-- | src/src/pdkim/pdkim.h | 5 | ||||
-rw-r--r-- | src/src/readconf.c | 1 |
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 |