2 * PDKIM - a RFC4871 (DKIM) implementation
4 * Copyright (C) 2009 - 2016 Tom Kistner <tom@duncanthrax.net>
5 * Copyright (C) 2016 - 2020 Jeremy Harris <jgh@exim.org>
6 * Copyright (c) The Exim Maintainers 2021
8 * http://duncanthrax.net/pdkim/
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #ifndef DISABLE_DKIM /* entire file */
31 # error Must not DISABLE_TLS, for DKIM
34 #include "crypt_ver.h"
37 # include <openssl/rsa.h>
38 # include <openssl/ssl.h>
39 # include <openssl/err.h>
40 #elif defined(SIGN_GNUTLS)
41 # include <gnutls/gnutls.h>
42 # include <gnutls/x509.h>
48 #define PDKIM_SIGNATURE_VERSION "1"
49 #define PDKIM_PUB_RECORD_VERSION US "DKIM1"
51 #define PDKIM_MAX_HEADER_LEN 65536
52 #define PDKIM_MAX_HEADERS 512
53 #define PDKIM_MAX_BODY_LINE_LEN 16384
54 #define PDKIM_DNS_TXT_MAX_NAMELEN 1024
56 /* -------------------------------------------------------------------------- */
57 struct pdkim_stringlist {
63 /* -------------------------------------------------------------------------- */
64 /* A bunch of list constants */
65 const uschar * pdkim_querymethods[] = {
69 const uschar * pdkim_canons[] = {
75 const pdkim_hashtype pdkim_hashes[] = {
76 { US"sha1", HASH_SHA1 },
77 { US"sha256", HASH_SHA2_256 },
78 { US"sha512", HASH_SHA2_512 }
81 const uschar * pdkim_keytypes[] = {
82 [KEYTYPE_RSA] = US"rsa",
83 #ifdef SIGN_HAVE_ED25519
84 [KEYTYPE_ED25519] = US"ed25519", /* Works for 3.6.0 GnuTLS, OpenSSL 1.1.1 */
87 #ifdef notyet_EC_dkim_extensions /* https://tools.ietf.org/html/draft-srose-dkim-ecc-00 */
94 typedef struct pdkim_combined_canon_entry {
98 } pdkim_combined_canon_entry;
100 pdkim_combined_canon_entry pdkim_combined_canons[] = {
101 { US"simple/simple", PDKIM_CANON_SIMPLE, PDKIM_CANON_SIMPLE },
102 { US"simple/relaxed", PDKIM_CANON_SIMPLE, PDKIM_CANON_RELAXED },
103 { US"relaxed/simple", PDKIM_CANON_RELAXED, PDKIM_CANON_SIMPLE },
104 { US"relaxed/relaxed", PDKIM_CANON_RELAXED, PDKIM_CANON_RELAXED },
105 { US"simple", PDKIM_CANON_SIMPLE, PDKIM_CANON_SIMPLE },
106 { US"relaxed", PDKIM_CANON_RELAXED, PDKIM_CANON_SIMPLE },
111 static const blob lineending = {.data = US"\r\n", .len = 2};
113 /* -------------------------------------------------------------------------- */
115 dkim_sig_to_a_tag(const pdkim_signature * sig)
117 if ( sig->keytype < 0 || sig->keytype > nelem(pdkim_keytypes)
118 || sig->hashtype < 0 || sig->hashtype > nelem(pdkim_hashes))
120 return string_sprintf("%s-%s",
121 pdkim_keytypes[sig->keytype], pdkim_hashes[sig->hashtype].dkim_hashname);
126 pdkim_keyname_to_keytype(const uschar * s)
128 for (int i = 0; i < nelem(pdkim_keytypes); i++)
129 if (Ustrcmp(s, pdkim_keytypes[i]) == 0) return i;
134 pdkim_hashname_to_hashtype(const uschar * s, unsigned len)
136 if (!len) len = Ustrlen(s);
137 for (int i = 0; i < nelem(pdkim_hashes); i++)
138 if (Ustrncmp(s, pdkim_hashes[i].dkim_hashname, len) == 0)
144 pdkim_cstring_to_canons(const uschar * s, unsigned len,
145 int * canon_head, int * canon_body)
147 if (!len) len = Ustrlen(s);
148 for (int i = 0; pdkim_combined_canons[i].str; i++)
149 if ( Ustrncmp(s, pdkim_combined_canons[i].str, len) == 0
150 && len == Ustrlen(pdkim_combined_canons[i].str))
152 *canon_head = pdkim_combined_canons[i].canon_headers;
153 *canon_body = pdkim_combined_canons[i].canon_body;
161 pdkim_verify_status_str(int status)
165 case PDKIM_VERIFY_NONE: return "PDKIM_VERIFY_NONE";
166 case PDKIM_VERIFY_INVALID: return "PDKIM_VERIFY_INVALID";
167 case PDKIM_VERIFY_FAIL: return "PDKIM_VERIFY_FAIL";
168 case PDKIM_VERIFY_PASS: return "PDKIM_VERIFY_PASS";
169 default: return "PDKIM_VERIFY_UNKNOWN";
174 pdkim_verify_ext_status_str(int ext_status)
178 case PDKIM_VERIFY_FAIL_BODY: return "PDKIM_VERIFY_FAIL_BODY";
179 case PDKIM_VERIFY_FAIL_MESSAGE: return "PDKIM_VERIFY_FAIL_MESSAGE";
180 case PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH: return "PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH";
181 case PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE: return "PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE";
182 case PDKIM_VERIFY_INVALID_BUFFER_SIZE: return "PDKIM_VERIFY_INVALID_BUFFER_SIZE";
183 case PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD: return "PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD";
184 case PDKIM_VERIFY_INVALID_PUBKEY_IMPORT: return "PDKIM_VERIFY_INVALID_PUBKEY_IMPORT";
185 case PDKIM_VERIFY_INVALID_PUBKEY_KEYSIZE: return "PDKIM_VERIFY_INVALID_PUBKEY_KEYSIZE";
186 case PDKIM_VERIFY_INVALID_SIGNATURE_ERROR: return "PDKIM_VERIFY_INVALID_SIGNATURE_ERROR";
187 case PDKIM_VERIFY_INVALID_DKIM_VERSION: return "PDKIM_VERIFY_INVALID_DKIM_VERSION";
188 default: return "PDKIM_VERIFY_UNKNOWN";
193 pdkim_errstr(int status)
197 case PDKIM_OK: return US"OK";
198 case PDKIM_FAIL: return US"FAIL";
199 case PDKIM_ERR_RSA_PRIVKEY: return US"PRIVKEY";
200 case PDKIM_ERR_RSA_SIGNING: return US"SIGNING";
201 case PDKIM_ERR_LONG_LINE: return US"LONG_LINE";
202 case PDKIM_ERR_BUFFER_TOO_SMALL: return US"BUFFER_TOO_SMALL";
203 case PDKIM_ERR_EXCESS_SIGS: return US"EXCESS_SIGS";
204 case PDKIM_SIGN_PRIVKEY_WRAP: return US"PRIVKEY_WRAP";
205 case PDKIM_SIGN_PRIVKEY_B64D: return US"PRIVKEY_B64D";
206 default: return US"(unknown)";
211 /* -------------------------------------------------------------------------- */
212 /* Print debugging functions */
214 pdkim_quoteprint(const uschar *data, int len)
216 for (int i = 0; i < len; i++)
218 const int c = data[i];
221 case ' ' : debug_printf("{SP}"); break;
222 case '\t': debug_printf("{TB}"); break;
223 case '\r': debug_printf("{CR}"); break;
224 case '\n': debug_printf("{LF}"); break;
225 case '{' : debug_printf("{BO}"); break;
226 case '}' : debug_printf("{BC}"); break;
228 if ( (c < 32) || (c > 127) )
229 debug_printf("{%02x}", c);
231 debug_printf("%c", c);
239 pdkim_hexprint(const uschar *data, int len)
241 if (data) for (int i = 0 ; i < len; i++) debug_printf("%02x", data[i]);
242 else debug_printf("<NULL>");
248 static pdkim_stringlist *
249 pdkim_prepend_stringlist(pdkim_stringlist * base, const uschar * str)
251 pdkim_stringlist * new_entry = store_get(sizeof(pdkim_stringlist), FALSE);
253 memset(new_entry, 0, sizeof(pdkim_stringlist));
254 new_entry->value = string_copy(str);
255 if (base) new_entry->next = base;
261 /* Trim whitespace fore & aft */
264 pdkim_strtrim(gstring * str)
269 while (*p == '\t' || *p == ' ') /* dump the leading whitespace */
270 { str->size--; str->ptr--; str->s++; }
273 && ((q = str->s + str->ptr - 1), (*q == '\t' || *q == ' '))
275 str->ptr--; /* dump trailing whitespace */
277 (void) string_from_gstring(str);
282 /* -------------------------------------------------------------------------- */
285 pdkim_free_ctx(pdkim_ctx *ctx)
290 /* -------------------------------------------------------------------------- */
291 /* Matches the name of the passed raw "header" against
292 the passed colon-separated "tick", and invalidates
293 the entry in tick. Entries can be prefixed for multi- or over-signing,
294 in which case do not invalidate.
296 Returns OK for a match, or fail-code
300 header_name_match(const uschar * header, uschar * tick)
302 const uschar * ticklist = tick;
305 uschar * hname, * p, * ele;
306 uschar * hcolon = Ustrchr(header, ':'); /* Get header name */
309 return PDKIM_FAIL; /* This isn't a header */
311 /* if we had strncmpic() we wouldn't need this copy */
312 hname = string_copyn(header, hcolon-header);
314 while (p = US ticklist, ele = string_nextinlist(&ticklist, &sep, NULL, 0))
318 case '=': case '+': multisign = TRUE; ele++; break;
319 default: multisign = FALSE; break;
322 if (strcmpic(ele, hname) == 0)
325 *p = '_'; /* Invalidate this header name instance in tick-off list */
333 /* -------------------------------------------------------------------------- */
334 /* Performs "relaxed" canonicalization of a header. */
337 pdkim_relax_header_n(const uschar * header, int len, BOOL append_crlf)
339 BOOL past_field_name = FALSE;
340 BOOL seen_wsp = FALSE;
341 uschar * relaxed = store_get(len+3, TRUE); /* tainted */
342 uschar * q = relaxed;
344 for (const uschar * p = header; p - header < len; p++)
348 if (c == '\r' || c == '\n') /* Ignore CR & LF */
350 if (c == '\t' || c == ' ')
354 c = ' '; /* Turns WSP into SP */
358 if (!past_field_name && c == ':')
360 if (seen_wsp) q--; /* This removes WSP immediately before the colon */
361 seen_wsp = TRUE; /* This removes WSP immediately after the colon */
362 past_field_name = TRUE;
367 /* Lowercase header name */
368 if (!past_field_name) c = tolower(c);
372 if (q > relaxed && q[-1] == ' ') q--; /* Squash eventual trailing SP */
374 if (append_crlf) { *q++ = '\r'; *q++ = '\n'; }
381 pdkim_relax_header(const uschar * header, BOOL append_crlf)
383 return pdkim_relax_header_n(header, Ustrlen(header), append_crlf);
387 /* -------------------------------------------------------------------------- */
388 #define PDKIM_QP_ERROR_DECODE -1
390 static const uschar *
391 pdkim_decode_qp_char(const uschar *qp_p, int *c)
393 const uschar *initial_pos = qp_p;
395 /* Advance one char */
398 /* Check for two hex digits and decode them */
399 if (isxdigit(*qp_p) && isxdigit(qp_p[1]))
401 /* Do hex conversion */
402 *c = (isdigit(*qp_p) ? *qp_p - '0' : toupper(*qp_p) - 'A' + 10) << 4;
403 *c |= isdigit(qp_p[1]) ? qp_p[1] - '0' : toupper(qp_p[1]) - 'A' + 10;
407 /* Illegal char here */
408 *c = PDKIM_QP_ERROR_DECODE;
413 /* -------------------------------------------------------------------------- */
416 pdkim_decode_qp(const uschar * str)
420 const uschar * p = str;
421 uschar * n = store_get(Ustrlen(str)+1, TRUE);
429 p = pdkim_decode_qp_char(p, &nchar);
445 /* -------------------------------------------------------------------------- */
448 pdkim_decode_base64(const uschar * str, blob * b)
450 int dlen = b64decode(str, &b->data);
451 if (dlen < 0) b->data = NULL;
456 pdkim_encode_base64(blob * b)
458 return b64encode(CUS b->data, b->len);
462 /* -------------------------------------------------------------------------- */
463 #define PDKIM_HDR_LIMBO 0
464 #define PDKIM_HDR_TAG 1
465 #define PDKIM_HDR_VALUE 2
467 static pdkim_signature *
468 pdkim_parse_sig_header(pdkim_ctx * ctx, uschar * raw_hdr)
470 pdkim_signature * sig;
472 gstring * cur_tag = NULL;
473 gstring * cur_val = NULL;
474 BOOL past_hname = FALSE;
475 BOOL in_b_val = FALSE;
476 int where = PDKIM_HDR_LIMBO;
478 sig = store_get(sizeof(pdkim_signature), FALSE);
479 memset(sig, 0, sizeof(pdkim_signature));
480 sig->bodylength = -1;
482 /* Set so invalid/missing data error display is accurate */
487 q = sig->rawsig_no_b_val = store_get(Ustrlen(raw_hdr)+1, TRUE); /* tainted */
489 for (uschar * p = raw_hdr; ; p++)
494 if (c == '\r' || c == '\n')
497 /* Fast-forward through header name */
500 if (c == ':') past_hname = TRUE;
504 if (where == PDKIM_HDR_LIMBO)
506 /* In limbo, just wait for a tag-char to appear */
507 if (!(c >= 'a' && c <= 'z'))
510 where = PDKIM_HDR_TAG;
513 if (where == PDKIM_HDR_TAG)
515 if (c >= 'a' && c <= 'z')
516 cur_tag = string_catn(cur_tag, p, 1);
520 if (Ustrcmp(string_from_gstring(cur_tag), "b") == 0)
525 where = PDKIM_HDR_VALUE;
530 if (where == PDKIM_HDR_VALUE)
532 if (c == '\r' || c == '\n' || c == ' ' || c == '\t')
535 if (c == ';' || c == '\0')
537 /* We must have both tag and value, and tags must be one char except
538 for the possibility of "bh". */
540 if ( cur_tag && cur_val
541 && (cur_tag->ptr == 1 || *cur_tag->s == 'b')
544 (void) string_from_gstring(cur_val);
545 pdkim_strtrim(cur_val);
547 DEBUG(D_acl) debug_printf(" %s=%s\n", cur_tag->s, cur_val->s);
551 case 'b': /* sig-data or body-hash */
552 switch (cur_tag->s[1])
554 case '\0': pdkim_decode_base64(cur_val->s, &sig->sighash); break;
555 case 'h': if (cur_tag->ptr == 2)
556 pdkim_decode_base64(cur_val->s, &sig->bodyhash);
561 case 'v': /* version */
562 /* We only support version 1, and that is currently the
563 only version there is. */
565 Ustrcmp(cur_val->s, PDKIM_SIGNATURE_VERSION) == 0 ? 1 : -1;
567 case 'a': /* algorithm */
569 const uschar * list = cur_val->s;
573 if ((elem = string_nextinlist(&list, &sep, NULL, 0)))
574 sig->keytype = pdkim_keyname_to_keytype(elem);
575 if ((elem = string_nextinlist(&list, &sep, NULL, 0)))
576 for (int i = 0; i < nelem(pdkim_hashes); i++)
577 if (Ustrcmp(elem, pdkim_hashes[i].dkim_hashname) == 0)
578 { sig->hashtype = i; break; }
581 case 'c': /* canonicalization */
582 pdkim_cstring_to_canons(cur_val->s, 0,
583 &sig->canon_headers, &sig->canon_body);
585 case 'q': /* Query method (for pubkey)*/
586 for (int i = 0; pdkim_querymethods[i]; i++)
587 if (Ustrcmp(cur_val->s, pdkim_querymethods[i]) == 0)
589 sig->querymethod = i; /* we never actually use this */
593 case 's': /* Selector */
594 sig->selector = string_copyn(cur_val->s, cur_val->ptr); break;
596 sig->domain = string_copyn(cur_val->s, cur_val->ptr); break;
598 sig->identity = pdkim_decode_qp(cur_val->s); break;
599 case 't': /* Timestamp */
600 sig->created = strtoul(CS cur_val->s, NULL, 10); break;
601 case 'x': /* Expiration */
602 sig->expires = strtoul(CS cur_val->s, NULL, 10); break;
603 case 'l': /* Body length count */
604 sig->bodylength = strtol(CS cur_val->s, NULL, 10); break;
605 case 'h': /* signed header fields */
606 sig->headernames = string_copyn(cur_val->s, cur_val->ptr); break;
607 case 'z': /* Copied headfields */
608 sig->copiedheaders = pdkim_decode_qp(cur_val->s); break;
609 /*XXX draft-ietf-dcrup-dkim-crypto-05 would need 'p' tag support
610 for rsafp signatures. But later discussion is dropping those. */
612 DEBUG(D_acl) debug_printf(" Unknown tag encountered\n");
616 cur_tag = cur_val = NULL;
618 where = PDKIM_HDR_LIMBO;
621 cur_val = string_catn(cur_val, p, 1);
632 if (sig->keytype < 0 || sig->hashtype < 0) /* Cannot verify this signature */
636 /* Chomp raw header. The final newline must not be added to the signature. */
637 while (--q > sig->rawsig_no_b_val && (*q == '\r' || *q == '\n'))
643 "DKIM >> Raw signature w/o b= tag value >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
644 pdkim_quoteprint(US sig->rawsig_no_b_val, Ustrlen(sig->rawsig_no_b_val));
646 "DKIM >> Sig size: %4u bits\n", (unsigned) sig->sighash.len*8);
648 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
651 if (!pdkim_set_sig_bodyhash(ctx, sig))
658 /* -------------------------------------------------------------------------- */
661 pdkim_parse_pubkey_record(const uschar *raw_record)
667 pub = store_get(sizeof(pdkim_pubkey), TRUE); /* tainted */
668 memset(pub, 0, sizeof(pdkim_pubkey));
670 while ((ele = string_nextinlist(&raw_record, &sep, NULL, 0)))
674 if ((val = Ustrchr(ele, '=')))
676 int taglen = val++ - ele;
678 DEBUG(D_acl) debug_printf(" %.*s=%s\n", taglen, ele, val);
681 case 'v': pub->version = val; break;
682 case 'h': pub->hashes = val; break;
683 case 'k': pub->keytype = val; break;
684 case 'g': pub->granularity = val; break;
685 case 'n': pub->notes = pdkim_decode_qp(val); break;
686 case 'p': pdkim_decode_base64(val, &pub->key); break;
687 case 's': pub->srvtype = val; break;
688 case 't': if (Ustrchr(val, 'y')) pub->testing = 1;
689 if (Ustrchr(val, 's')) pub->no_subdomaining = 1;
691 default: DEBUG(D_acl) debug_printf(" Unknown tag encountered\n"); break;
696 /* Set fallback defaults */
698 pub->version = string_copy(PDKIM_PUB_RECORD_VERSION);
699 else if (Ustrcmp(pub->version, PDKIM_PUB_RECORD_VERSION) != 0)
701 DEBUG(D_acl) debug_printf(" Bad v= field\n");
705 if (!pub->granularity) pub->granularity = US"*";
706 if (!pub->keytype ) pub->keytype = US"rsa";
707 if (!pub->srvtype ) pub->srvtype = US"*";
713 DEBUG(D_acl) debug_printf(" Missing p= field\n");
718 /* -------------------------------------------------------------------------- */
720 /* Update one bodyhash with some additional data.
721 If we have to relax the data for this sig, return our copy of it. */
724 pdkim_update_ctx_bodyhash(pdkim_bodyhash * b, const blob * orig_data, blob * relaxed_data)
726 const blob * canon_data = orig_data;
729 /* Defaults to simple canon (no further treatment necessary) */
731 if (b->canon_method == PDKIM_CANON_RELAXED)
733 /* Relax the line if not done already */
736 BOOL seen_wsp = FALSE;
739 /* We want to be able to free this else we allocate
740 for the entire message which could be many MB. Since
741 we don't know what allocations the SHA routines might
742 do, not safe to use store_get()/store_reset(). */
744 relaxed_data = store_malloc(sizeof(blob) + orig_data->len+1);
745 relaxed_data->data = US (relaxed_data+1);
747 for (const uschar * p = orig_data->data, * r = p + orig_data->len; p < r; p++)
752 if (q > 0 && relaxed_data->data[q-1] == ' ')
755 else if (c == '\t' || c == ' ')
757 c = ' '; /* Turns WSP into SP */
764 relaxed_data->data[q++] = c;
766 relaxed_data->data[q] = '\0';
767 relaxed_data->len = q;
769 canon_data = relaxed_data;
772 /* Make sure we don't exceed the to-be-signed body length */
773 left = canon_data->len;
774 if ( b->bodylength >= 0
775 && left > (unsigned long)b->bodylength - b->signed_body_bytes
777 left = (unsigned long)b->bodylength - b->signed_body_bytes;
781 exim_sha_update(&b->body_hash_ctx, CUS canon_data->data, left);
782 b->signed_body_bytes += left;
783 DEBUG(D_acl) pdkim_quoteprint(canon_data->data, left);
790 /* -------------------------------------------------------------------------- */
793 pdkim_finish_bodyhash(pdkim_ctx * ctx)
795 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next) /* Finish hashes */
797 DEBUG(D_acl) debug_printf("DKIM: finish bodyhash %d/%d/%ld len %ld\n",
798 b->hashtype, b->canon_method, b->bodylength, b->signed_body_bytes);
799 exim_sha_finish(&b->body_hash_ctx, &b->bh);
802 /* Traverse all signatures */
803 for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next)
805 pdkim_bodyhash * b = sig->calc_body_hash;
809 debug_printf("DKIM [%s] Body bytes (%s) hashed: %lu\n"
810 "DKIM [%s] Body %s computed: ",
811 sig->domain, pdkim_canons[b->canon_method], b->signed_body_bytes,
812 sig->domain, pdkim_hashes[b->hashtype].dkim_hashname);
813 pdkim_hexprint(CUS b->bh.data, b->bh.len);
816 /* SIGNING -------------------------------------------------------------- */
817 if (ctx->flags & PDKIM_MODE_SIGN)
819 /* If bodylength limit is set, and we have received less bytes
820 than the requested amount, effectively remove the limit tag. */
821 if (b->signed_body_bytes < sig->bodylength)
822 sig->bodylength = -1;
826 /* VERIFICATION --------------------------------------------------------- */
827 /* Be careful that the header sig included a bodyash */
829 if (sig->bodyhash.data && sig->bodyhash.len == b->bh.len
830 && memcmp(b->bh.data, sig->bodyhash.data, b->bh.len) == 0)
832 DEBUG(D_acl) debug_printf("DKIM [%s] Body hash compared OK\n", sig->domain);
838 debug_printf("DKIM [%s] Body hash signature from headers: ", sig->domain);
839 pdkim_hexprint(sig->bodyhash.data, sig->bodyhash.len);
840 debug_printf("DKIM [%s] Body hash did NOT verify\n", sig->domain);
842 sig->verify_status = PDKIM_VERIFY_FAIL;
843 sig->verify_ext_status = PDKIM_VERIFY_FAIL_BODY;
851 pdkim_body_complete(pdkim_ctx * ctx)
853 /* In simple body mode, if any empty lines were buffered,
854 replace with one. rfc 4871 3.4.3 */
855 /*XXX checking the signed-body-bytes is a gross hack; I think
856 it indicates that all linebreaks should be buffered, including
857 the one terminating a text line */
859 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
860 if ( b->canon_method == PDKIM_CANON_SIMPLE
861 && b->signed_body_bytes == 0
862 && b->num_buffered_blanklines > 0
864 (void) pdkim_update_ctx_bodyhash(b, &lineending, NULL);
866 ctx->flags |= PDKIM_SEEN_EOD;
867 ctx->linebuf_offset = 0;
872 /* -------------------------------------------------------------------------- */
873 /* Call from pdkim_feed below for processing complete body lines */
874 /* NOTE: the line is not NUL-terminated; but we have a count */
877 pdkim_bodyline_complete(pdkim_ctx * ctx)
879 blob line = {.data = ctx->linebuf, .len = ctx->linebuf_offset};
883 /* Ignore extra data if we've seen the end-of-data marker */
884 if (ctx->flags & PDKIM_SEEN_EOD) goto all_skip;
886 /* We've always got one extra byte to stuff a zero ... */
887 ctx->linebuf[line.len] = '\0';
889 /* Terminate on EOD marker */
890 if (ctx->flags & PDKIM_DOT_TERM)
892 if (memcmp(line.data, ".\r\n", 3) == 0)
893 { pdkim_body_complete(ctx); return; }
896 if (memcmp(line.data, "..", 2) == 0)
897 { line.data++; line.len--; }
900 /* Empty lines need to be buffered until we find a non-empty line */
901 if (memcmp(line.data, "\r\n", 2) == 0)
903 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
904 b->num_buffered_blanklines++;
908 /* Process line for each bodyhash separately */
909 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
911 if (b->canon_method == PDKIM_CANON_RELAXED)
913 /* Lines with just spaces need to be buffered too */
914 uschar * cp = line.data;
919 if (c == '\r' && cp[1] == '\n') break;
920 if (c != ' ' && c != '\t') goto hash_process;
924 b->num_buffered_blanklines++;
929 /* At this point, we have a non-empty line, so release the buffered ones. */
931 while (b->num_buffered_blanklines)
933 rnl = pdkim_update_ctx_bodyhash(b, &lineending, rnl);
934 b->num_buffered_blanklines--;
937 rline = pdkim_update_ctx_bodyhash(b, &line, rline);
941 if (rnl) store_free(rnl);
942 if (rline) store_free(rline);
946 ctx->linebuf_offset = 0;
951 /* -------------------------------------------------------------------------- */
952 /* Callback from pdkim_feed below for processing complete headers */
953 #define DKIM_SIGNATURE_HEADERNAME "DKIM-Signature:"
956 pdkim_header_complete(pdkim_ctx * ctx)
958 if ( (ctx->cur_header->ptr > 1) &&
959 (ctx->cur_header->s[ctx->cur_header->ptr-1] == '\r') )
960 --ctx->cur_header->ptr;
961 (void) string_from_gstring(ctx->cur_header);
963 #ifdef EXPERIMENTAL_ARC
964 /* Feed the header line to ARC processing */
965 (void) arc_header_feed(ctx->cur_header, !(ctx->flags & PDKIM_MODE_SIGN));
968 if (++ctx->num_headers > PDKIM_MAX_HEADERS) goto BAIL;
970 /* SIGNING -------------------------------------------------------------- */
971 if (ctx->flags & PDKIM_MODE_SIGN)
972 for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) /* Traverse all signatures */
974 /* Add header to the signed headers list (in reverse order) */
975 sig->headers = pdkim_prepend_stringlist(sig->headers, ctx->cur_header->s);
977 /* VERIFICATION ----------------------------------------------------------- */
978 /* DKIM-Signature: headers are added to the verification list */
984 debug_printf("DKIM >> raw hdr: ");
985 pdkim_quoteprint(CUS ctx->cur_header->s, ctx->cur_header->ptr);
988 if (strncasecmp(CCS ctx->cur_header->s,
989 DKIM_SIGNATURE_HEADERNAME,
990 Ustrlen(DKIM_SIGNATURE_HEADERNAME)) == 0)
992 pdkim_signature * sig, * last_sig;
993 /* Create and chain new signature block. We could error-check for all
994 required tags here, but prefer to create the internal sig and expicitly
995 fail verification of it later. */
997 DEBUG(D_acl) debug_printf(
998 "DKIM >> Found sig, trying to parse >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1000 sig = pdkim_parse_sig_header(ctx, ctx->cur_header->s);
1002 if (!(last_sig = ctx->sig))
1006 while (last_sig->next) last_sig = last_sig->next;
1007 last_sig->next = sig;
1010 if (dkim_collect_input && --dkim_collect_input == 0)
1012 ctx->headers = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->s);
1013 ctx->cur_header->s[ctx->cur_header->ptr = 0] = '\0';
1014 return PDKIM_ERR_EXCESS_SIGS;
1018 /* all headers are stored for signature verification */
1019 ctx->headers = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->s);
1023 ctx->cur_header->s[ctx->cur_header->ptr = 0] = '\0'; /* leave buffer for reuse */
1029 /* -------------------------------------------------------------------------- */
1030 #define HEADER_BUFFER_FRAG_SIZE 256
1033 pdkim_feed(pdkim_ctx * ctx, uschar * data, int len)
1035 /* Alternate EOD signal, used in non-dotstuffing mode */
1037 pdkim_body_complete(ctx);
1039 else for (int p = 0; p < len; p++)
1044 if (ctx->flags & PDKIM_PAST_HDRS)
1046 if (c == '\n' && !(ctx->flags & PDKIM_SEEN_CR)) /* emulate the CR */
1048 ctx->linebuf[ctx->linebuf_offset++] = '\r';
1049 if (ctx->linebuf_offset == PDKIM_MAX_BODY_LINE_LEN-1)
1050 return PDKIM_ERR_LONG_LINE;
1053 /* Processing body byte */
1054 ctx->linebuf[ctx->linebuf_offset++] = c;
1056 ctx->flags |= PDKIM_SEEN_CR;
1059 ctx->flags &= ~PDKIM_SEEN_CR;
1060 pdkim_bodyline_complete(ctx);
1063 if (ctx->linebuf_offset == PDKIM_MAX_BODY_LINE_LEN-1)
1064 return PDKIM_ERR_LONG_LINE;
1068 /* Processing header byte */
1070 ctx->flags |= PDKIM_SEEN_CR;
1073 if (!(ctx->flags & PDKIM_SEEN_CR)) /* emulate the CR */
1074 ctx->cur_header = string_catn(ctx->cur_header, CUS "\r", 1);
1076 if (ctx->flags & PDKIM_SEEN_LF) /* Seen last header line */
1078 if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1081 ctx->flags = (ctx->flags & ~(PDKIM_SEEN_LF|PDKIM_SEEN_CR)) | PDKIM_PAST_HDRS;
1082 DEBUG(D_acl) debug_printf(
1083 "DKIM >> Body data for hash, canonicalized >>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1087 ctx->flags = (ctx->flags & ~PDKIM_SEEN_CR) | PDKIM_SEEN_LF;
1089 else if (ctx->flags & PDKIM_SEEN_LF)
1091 if (!(c == '\t' || c == ' ')) /* End of header */
1092 if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1094 ctx->flags &= ~PDKIM_SEEN_LF;
1097 if (!ctx->cur_header || ctx->cur_header->ptr < PDKIM_MAX_HEADER_LEN)
1098 ctx->cur_header = string_catn(ctx->cur_header, CUS &data[p], 1);
1106 /* Extend a growing header with a continuation-linebreak */
1108 pdkim_hdr_cont(gstring * str, int * col)
1111 return string_catn(str, US"\r\n\t", 3);
1117 * RFC 5322 specifies that header line length SHOULD be no more than 78
1120 * Returns gstring (not nul-terminated) appending to one supplied
1122 * col: this int holds and receives column number (octets since last '\n')
1123 * str: partial string to append to
1124 * pad: padding, split line or space after before or after eg: ";".
1125 * Only the initial charater is used.
1126 * intro: - must join to payload eg "h=", usually the tag name
1127 * payload: eg base64 data - long data can be split arbitrarily.
1129 * this code doesn't fold the header in some of the places that RFC4871
1130 * allows: As per RFC5322(2.2.3) it only folds before or after tag-value
1131 * pairs and inside long values. it also always spaces or breaks after the
1134 * No guarantees are made for output given out-of range input. like tag
1135 * names longer than 78, or bogus col. Input is assumed to be free of line breaks.
1139 pdkim_headcat(int * col, gstring * str,
1140 const uschar * pad, const uschar * intro, const uschar * payload)
1142 int len, chomp, padded = 0;
1144 /* If we can fit at least the pad at the end of current line, do it now.
1145 Otherwise, wrap if there is a pad. */
1150 str = string_catn(str, pad, 1);
1156 str = pdkim_hdr_cont(str, col);
1158 /* Special case: if the whole addition does not fit at the end of the current
1159 line, but could fit on a new line, wrap to give it its full, dedicated line. */
1161 len = (pad ? 2 : padded)
1162 + (intro ? Ustrlen(intro) : 0)
1163 + (payload ? Ustrlen(payload) : 0);
1164 if (len <= 77 && *col+len > 78)
1166 str = pdkim_hdr_cont(str, col);
1170 /* Either we already dealt with the pad or we know there is room */
1174 str = string_catn(str, pad, 1);
1175 str = string_catn(str, US" ", 1);
1178 else if (padded && *col < 78)
1180 str = string_catn(str, US" ", 1);
1184 /* Call recursively with intro as payload: it gets the same, special treatment
1185 (that is, not split if < 78). */
1188 str = pdkim_headcat(col, str, NULL, NULL, intro);
1191 for (len = Ustrlen(payload); len; len -= chomp)
1194 str = pdkim_hdr_cont(str, col);
1195 chomp = *col+len > 78 ? 78 - *col : len;
1196 str = string_catn(str, payload, chomp);
1205 /* -------------------------------------------------------------------------- */
1207 /* Signing: create signature header
1210 pdkim_create_header(pdkim_signature * sig, BOOL final)
1216 gstring * canon_all;
1218 canon_all = string_cat (NULL, pdkim_canons[sig->canon_headers]);
1219 canon_all = string_catn(canon_all, US"/", 1);
1220 canon_all = string_cat (canon_all, pdkim_canons[sig->canon_body]);
1221 (void) string_from_gstring(canon_all);
1223 hdr = string_cat(NULL, US"DKIM-Signature: v="PDKIM_SIGNATURE_VERSION);
1226 /* Required and static bits */
1227 hdr = pdkim_headcat(&col, hdr, US";", US"a=", dkim_sig_to_a_tag(sig));
1228 hdr = pdkim_headcat(&col, hdr, US";", US"q=", pdkim_querymethods[sig->querymethod]);
1229 hdr = pdkim_headcat(&col, hdr, US";", US"c=", canon_all->s);
1230 hdr = pdkim_headcat(&col, hdr, US";", US"d=", sig->domain);
1231 hdr = pdkim_headcat(&col, hdr, US";", US"s=", sig->selector);
1233 /* list of header names can be split between items. */
1235 uschar * n = string_copy(sig->headernames);
1236 uschar * i = US"h=";
1241 uschar * c = Ustrchr(n, ':');
1246 hdr = pdkim_headcat(&col, hdr, NULL, NULL, US":");
1248 hdr = pdkim_headcat(&col, hdr, s, i, n);
1259 base64_bh = pdkim_encode_base64(&sig->calc_body_hash->bh);
1260 hdr = pdkim_headcat(&col, hdr, US";", US"bh=", base64_bh);
1264 hdr = pdkim_headcat(&col, hdr, US";", US"i=", sig->identity);
1266 if (sig->created > 0)
1270 snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->created);
1271 hdr = pdkim_headcat(&col, hdr, US";", US"t=", minibuf);
1274 if (sig->expires > 0)
1278 snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->expires);
1279 hdr = pdkim_headcat(&col, hdr, US";", US"x=", minibuf);
1282 if (sig->bodylength >= 0)
1286 snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->bodylength);
1287 hdr = pdkim_headcat(&col, hdr, US";", US"l=", minibuf);
1290 /* Preliminary or final version? */
1293 base64_b = pdkim_encode_base64(&sig->sighash);
1294 hdr = pdkim_headcat(&col, hdr, US";", US"b=", base64_b);
1296 /* add trailing semicolon: I'm not sure if this is actually needed */
1297 hdr = pdkim_headcat(&col, hdr, NULL, US";", US"");
1301 /* To satisfy the rule "all surrounding whitespace [...] deleted"
1302 ( RFC 6376 section 3.7 ) we ensure there is no whitespace here. Otherwise
1303 the headcat routine could insert a linebreak which the relaxer would reduce
1304 to a single space preceding the terminating semicolon, resulting in an
1305 incorrect header-hash. */
1306 hdr = pdkim_headcat(&col, hdr, US";", US"b=;", US"");
1309 return string_from_gstring(hdr);
1313 /* -------------------------------------------------------------------------- */
1315 /* According to draft-ietf-dcrup-dkim-crypto-07 "keys are 256 bits" (referring
1316 to DNS, hence the pubkey). Check for more than 32 bytes; if so assume the
1317 alternate possible representation (still) being discussed: a
1318 SubjectPublickeyInfo wrapped key - and drop all but the trailing 32-bytes (it
1319 should be a DER, with exactly 12 leading bytes - but we could accept a BER also,
1320 which could be any size). We still rely on the crypto library for checking for
1323 When the RFC is published this should be re-addressed. */
1326 check_bare_ed25519_pubkey(pdkim_pubkey * p)
1328 int excess = p->key.len - 32;
1332 debug_printf("DKIM: unexpected pubkey len %lu\n", (unsigned long) p->key.len);
1333 p->key.data += excess; p->key.len = 32;
1338 static pdkim_pubkey *
1339 pdkim_key_from_dns(pdkim_ctx * ctx, pdkim_signature * sig, ev_ctx * vctx,
1340 const uschar ** errstr)
1342 uschar * dns_txt_name, * dns_txt_reply;
1345 /* Fetch public key for signing domain, from DNS */
1347 dns_txt_name = string_sprintf("%s._domainkey.%s.", sig->selector, sig->domain);
1349 if ( !(dns_txt_reply = ctx->dns_txt_callback(dns_txt_name))
1350 || dns_txt_reply[0] == '\0'
1353 sig->verify_status = PDKIM_VERIFY_INVALID;
1354 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE;
1361 "DKIM >> Parsing public key record >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"
1365 pdkim_quoteprint(CUS dns_txt_reply, Ustrlen(dns_txt_reply));
1368 if ( !(p = pdkim_parse_pubkey_record(CUS dns_txt_reply))
1369 || (Ustrcmp(p->srvtype, "*") != 0 && Ustrcmp(p->srvtype, "email") != 0)
1372 sig->verify_status = PDKIM_VERIFY_INVALID;
1373 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD;
1378 debug_printf(" Invalid public key service type '%s'\n", p->srvtype);
1380 debug_printf(" Error while parsing public key record\n");
1382 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1387 DEBUG(D_acl) debug_printf(
1388 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1390 /* Import public key */
1392 /* Normally we use the signature a= tag to tell us the pubkey format.
1393 When signing under debug we do a test-import of the pubkey, and at that
1394 time we do not have a signature so we must interpret the pubkey k= tag
1395 instead. Assume writing on the sig is ok in that case. */
1397 if (sig->keytype < 0)
1398 if ((sig->keytype = pdkim_keyname_to_keytype(p->keytype)) < 0)
1400 DEBUG(D_acl) debug_printf("verify_init: unhandled keytype %s\n", p->keytype);
1401 sig->verify_status = PDKIM_VERIFY_INVALID;
1402 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
1406 if (sig->keytype == KEYTYPE_ED25519)
1407 check_bare_ed25519_pubkey(p);
1409 if ((*errstr = exim_dkim_verify_init(&p->key,
1410 sig->keytype == KEYTYPE_ED25519 ? KEYFMT_ED25519_BARE : KEYFMT_DER,
1411 vctx, &sig->keybits)))
1413 DEBUG(D_acl) debug_printf("verify_init: %s\n", *errstr);
1414 sig->verify_status = PDKIM_VERIFY_INVALID;
1415 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
1419 vctx->keytype = sig->keytype;
1424 /* -------------------------------------------------------------------------- */
1425 /* Sort and filter the sigs developed from the message */
1427 static pdkim_signature *
1428 sort_sig_methods(pdkim_signature * siglist)
1430 pdkim_signature * yield, ** ss;
1431 const uschar * prefs;
1435 if (!siglist) return NULL;
1437 /* first select in order of hashtypes */
1438 DEBUG(D_acl) debug_printf("DKIM: dkim_verify_hashes '%s'\n", dkim_verify_hashes);
1439 for (prefs = dkim_verify_hashes, sep = 0, yield = NULL, ss = &yield;
1440 ele = string_nextinlist(&prefs, &sep, NULL, 0); )
1442 int i = pdkim_hashname_to_hashtype(CUS ele, 0);
1443 for (pdkim_signature * s = siglist, * next, ** prev = &siglist; s;
1447 if (s->hashtype == i)
1448 { *prev = next; s->next = NULL; *ss = s; ss = &s->next; }
1454 /* then in order of keytypes */
1456 DEBUG(D_acl) debug_printf("DKIM: dkim_verify_keytypes '%s'\n", dkim_verify_keytypes);
1457 for (prefs = dkim_verify_keytypes, sep = 0, yield = NULL, ss = &yield;
1458 ele = string_nextinlist(&prefs, &sep, NULL, 0); )
1460 int i = pdkim_keyname_to_keytype(CUS ele);
1461 for (pdkim_signature * s = siglist, * next, ** prev = &siglist; s;
1465 if (s->keytype == i)
1466 { *prev = next; s->next = NULL; *ss = s; ss = &s->next; }
1472 DEBUG(D_acl) for (pdkim_signature * s = yield; s; s = s->next)
1473 debug_printf(" retain d=%s s=%s a=%s\n",
1474 s->domain, s->selector, dkim_sig_to_a_tag(s));
1479 /* -------------------------------------------------------------------------- */
1482 pdkim_feed_finish(pdkim_ctx * ctx, pdkim_signature ** return_signatures,
1483 const uschar ** err)
1485 BOOL verify_pass = FALSE;
1487 /* Check if we must still flush a (partial) header. If that is the
1488 case, the message has no body, and we must compute a body hash
1489 out of '<CR><LF>' */
1490 if (ctx->cur_header && ctx->cur_header->ptr > 0)
1495 if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1498 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
1499 rnl = pdkim_update_ctx_bodyhash(b, &lineending, rnl);
1500 if (rnl) store_free(rnl);
1503 DEBUG(D_acl) debug_printf(
1504 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1506 /* Build (and/or evaluate) body hash. Do this even if no DKIM sigs, in case we
1507 have a hash to do for ARC. */
1509 pdkim_finish_bodyhash(ctx);
1511 /* Sort and filter the recived signatures */
1513 if (!(ctx->flags & PDKIM_MODE_SIGN))
1514 ctx->sig = sort_sig_methods(ctx->sig);
1518 DEBUG(D_acl) debug_printf("DKIM: no signatures\n");
1519 *return_signatures = NULL;
1523 for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next)
1526 uschar * sig_hdr = US"";
1528 gstring * hdata = NULL;
1531 if ( !(ctx->flags & PDKIM_MODE_SIGN)
1532 && sig->verify_status == PDKIM_VERIFY_FAIL)
1535 debug_printf("DKIM: [%s] abandoning this signature\n", sig->domain);
1539 /*XXX The hash of the headers is needed for GCrypt (for which we can do RSA
1540 signing only, as it happens) and for either GnuTLS and OpenSSL when we are
1541 signing with EC (specifically, Ed25519). The former is because the GCrypt
1542 signing operation is pure (does not do its own hash) so we must hash. The
1543 latter is because we (stupidly, but this is what the IETF draft is saying)
1544 must hash with the declared hash method, then pass the result to the library
1545 hash-and-sign routine (because that's all the libraries are providing. And
1546 we're stuck with whatever that hidden hash method is, too). We may as well
1547 do this hash incrementally.
1548 We don't need the hash we're calculating here for the GnuTLS and OpenSSL
1549 cases of RSA signing, since those library routines can do hash-and-sign.
1551 Some time in the future we could easily avoid doing the hash here for those
1552 cases (which will be common for a long while. We could also change from
1553 the current copy-all-the-headers-into-one-block, then call the hash-and-sign
1554 implementation - to a proper incremental one. Unfortunately, GnuTLS just
1555 cannot do incremental - either signing or verification. Unsure about GCrypt.
1558 /*XXX The header hash is also used (so far) by the verify operation */
1560 if (!exim_sha_init(&hhash_ctx, pdkim_hashes[sig->hashtype].exim_hashmethod))
1562 log_write(0, LOG_MAIN|LOG_PANIC,
1563 "DKIM: hash setup error, possibly nonhandled hashtype");
1567 if (ctx->flags & PDKIM_MODE_SIGN)
1568 DEBUG(D_acl) debug_printf(
1569 "DKIM >> Headers to be signed: >>>>>>>>>>>>\n"
1573 DEBUG(D_acl) debug_printf(
1574 "DKIM >> Header data for hash, canonicalized (%-7s), in sequence >>\n",
1575 pdkim_canons[sig->canon_headers]);
1578 /* SIGNING ---------------------------------------------------------------- */
1579 /* When signing, walk through our header list and add them to the hash. As we
1580 go, construct a list of the header's names to use for the h= parameter.
1581 Then append to that list any remaining header names for which there was no
1584 if (ctx->flags & PDKIM_MODE_SIGN)
1591 /* Import private key, including the keytype which we need for building
1592 the signature header */
1594 if ((*err = exim_dkim_signing_init(CUS sig->privkey, &sctx)))
1596 log_write(0, LOG_MAIN|LOG_PANIC, "signing_init: %s", *err);
1597 return PDKIM_ERR_RSA_PRIVKEY;
1599 sig->keytype = sctx.keytype;
1601 sig->headernames = NULL; /* Collected signed header names */
1602 for (pdkim_stringlist * p = sig->headers; p; p = p->next)
1604 uschar * rh = p->value;
1606 if (header_name_match(rh, sig->sign_headers) == PDKIM_OK)
1608 /* Collect header names (Note: colon presence is guaranteed here) */
1609 g = string_append_listele_n(g, ':', rh, Ustrchr(rh, ':') - rh);
1611 if (sig->canon_headers == PDKIM_CANON_RELAXED)
1612 rh = pdkim_relax_header(rh, TRUE); /* cook header for relaxed canon */
1614 /* Feed header to the hash algorithm */
1615 exim_sha_update(&hhash_ctx, CUS rh, Ustrlen(rh));
1617 /* Remember headers block for signing (when the library cannot do incremental) */
1618 /*XXX we could avoid doing this for all but the GnuTLS/RSA case */
1619 hdata = exim_dkim_data_append(hdata, rh);
1621 DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1625 /* Any headers we wanted to sign but were not present must also be listed.
1626 Ignore elements that have been ticked-off or are marked as never-oversign. */
1628 l = sig->sign_headers;
1629 while((s = string_nextinlist(&l, &sep, NULL, 0)))
1631 if (*s == '+') /* skip oversigning marker */
1633 if (*s != '_' && *s != '=')
1634 g = string_append_listele(g, ':', s);
1636 sig->headernames = string_from_gstring(g);
1638 /* Create signature header with b= omitted */
1639 sig_hdr = pdkim_create_header(sig, FALSE);
1642 /* VERIFICATION ----------------------------------------------------------- */
1643 /* When verifying, walk through the header name list in the h= parameter and
1644 add the headers to the hash in that order. */
1647 uschar * p = sig->headernames;
1653 for (pdkim_stringlist * hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1659 if ((q = Ustrchr(p, ':')))
1662 /*XXX walk the list of headers in same order as received. */
1663 for (pdkim_stringlist * hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1665 && strncasecmp(CCS hdrs->value, CCS p, Ustrlen(p)) == 0
1666 && (hdrs->value)[Ustrlen(p)] == ':'
1669 /* cook header for relaxed canon, or just copy it for simple */
1671 uschar * rh = sig->canon_headers == PDKIM_CANON_RELAXED
1672 ? pdkim_relax_header(hdrs->value, TRUE)
1673 : string_copy(CUS hdrs->value);
1675 /* Feed header to the hash algorithm */
1676 exim_sha_update(&hhash_ctx, CUS rh, Ustrlen(rh));
1678 DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1687 sig_hdr = string_copy(sig->rawsig_no_b_val);
1691 DEBUG(D_acl) debug_printf(
1692 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1697 "DKIM >> Signed DKIM-Signature header, pre-canonicalized >>>>>>>>>>>>>\n");
1698 pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr));
1700 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1703 /* Relax header if necessary */
1704 if (sig->canon_headers == PDKIM_CANON_RELAXED)
1705 sig_hdr = pdkim_relax_header(sig_hdr, FALSE);
1709 debug_printf("DKIM >> Signed DKIM-Signature header, canonicalized (%-7s) >>>>>>>\n",
1710 pdkim_canons[sig->canon_headers]);
1711 pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr));
1713 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1716 /* Finalize header hash */
1717 exim_sha_update(&hhash_ctx, CUS sig_hdr, Ustrlen(sig_hdr));
1718 exim_sha_finish(&hhash_ctx, &hhash);
1722 debug_printf("DKIM [%s] Header %s computed: ",
1723 sig->domain, pdkim_hashes[sig->hashtype].dkim_hashname);
1724 pdkim_hexprint(hhash.data, hhash.len);
1727 /* Remember headers block for signing (when the signing library cannot do
1729 if (ctx->flags & PDKIM_MODE_SIGN)
1730 hdata = exim_dkim_data_append(hdata, US sig_hdr);
1732 /* SIGNING ---------------------------------------------------------------- */
1733 if (ctx->flags & PDKIM_MODE_SIGN)
1735 hashmethod hm = sig->keytype == KEYTYPE_ED25519
1736 #if defined(SIGN_OPENSSL)
1741 : pdkim_hashes[sig->hashtype].exim_hashmethod;
1743 #ifdef SIGN_HAVE_ED25519
1744 /* For GCrypt, and for EC, we pass the hash-of-headers to the signing
1745 routine. For anything else we just pass the headers. */
1747 if (sig->keytype != KEYTYPE_ED25519)
1750 hhash.data = hdata->s;
1751 hhash.len = hdata->ptr;
1754 if ((*err = exim_dkim_sign(&sctx, hm, &hhash, &sig->sighash)))
1756 log_write(0, LOG_MAIN|LOG_PANIC, "signing: %s", *err);
1757 return PDKIM_ERR_RSA_SIGNING;
1762 debug_printf( "DKIM [%s] b computed: ", sig->domain);
1763 pdkim_hexprint(sig->sighash.data, sig->sighash.len);
1766 sig->signature_header = pdkim_create_header(sig, TRUE);
1769 /* VERIFICATION ----------------------------------------------------------- */
1775 /* Make sure we have all required signature tags */
1776 if (!( sig->domain && *sig->domain
1777 && sig->selector && *sig->selector
1778 && sig->headernames && *sig->headernames
1779 && sig->bodyhash.data
1780 && sig->sighash.data
1781 && sig->keytype >= 0
1782 && sig->hashtype >= 0
1786 sig->verify_status = PDKIM_VERIFY_INVALID;
1787 sig->verify_ext_status = PDKIM_VERIFY_INVALID_SIGNATURE_ERROR;
1789 DEBUG(D_acl) debug_printf(
1790 " Error in DKIM-Signature header: tags missing or invalid (%s)\n"
1791 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
1792 !(sig->domain && *sig->domain) ? "d="
1793 : !(sig->selector && *sig->selector) ? "s="
1794 : !(sig->headernames && *sig->headernames) ? "h="
1795 : !sig->bodyhash.data ? "bh="
1796 : !sig->sighash.data ? "b="
1797 : sig->keytype < 0 || sig->hashtype < 0 ? "a="
1803 /* Make sure sig uses supported DKIM version (only v1) */
1804 if (sig->version != 1)
1806 sig->verify_status = PDKIM_VERIFY_INVALID;
1807 sig->verify_ext_status = PDKIM_VERIFY_INVALID_DKIM_VERSION;
1809 DEBUG(D_acl) debug_printf(
1810 " Error in DKIM-Signature header: unsupported DKIM version\n"
1811 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1817 debug_printf( "DKIM [%s] b from mail: ", sig->domain);
1818 pdkim_hexprint(sig->sighash.data, sig->sighash.len);
1821 if (!(sig->pubkey = pdkim_key_from_dns(ctx, sig, &vctx, err)))
1823 log_write(0, LOG_MAIN, "DKIM: %s%s %s%s [failed key import]",
1824 sig->domain ? "d=" : "", sig->domain ? sig->domain : US"",
1825 sig->selector ? "s=" : "", sig->selector ? sig->selector : US"");
1829 /* If the pubkey limits to a list of specific hashes, ignore sigs that
1830 do not have the hash part of the sig algorithm matching */
1832 if (sig->pubkey->hashes)
1834 const uschar * list = sig->pubkey->hashes, * ele;
1836 while ((ele = string_nextinlist(&list, &sep, NULL, 0)))
1837 if (Ustrcmp(ele, pdkim_hashes[sig->hashtype].dkim_hashname) == 0) break;
1840 DEBUG(D_acl) debug_printf("pubkey h=%s vs. sig a=%s_%s\n",
1841 sig->pubkey->hashes,
1842 pdkim_keytypes[sig->keytype],
1843 pdkim_hashes[sig->hashtype].dkim_hashname);
1844 sig->verify_status = PDKIM_VERIFY_FAIL;
1845 sig->verify_ext_status = PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH;
1850 hm = sig->keytype == KEYTYPE_ED25519
1851 #if defined(SIGN_OPENSSL)
1856 : pdkim_hashes[sig->hashtype].exim_hashmethod;
1858 /* Check the signature */
1860 if ((*err = exim_dkim_verify(&vctx, hm, &hhash, &sig->sighash)))
1862 DEBUG(D_acl) debug_printf("headers verify: %s\n", *err);
1863 sig->verify_status = PDKIM_VERIFY_FAIL;
1864 sig->verify_ext_status = PDKIM_VERIFY_FAIL_MESSAGE;
1867 if (*dkim_verify_min_keysizes)
1870 uschar * ss = expand_getkeyed(US pdkim_keytypes[sig->keytype],
1871 dkim_verify_min_keysizes);
1872 if (ss && (minbits = atoi(CS ss)) > sig->keybits)
1874 DEBUG(D_acl) debug_printf("Key too short: Actual: %s %u Minima '%s'\n",
1875 pdkim_keytypes[sig->keytype], sig->keybits, dkim_verify_min_keysizes);
1876 sig->verify_status = PDKIM_VERIFY_FAIL;
1877 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_KEYSIZE;
1882 /* We have a winner! (if bodyhash was correct earlier) */
1883 if (sig->verify_status == PDKIM_VERIFY_NONE)
1885 sig->verify_status = PDKIM_VERIFY_PASS;
1887 if (dkim_verify_minimal) break;
1894 debug_printf("DKIM [%s] %s signature status: %s",
1895 sig->domain, dkim_sig_to_a_tag(sig),
1896 pdkim_verify_status_str(sig->verify_status));
1897 if (sig->verify_ext_status > 0)
1898 debug_printf(" (%s)\n",
1899 pdkim_verify_ext_status_str(sig->verify_ext_status));
1906 /* If requested, set return pointer to signature(s) */
1907 if (return_signatures)
1908 *return_signatures = ctx->sig;
1910 return ctx->flags & PDKIM_MODE_SIGN || verify_pass
1911 ? PDKIM_OK : PDKIM_FAIL;
1915 /* -------------------------------------------------------------------------- */
1917 DLLEXPORT pdkim_ctx *
1918 pdkim_init_verify(uschar * (*dns_txt_callback)(const uschar *), BOOL dot_stuffing)
1922 ctx = store_get(sizeof(pdkim_ctx), FALSE);
1923 memset(ctx, 0, sizeof(pdkim_ctx));
1925 if (dot_stuffing) ctx->flags = PDKIM_DOT_TERM;
1926 /* The line-buffer is for message data, hence tainted */
1927 ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN, TRUE);
1928 ctx->dns_txt_callback = dns_txt_callback;
1929 ctx->cur_header = string_get_tainted(36, TRUE);
1935 /* -------------------------------------------------------------------------- */
1937 DLLEXPORT pdkim_signature *
1938 pdkim_init_sign(pdkim_ctx * ctx,
1939 uschar * domain, uschar * selector, uschar * privkey,
1940 uschar * hashname, const uschar ** errstr)
1943 pdkim_signature * sig;
1945 if (!domain || !selector || !privkey)
1948 /* Allocate & init one signature struct */
1950 sig = store_get(sizeof(pdkim_signature), FALSE);
1951 memset(sig, 0, sizeof(pdkim_signature));
1953 sig->bodylength = -1;
1955 sig->domain = string_copy(US domain);
1956 sig->selector = string_copy(US selector);
1957 sig->privkey = string_copy(US privkey);
1960 for (hashtype = 0; hashtype < nelem(pdkim_hashes); hashtype++)
1961 if (Ustrcmp(hashname, pdkim_hashes[hashtype].dkim_hashname) == 0)
1962 { sig->hashtype = hashtype; break; }
1963 if (hashtype >= nelem(pdkim_hashes))
1965 log_write(0, LOG_MAIN|LOG_PANIC,
1966 "DKIM: unrecognised hashname '%s'", hashname);
1972 pdkim_signature s = *sig;
1975 debug_printf("DKIM (checking verify key)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1976 if (!pdkim_key_from_dns(ctx, &s, &vctx, errstr))
1977 debug_printf("WARNING: bad dkim key in dns\n");
1978 debug_printf("DKIM (finished checking verify key)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1984 /* -------------------------------------------------------------------------- */
1987 pdkim_set_optional(pdkim_signature * sig,
1988 char * sign_headers,
1993 unsigned long created,
1994 unsigned long expires)
1997 sig->identity = string_copy(US identity);
1999 sig->sign_headers = string_copy(sign_headers
2000 ? US sign_headers : US PDKIM_DEFAULT_SIGN_HEADERS);
2002 sig->canon_headers = canon_headers;
2003 sig->canon_body = canon_body;
2004 sig->bodylength = bodylength;
2005 sig->created = created;
2006 sig->expires = expires;
2013 /* Set up a blob for calculating the bodyhash according to the
2014 given needs. Use an existing one if possible, or create a new one.
2016 Return: hashblob pointer, or NULL on error
2019 pdkim_set_bodyhash(pdkim_ctx * ctx, int hashtype, int canon_method,
2024 if (hashtype == -1 || canon_method == -1) return NULL;
2026 for (b = ctx->bodyhash; b; b = b->next)
2027 if ( hashtype == b->hashtype
2028 && canon_method == b->canon_method
2029 && bodylength == b->bodylength)
2031 DEBUG(D_receive) debug_printf("DKIM: using existing bodyhash %d/%d/%ld\n",
2032 hashtype, canon_method, bodylength);
2036 DEBUG(D_receive) debug_printf("DKIM: new bodyhash %d/%d/%ld\n",
2037 hashtype, canon_method, bodylength);
2038 b = store_get(sizeof(pdkim_bodyhash), FALSE);
2039 b->next = ctx->bodyhash;
2040 b->hashtype = hashtype;
2041 b->canon_method = canon_method;
2042 b->bodylength = bodylength;
2043 if (!exim_sha_init(&b->body_hash_ctx, /*XXX hash method: extend for sha512 */
2044 pdkim_hashes[hashtype].exim_hashmethod))
2047 debug_printf("DKIM: hash init error, possibly nonhandled hashtype\n");
2050 b->signed_body_bytes = 0;
2051 b->num_buffered_blanklines = 0;
2057 /* Set up a blob for calculating the bodyhash according to the
2058 needs of this signature. Use an existing one if possible, or
2061 Return: hashblob pointer, or NULL on error (only used as a boolean).
2064 pdkim_set_sig_bodyhash(pdkim_ctx * ctx, pdkim_signature * sig)
2066 pdkim_bodyhash * b = pdkim_set_bodyhash(ctx,
2067 sig->hashtype, sig->canon_body, sig->bodylength);
2068 sig->calc_body_hash = b;
2073 /* -------------------------------------------------------------------------- */
2077 pdkim_init_context(pdkim_ctx * ctx, BOOL dot_stuffed,
2078 uschar * (*dns_txt_callback)(const uschar *))
2080 memset(ctx, 0, sizeof(pdkim_ctx));
2081 ctx->flags = dot_stuffed ? PDKIM_MODE_SIGN | PDKIM_DOT_TERM : PDKIM_MODE_SIGN;
2082 /* The line buffer is for message data, hence tainted */
2083 ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN, TRUE);
2084 DEBUG(D_acl) ctx->dns_txt_callback = dns_txt_callback;
2096 #endif /*DISABLE_DKIM*/