diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2020-07-09 13:39:39 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2020-07-09 13:39:39 +0300 |
commit | e87b7139c79c84d7af859c086002c1ead0ca21c9 (patch) | |
tree | b74bb04d7551eca7bd2e127c2a4b2ce7865a061e /src | |
parent | d4c5c2c98e8b5f90a4d3f61fc618e9001685aa38 (diff) | |
download | mailfromd-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.c | 39 |
1 files changed, 33 insertions, 6 deletions
@@ -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); |