aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2020-07-09 13:39:39 +0300
committerSergey Poznyakoff <gray@gnu.org>2020-07-09 13:39:39 +0300
commite87b7139c79c84d7af859c086002c1ead0ca21c9 (patch)
treeb74bb04d7551eca7bd2e127c2a4b2ce7865a061e /src
parentd4c5c2c98e8b5f90a4d3f61fc618e9001685aa38 (diff)
downloadmailfromd-e87b7139c79c84d7af859c086002c1ead0ca21c9.tar.gz
mailfromd-e87b7139c79c84d7af859c086002c1ead0ca21c9.tar.bz2
DKIM: Fix verification in case of wrapped DKIM-Signature
* src/dkim.c: tranlsate lf->crlf before hashing
Diffstat (limited to 'src')
-rw-r--r--src/dkim.c39
1 files changed, 33 insertions, 6 deletions
diff --git a/src/dkim.c b/src/dkim.c
index 8bf7c906..37038774 100644
--- a/src/dkim.c
+++ b/src/dkim.c
@@ -840,7 +840,8 @@ dkim_tag_find(char const *sigstr, char const *tag, size_t *ret_len)
size_t sig_len = strlen(sigstr);
for (i = 0; i + tag_len + 1 < sig_len; i++) {
- if (!(sigstr[i] == ' ' || sigstr[i] == '\t')) {
+ if (!(sigstr[i] == ' ' || sigstr[i] == '\t' ||
+ sigstr[i] == '\r' || sigstr[i] == '\n')) {
size_t n = strcspn(sigstr + i, ";");
if (memcmp(sigstr + i, tag, tag_len) == 0 &&
sigstr[i + tag_len] == '=') {
@@ -1072,6 +1073,17 @@ end:
mu_error("dkim_canonicalizer_create: %s", mu_strerror(rc));
goto err;
}
+
+ rc = mu_filter_create(&str, sigcanon, "CRLF", MU_FILTER_ENCODE,
+ MU_STREAM_READ);
+ mu_stream_unref(sigcanon);
+ if (rc) {
+ mu_diag_funcall(MU_DIAG_ERROR,
+ "mu_filter_stream_create", NULL, c);
+ goto err;
+ }
+ sigcanon = str;
+
hash_stream(sigcanon, ctx);
mu_stream_unref(sigcanon);
free(sig_str_buf);
@@ -1317,7 +1329,6 @@ pubkey_validate(mu_assoc_t a, struct dkim_signature const *sig)
static int
dkim_sig_key_verify(mu_message_t msg, struct dkim_signature *sig,
- char const *sigstr,
struct rsa_public_key *pub)
{
struct sha256_ctx ctx;
@@ -1325,7 +1336,23 @@ dkim_sig_key_verify(mu_message_t msg, struct dkim_signature *sig,
int rc;
struct nettle_buffer buffer;
size_t length;
-
+ mu_header_t hdr;
+ char const *sigstr;
+
+ rc = mu_message_get_header(msg, &hdr);
+ if (rc) {
+ mu_diag_funcall(MU_DIAG_ERROR,
+ "mu_message_get_header", NULL, rc);
+ return DKIM_EXPL_INTERNAL_ERROR;
+ }
+ rc = mu_header_sget_value(hdr, DKIM_SIGNATURE_HEADER, &sigstr);
+ if (rc) {
+ mu_diag_funcall(MU_DIAG_ERROR,
+ "mu_header_sget_value",
+ DKIM_SIGNATURE_HEADER, rc);
+ return DKIM_EXPL_INTERNAL_ERROR;
+ }
+
sha256_init(&ctx);
switch (dkim_hash(msg, sig, sigstr, &ctx)) {
case DKIM_HASH_OK:
@@ -1353,7 +1380,7 @@ dkim_sig_key_verify(mu_message_t msg, struct dkim_signature *sig,
}
static int
-dkim_sig_verify(mu_message_t msg, struct dkim_signature *sig, char *sig_str)
+dkim_sig_verify(mu_message_t msg, struct dkim_signature *sig)
{
char **dnsrec;
int i;
@@ -1385,7 +1412,7 @@ dkim_sig_verify(mu_message_t msg, struct dkim_signature *sig, char *sig_str)
!= READ_PEM_OK) {
result = DKIM_EXPL_KEY_SYNTAX;
} else {
- result = dkim_sig_key_verify(msg, sig, sig_str, &pub);
+ result = dkim_sig_key_verify(msg, sig, &pub);
rsa_public_key_clear(&pub);
}
mu_assoc_destroy(&a);
@@ -1442,7 +1469,7 @@ mfd_dkim_verify(mu_message_t msg)
/* Validate the signature */
result = dkim_sig_validate(&sig);
if (result == DKIM_EXPL_OK)
- result = dkim_sig_verify(msg, &sig, sig_str);
+ result = dkim_sig_verify(msg, &sig);
dkim_signature_free(&sig);
}
free(sig_str);

Return to:

Send suggestions and report system problems to the System administrator.