2 * PDKIM - a RFC4871 (DKIM) implementation
4 * Copyright (C) 2009 - 2016 Tom Kistner <tom@duncanthrax.net>
5 * Copyright (C) 2016 - 2018 Jeremy Harris <jgh@exim.org>
7 * http://duncanthrax.net/pdkim/
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #ifndef DISABLE_DKIM /* entire file */
30 # error Need SUPPORT_TLS for DKIM
33 #include "crypt_ver.h"
36 # include <openssl/rsa.h>
37 # include <openssl/ssl.h>
38 # include <openssl/err.h>
39 #elif defined(SIGN_GNUTLS)
40 # include <gnutls/gnutls.h>
41 # include <gnutls/x509.h>
47 #define PDKIM_SIGNATURE_VERSION "1"
48 #define PDKIM_PUB_RECORD_VERSION US "DKIM1"
50 #define PDKIM_MAX_HEADER_LEN 65536
51 #define PDKIM_MAX_HEADERS 512
52 #define PDKIM_MAX_BODY_LINE_LEN 16384
53 #define PDKIM_DNS_TXT_MAX_NAMELEN 1024
55 /* -------------------------------------------------------------------------- */
56 struct pdkim_stringlist {
62 /* -------------------------------------------------------------------------- */
63 /* A bunch of list constants */
64 const uschar * pdkim_querymethods[] = {
68 const uschar * pdkim_canons[] = {
74 const pdkim_hashtype pdkim_hashes[] = {
75 { US"sha1", HASH_SHA1 },
76 { US"sha256", HASH_SHA2_256 },
77 { US"sha512", HASH_SHA2_512 }
80 const uschar * pdkim_keytypes[] = {
81 [KEYTYPE_RSA] = US"rsa",
82 #ifdef SIGN_HAVE_ED25519
83 [KEYTYPE_ED25519] = US"ed25519", /* Works for 3.6.0 GnuTLS, OpenSSL 1.1.1 */
86 #ifdef notyet_EC_dkim_extensions /* https://tools.ietf.org/html/draft-srose-dkim-ecc-00 */
93 typedef struct pdkim_combined_canon_entry {
97 } pdkim_combined_canon_entry;
99 pdkim_combined_canon_entry pdkim_combined_canons[] = {
100 { US"simple/simple", PDKIM_CANON_SIMPLE, PDKIM_CANON_SIMPLE },
101 { US"simple/relaxed", PDKIM_CANON_SIMPLE, PDKIM_CANON_RELAXED },
102 { US"relaxed/simple", PDKIM_CANON_RELAXED, PDKIM_CANON_SIMPLE },
103 { US"relaxed/relaxed", PDKIM_CANON_RELAXED, PDKIM_CANON_RELAXED },
104 { US"simple", PDKIM_CANON_SIMPLE, PDKIM_CANON_SIMPLE },
105 { US"relaxed", PDKIM_CANON_RELAXED, PDKIM_CANON_SIMPLE },
110 static blob lineending = {.data = US"\r\n", .len = 2};
112 /* -------------------------------------------------------------------------- */
114 dkim_sig_to_a_tag(const pdkim_signature * sig)
116 if ( sig->keytype < 0 || sig->keytype > nelem(pdkim_keytypes)
117 || sig->hashtype < 0 || sig->hashtype > nelem(pdkim_hashes))
119 return string_sprintf("%s-%s",
120 pdkim_keytypes[sig->keytype], pdkim_hashes[sig->hashtype].dkim_hashname);
125 pdkim_hashname_to_hashtype(const uschar * s, unsigned len)
128 if (!len) len = Ustrlen(s);
129 for (i = 0; i < nelem(pdkim_hashes); i++)
130 if (Ustrncmp(s, pdkim_hashes[i].dkim_hashname, len) == 0)
136 pdkim_cstring_to_canons(const uschar * s, unsigned len,
137 int * canon_head, int * canon_body)
140 if (!len) len = Ustrlen(s);
141 for (i = 0; pdkim_combined_canons[i].str; i++)
142 if ( Ustrncmp(s, pdkim_combined_canons[i].str, len) == 0
143 && len == Ustrlen(pdkim_combined_canons[i].str))
145 *canon_head = pdkim_combined_canons[i].canon_headers;
146 *canon_body = pdkim_combined_canons[i].canon_body;
154 pdkim_verify_status_str(int status)
158 case PDKIM_VERIFY_NONE: return "PDKIM_VERIFY_NONE";
159 case PDKIM_VERIFY_INVALID: return "PDKIM_VERIFY_INVALID";
160 case PDKIM_VERIFY_FAIL: return "PDKIM_VERIFY_FAIL";
161 case PDKIM_VERIFY_PASS: return "PDKIM_VERIFY_PASS";
162 default: return "PDKIM_VERIFY_UNKNOWN";
167 pdkim_verify_ext_status_str(int ext_status)
171 case PDKIM_VERIFY_FAIL_BODY: return "PDKIM_VERIFY_FAIL_BODY";
172 case PDKIM_VERIFY_FAIL_MESSAGE: return "PDKIM_VERIFY_FAIL_MESSAGE";
173 case PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH: return "PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH";
174 case PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE: return "PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE";
175 case PDKIM_VERIFY_INVALID_BUFFER_SIZE: return "PDKIM_VERIFY_INVALID_BUFFER_SIZE";
176 case PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD: return "PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD";
177 case PDKIM_VERIFY_INVALID_PUBKEY_IMPORT: return "PDKIM_VERIFY_INVALID_PUBKEY_IMPORT";
178 case PDKIM_VERIFY_INVALID_SIGNATURE_ERROR: return "PDKIM_VERIFY_INVALID_SIGNATURE_ERROR";
179 case PDKIM_VERIFY_INVALID_DKIM_VERSION: return "PDKIM_VERIFY_INVALID_DKIM_VERSION";
180 default: return "PDKIM_VERIFY_UNKNOWN";
185 pdkim_errstr(int status)
189 case PDKIM_OK: return US"OK";
190 case PDKIM_FAIL: return US"FAIL";
191 case PDKIM_ERR_RSA_PRIVKEY: return US"PRIVKEY";
192 case PDKIM_ERR_RSA_SIGNING: return US"SIGNING";
193 case PDKIM_ERR_LONG_LINE: return US"LONG_LINE";
194 case PDKIM_ERR_BUFFER_TOO_SMALL: return US"BUFFER_TOO_SMALL";
195 case PDKIM_ERR_EXCESS_SIGS: return US"EXCESS_SIGS";
196 case PDKIM_SIGN_PRIVKEY_WRAP: return US"PRIVKEY_WRAP";
197 case PDKIM_SIGN_PRIVKEY_B64D: return US"PRIVKEY_B64D";
198 default: return US"(unknown)";
203 /* -------------------------------------------------------------------------- */
204 /* Print debugging functions */
206 pdkim_quoteprint(const uschar *data, int len)
209 for (i = 0; i < len; i++)
211 const int c = data[i];
214 case ' ' : debug_printf("{SP}"); break;
215 case '\t': debug_printf("{TB}"); break;
216 case '\r': debug_printf("{CR}"); break;
217 case '\n': debug_printf("{LF}"); break;
218 case '{' : debug_printf("{BO}"); break;
219 case '}' : debug_printf("{BC}"); break;
221 if ( (c < 32) || (c > 127) )
222 debug_printf("{%02x}", c);
224 debug_printf("%c", c);
232 pdkim_hexprint(const uschar *data, int len)
235 if (data) for (i = 0 ; i < len; i++) debug_printf("%02x", data[i]);
236 else debug_printf("<NULL>");
242 static pdkim_stringlist *
243 pdkim_prepend_stringlist(pdkim_stringlist * base, const uschar * str)
245 pdkim_stringlist * new_entry = store_get(sizeof(pdkim_stringlist));
247 memset(new_entry, 0, sizeof(pdkim_stringlist));
248 new_entry->value = string_copy(str);
249 if (base) new_entry->next = base;
255 /* Trim whitespace fore & aft */
258 pdkim_strtrim(gstring * str)
263 while (*p == '\t' || *p == ' ') /* dump the leading whitespace */
264 { str->size--; str->ptr--; str->s++; }
267 && ((q = str->s + str->ptr - 1), (*q == '\t' || *q == ' '))
269 str->ptr--; /* dump trailing whitespace */
271 (void) string_from_gstring(str);
276 /* -------------------------------------------------------------------------- */
279 pdkim_free_ctx(pdkim_ctx *ctx)
284 /* -------------------------------------------------------------------------- */
285 /* Matches the name of the passed raw "header" against
286 the passed colon-separated "tick", and invalidates
287 the entry in tick. Entries can be prefixed for multi- or over-signing,
288 in which case do not invalidate.
290 Returns OK for a match, or fail-code
294 header_name_match(const uschar * header, uschar * tick)
296 const uschar * ticklist = tick;
299 uschar * hname, * p, * ele;
300 uschar * hcolon = Ustrchr(header, ':'); /* Get header name */
303 return PDKIM_FAIL; /* This isn't a header */
305 /* if we had strncmpic() we wouldn't need this copy */
306 hname = string_copyn(header, hcolon-header);
308 while (p = US ticklist, ele = string_nextinlist(&ticklist, &sep, NULL, 0))
312 case '=': case '+': multisign = TRUE; ele++; break;
313 default: multisign = FALSE; break;
316 if (strcmpic(ele, hname) == 0)
319 *p = '_'; /* Invalidate this header name instance in tick-off list */
327 /* -------------------------------------------------------------------------- */
328 /* Performs "relaxed" canonicalization of a header. */
331 pdkim_relax_header_n(const uschar * header, int len, BOOL append_crlf)
333 BOOL past_field_name = FALSE;
334 BOOL seen_wsp = FALSE;
336 uschar * relaxed = store_get(len+3);
337 uschar * q = relaxed;
339 for (p = header; p - header < len; p++)
343 if (c == '\r' || c == '\n') /* Ignore CR & LF */
345 if (c == '\t' || c == ' ')
349 c = ' '; /* Turns WSP into SP */
353 if (!past_field_name && c == ':')
355 if (seen_wsp) q--; /* This removes WSP immediately before the colon */
356 seen_wsp = TRUE; /* This removes WSP immediately after the colon */
357 past_field_name = TRUE;
362 /* Lowercase header name */
363 if (!past_field_name) c = tolower(c);
367 if (q > relaxed && q[-1] == ' ') q--; /* Squash eventual trailing SP */
369 if (append_crlf) { *q++ = '\r'; *q++ = '\n'; }
376 pdkim_relax_header(const uschar * header, BOOL append_crlf)
378 return pdkim_relax_header_n(header, Ustrlen(header), append_crlf);
382 /* -------------------------------------------------------------------------- */
383 #define PDKIM_QP_ERROR_DECODE -1
385 static const uschar *
386 pdkim_decode_qp_char(const uschar *qp_p, int *c)
388 const uschar *initial_pos = qp_p;
390 /* Advance one char */
393 /* Check for two hex digits and decode them */
394 if (isxdigit(*qp_p) && isxdigit(qp_p[1]))
396 /* Do hex conversion */
397 *c = (isdigit(*qp_p) ? *qp_p - '0' : toupper(*qp_p) - 'A' + 10) << 4;
398 *c |= isdigit(qp_p[1]) ? qp_p[1] - '0' : toupper(qp_p[1]) - 'A' + 10;
402 /* Illegal char here */
403 *c = PDKIM_QP_ERROR_DECODE;
408 /* -------------------------------------------------------------------------- */
411 pdkim_decode_qp(const uschar * str)
415 const uschar * p = str;
416 uschar * n = store_get(Ustrlen(str)+1);
424 p = pdkim_decode_qp_char(p, &nchar);
440 /* -------------------------------------------------------------------------- */
443 pdkim_decode_base64(const uschar * str, blob * b)
445 int dlen = b64decode(str, &b->data);
446 if (dlen < 0) b->data = NULL;
451 pdkim_encode_base64(blob * b)
453 return b64encode(b->data, b->len);
457 /* -------------------------------------------------------------------------- */
458 #define PDKIM_HDR_LIMBO 0
459 #define PDKIM_HDR_TAG 1
460 #define PDKIM_HDR_VALUE 2
462 static pdkim_signature *
463 pdkim_parse_sig_header(pdkim_ctx * ctx, uschar * raw_hdr)
465 pdkim_signature * sig;
467 gstring * cur_tag = NULL;
468 gstring * cur_val = NULL;
469 BOOL past_hname = FALSE;
470 BOOL in_b_val = FALSE;
471 int where = PDKIM_HDR_LIMBO;
474 sig = store_get(sizeof(pdkim_signature));
475 memset(sig, 0, sizeof(pdkim_signature));
476 sig->bodylength = -1;
478 /* Set so invalid/missing data error display is accurate */
483 q = sig->rawsig_no_b_val = store_get(Ustrlen(raw_hdr)+1);
485 for (p = raw_hdr; ; p++)
490 if (c == '\r' || c == '\n')
493 /* Fast-forward through header name */
496 if (c == ':') past_hname = TRUE;
500 if (where == PDKIM_HDR_LIMBO)
502 /* In limbo, just wait for a tag-char to appear */
503 if (!(c >= 'a' && c <= 'z'))
506 where = PDKIM_HDR_TAG;
509 if (where == PDKIM_HDR_TAG)
511 if (c >= 'a' && c <= 'z')
512 cur_tag = string_catn(cur_tag, p, 1);
516 if (Ustrcmp(string_from_gstring(cur_tag), "b") == 0)
521 where = PDKIM_HDR_VALUE;
526 if (where == PDKIM_HDR_VALUE)
528 if (c == '\r' || c == '\n' || c == ' ' || c == '\t')
531 if (c == ';' || c == '\0')
533 /* We must have both tag and value, and tags must be one char except
534 for the possibility of "bh". */
536 if ( cur_tag && cur_val
537 && (cur_tag->ptr == 1 || *cur_tag->s == 'b')
540 (void) string_from_gstring(cur_val);
541 pdkim_strtrim(cur_val);
543 DEBUG(D_acl) debug_printf(" %s=%s\n", cur_tag->s, cur_val->s);
547 case 'b': /* sig-data or body-hash */
548 switch (cur_tag->s[1])
550 case '\0': pdkim_decode_base64(cur_val->s, &sig->sighash); break;
551 case 'h': if (cur_tag->ptr == 2)
552 pdkim_decode_base64(cur_val->s, &sig->bodyhash);
557 case 'v': /* version */
558 /* We only support version 1, and that is currently the
559 only version there is. */
561 Ustrcmp(cur_val->s, PDKIM_SIGNATURE_VERSION) == 0 ? 1 : -1;
563 case 'a': /* algorithm */
565 const uschar * list = cur_val->s;
569 if ((elem = string_nextinlist(&list, &sep, NULL, 0)))
570 for(i = 0; i < nelem(pdkim_keytypes); i++)
571 if (Ustrcmp(elem, pdkim_keytypes[i]) == 0)
572 { sig->keytype = i; break; }
573 if ((elem = string_nextinlist(&list, &sep, NULL, 0)))
574 for (i = 0; i < nelem(pdkim_hashes); i++)
575 if (Ustrcmp(elem, pdkim_hashes[i].dkim_hashname) == 0)
576 { sig->hashtype = i; break; }
579 case 'c': /* canonicalization */
580 pdkim_cstring_to_canons(cur_val->s, 0,
581 &sig->canon_headers, &sig->canon_body);
583 case 'q': /* Query method (for pubkey)*/
584 for (i = 0; pdkim_querymethods[i]; i++)
585 if (Ustrcmp(cur_val->s, pdkim_querymethods[i]) == 0)
587 sig->querymethod = i; /* we never actually use this */
591 case 's': /* Selector */
592 sig->selector = string_copyn(cur_val->s, cur_val->ptr); break;
594 sig->domain = string_copyn(cur_val->s, cur_val->ptr); break;
596 sig->identity = pdkim_decode_qp(cur_val->s); break;
597 case 't': /* Timestamp */
598 sig->created = strtoul(CS cur_val->s, NULL, 10); break;
599 case 'x': /* Expiration */
600 sig->expires = strtoul(CS cur_val->s, NULL, 10); break;
601 case 'l': /* Body length count */
602 sig->bodylength = strtol(CS cur_val->s, NULL, 10); break;
603 case 'h': /* signed header fields */
604 sig->headernames = string_copyn(cur_val->s, cur_val->ptr); break;
605 case 'z': /* Copied headfields */
606 sig->copiedheaders = pdkim_decode_qp(cur_val->s); break;
607 /*XXX draft-ietf-dcrup-dkim-crypto-05 would need 'p' tag support
608 for rsafp signatures. But later discussion is dropping those. */
610 DEBUG(D_acl) debug_printf(" Unknown tag encountered\n");
614 cur_tag = cur_val = NULL;
616 where = PDKIM_HDR_LIMBO;
619 cur_val = string_catn(cur_val, p, 1);
630 if (sig->keytype < 0 || sig->hashtype < 0) /* Cannot verify this signature */
634 /* Chomp raw header. The final newline must not be added to the signature. */
635 while (--q > sig->rawsig_no_b_val && (*q == '\r' || *q == '\n'))
641 "PDKIM >> Raw signature w/o b= tag value >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
642 pdkim_quoteprint(US sig->rawsig_no_b_val, Ustrlen(sig->rawsig_no_b_val));
644 "PDKIM >> Sig size: %4u bits\n", (unsigned) sig->sighash.len*8);
646 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
649 if (!pdkim_set_sig_bodyhash(ctx, sig))
656 /* -------------------------------------------------------------------------- */
659 pdkim_parse_pubkey_record(const uschar *raw_record)
665 pub = store_get(sizeof(pdkim_pubkey));
666 memset(pub, 0, sizeof(pdkim_pubkey));
668 while ((ele = string_nextinlist(&raw_record, &sep, NULL, 0)))
672 if ((val = Ustrchr(ele, '=')))
674 int taglen = val++ - ele;
676 DEBUG(D_acl) debug_printf(" %.*s=%s\n", taglen, ele, val);
679 case 'v': pub->version = val; break;
680 case 'h': pub->hashes = val; break;
681 case 'k': pub->keytype = val; break;
682 case 'g': pub->granularity = val; break;
683 case 'n': pub->notes = pdkim_decode_qp(val); break;
684 case 'p': pdkim_decode_base64(val, &pub->key); break;
685 case 's': pub->srvtype = val; break;
686 case 't': if (Ustrchr(val, 'y')) pub->testing = 1;
687 if (Ustrchr(val, 's')) pub->no_subdomaining = 1;
689 default: DEBUG(D_acl) debug_printf(" Unknown tag encountered\n"); break;
694 /* Set fallback defaults */
696 pub->version = string_copy(PDKIM_PUB_RECORD_VERSION);
697 else if (Ustrcmp(pub->version, PDKIM_PUB_RECORD_VERSION) != 0)
699 DEBUG(D_acl) debug_printf(" Bad v= field\n");
703 if (!pub->granularity) pub->granularity = US"*";
704 if (!pub->keytype ) pub->keytype = US"rsa";
705 if (!pub->srvtype ) pub->srvtype = US"*";
711 DEBUG(D_acl) debug_printf(" Missing p= field\n");
716 /* -------------------------------------------------------------------------- */
718 /* Update one bodyhash with some additional data.
719 If we have to relax the data for this sig, return our copy of it. */
722 pdkim_update_ctx_bodyhash(pdkim_bodyhash * b, blob * orig_data, blob * relaxed_data)
724 blob * canon_data = orig_data;
725 /* Defaults to simple canon (no further treatment necessary) */
727 if (b->canon_method == PDKIM_CANON_RELAXED)
729 /* Relax the line if not done already */
732 BOOL seen_wsp = FALSE;
733 const uschar * p, * r;
736 /* We want to be able to free this else we allocate
737 for the entire message which could be many MB. Since
738 we don't know what allocations the SHA routines might
739 do, not safe to use store_get()/store_reset(). */
741 relaxed_data = store_malloc(sizeof(blob) + orig_data->len+1);
742 relaxed_data->data = US (relaxed_data+1);
744 for (p = orig_data->data, r = p + orig_data->len; p < r; p++)
749 if (q > 0 && relaxed_data->data[q-1] == ' ')
752 else if (c == '\t' || c == ' ')
754 c = ' '; /* Turns WSP into SP */
761 relaxed_data->data[q++] = c;
763 relaxed_data->data[q] = '\0';
764 relaxed_data->len = q;
766 canon_data = relaxed_data;
769 /* Make sure we don't exceed the to-be-signed body length */
770 if ( b->bodylength >= 0
771 && b->signed_body_bytes + (unsigned long)canon_data->len > b->bodylength
773 canon_data->len = b->bodylength - b->signed_body_bytes;
775 if (canon_data->len > 0)
777 exim_sha_update(&b->body_hash_ctx, CUS canon_data->data, canon_data->len);
778 b->signed_body_bytes += canon_data->len;
779 DEBUG(D_acl) pdkim_quoteprint(canon_data->data, canon_data->len);
786 /* -------------------------------------------------------------------------- */
789 pdkim_finish_bodyhash(pdkim_ctx * ctx)
792 pdkim_signature * sig;
794 for (b = ctx->bodyhash; b; b = b->next) /* Finish hashes */
796 DEBUG(D_acl) debug_printf("PDKIM: finish bodyhash %d/%d/%ld len %ld\n",
797 b->hashtype, b->canon_method, b->bodylength, b->signed_body_bytes);
798 exim_sha_finish(&b->body_hash_ctx, &b->bh);
801 /* Traverse all signatures */
802 for (sig = ctx->sig; sig; sig = sig->next)
804 b = sig->calc_body_hash;
808 debug_printf("PDKIM [%s] Body bytes (%s) hashed: %lu\n"
809 "PDKIM [%s] Body %s computed: ",
810 sig->domain, pdkim_canons[b->canon_method], b->signed_body_bytes,
811 sig->domain, pdkim_hashes[b->hashtype].dkim_hashname);
812 pdkim_hexprint(CUS b->bh.data, b->bh.len);
815 /* SIGNING -------------------------------------------------------------- */
816 if (ctx->flags & PDKIM_MODE_SIGN)
818 /* If bodylength limit is set, and we have received less bytes
819 than the requested amount, effectively remove the limit tag. */
820 if (b->signed_body_bytes < sig->bodylength)
821 sig->bodylength = -1;
825 /* VERIFICATION --------------------------------------------------------- */
826 /* Be careful that the header sig included a bodyash */
828 if ( sig->bodyhash.data
829 && memcmp(b->bh.data, sig->bodyhash.data, b->bh.len) == 0)
831 DEBUG(D_acl) debug_printf("PDKIM [%s] Body hash compared OK\n", sig->domain);
837 debug_printf("PDKIM [%s] Body hash signature from headers: ", sig->domain);
838 pdkim_hexprint(sig->bodyhash.data, sig->bodyhash.len);
839 debug_printf("PDKIM [%s] Body hash did NOT verify\n", sig->domain);
841 sig->verify_status = PDKIM_VERIFY_FAIL;
842 sig->verify_ext_status = PDKIM_VERIFY_FAIL_BODY;
850 pdkim_body_complete(pdkim_ctx * ctx)
854 /* In simple body mode, if any empty lines were buffered,
855 replace with one. rfc 4871 3.4.3 */
856 /*XXX checking the signed-body-bytes is a gross hack; I think
857 it indicates that all linebreaks should be buffered, including
858 the one terminating a text line */
860 for (b = ctx->bodyhash; b; b = b->next)
861 if ( b->canon_method == PDKIM_CANON_SIMPLE
862 && b->signed_body_bytes == 0
863 && b->num_buffered_blanklines > 0
865 (void) pdkim_update_ctx_bodyhash(b, &lineending, NULL);
867 ctx->flags |= PDKIM_SEEN_EOD;
868 ctx->linebuf_offset = 0;
873 /* -------------------------------------------------------------------------- */
874 /* Call from pdkim_feed below for processing complete body lines */
875 /* NOTE: the line is not NUL-terminated; but we have a count */
878 pdkim_bodyline_complete(pdkim_ctx * ctx)
880 blob line = {.data = ctx->linebuf, .len = ctx->linebuf_offset};
885 /* Ignore extra data if we've seen the end-of-data marker */
886 if (ctx->flags & PDKIM_SEEN_EOD) goto all_skip;
888 /* We've always got one extra byte to stuff a zero ... */
889 ctx->linebuf[line.len] = '\0';
891 /* Terminate on EOD marker */
892 if (ctx->flags & PDKIM_DOT_TERM)
894 if (memcmp(line.data, ".\r\n", 3) == 0)
895 { pdkim_body_complete(ctx); return; }
898 if (memcmp(line.data, "..", 2) == 0)
899 { line.data++; line.len--; }
902 /* Empty lines need to be buffered until we find a non-empty line */
903 if (memcmp(line.data, "\r\n", 2) == 0)
905 for (b = ctx->bodyhash; b; b = b->next) b->num_buffered_blanklines++;
909 /* Process line for each bodyhash separately */
910 for (b = ctx->bodyhash; b; b = b->next)
912 if (b->canon_method == PDKIM_CANON_RELAXED)
914 /* Lines with just spaces need to be buffered too */
915 uschar * cp = line.data;
920 if (c == '\r' && cp[1] == '\n') break;
921 if (c != ' ' && c != '\t') goto hash_process;
925 b->num_buffered_blanklines++;
930 /* At this point, we have a non-empty line, so release the buffered ones. */
932 while (b->num_buffered_blanklines)
934 rnl = pdkim_update_ctx_bodyhash(b, &lineending, rnl);
935 b->num_buffered_blanklines--;
938 rline = pdkim_update_ctx_bodyhash(b, &line, rline);
942 if (rnl) store_free(rnl);
943 if (rline) store_free(rline);
947 ctx->linebuf_offset = 0;
952 /* -------------------------------------------------------------------------- */
953 /* Callback from pdkim_feed below for processing complete headers */
954 #define DKIM_SIGNATURE_HEADERNAME "DKIM-Signature:"
957 pdkim_header_complete(pdkim_ctx * ctx)
959 pdkim_signature * sig, * last_sig;
961 /* Special case: The last header can have an extra \r appended */
962 if ( (ctx->cur_header->ptr > 1) &&
963 (ctx->cur_header->s[ctx->cur_header->ptr-1] == '\r') )
964 --ctx->cur_header->ptr;
965 (void) string_from_gstring(ctx->cur_header);
967 #ifdef EXPERIMENTAL_ARC
968 /* Feed the header line to ARC processing */
969 (void) arc_header_feed(ctx->cur_header, !(ctx->flags & PDKIM_MODE_SIGN));
972 if (++ctx->num_headers > PDKIM_MAX_HEADERS) goto BAIL;
974 /* SIGNING -------------------------------------------------------------- */
975 if (ctx->flags & PDKIM_MODE_SIGN)
976 for (sig = ctx->sig; sig; sig = sig->next) /* Traverse all signatures */
978 /* Add header to the signed headers list (in reverse order) */
979 sig->headers = pdkim_prepend_stringlist(sig->headers, ctx->cur_header->s);
981 /* VERIFICATION ----------------------------------------------------------- */
982 /* DKIM-Signature: headers are added to the verification list */
988 debug_printf("PDKIM >> raw hdr: ");
989 pdkim_quoteprint(CUS ctx->cur_header->s, ctx->cur_header->ptr);
992 if (strncasecmp(CCS ctx->cur_header->s,
993 DKIM_SIGNATURE_HEADERNAME,
994 Ustrlen(DKIM_SIGNATURE_HEADERNAME)) == 0)
996 /* Create and chain new signature block. We could error-check for all
997 required tags here, but prefer to create the internal sig and expicitly
998 fail verification of it later. */
1000 DEBUG(D_acl) debug_printf(
1001 "PDKIM >> Found sig, trying to parse >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1003 sig = pdkim_parse_sig_header(ctx, ctx->cur_header->s);
1005 if (!(last_sig = ctx->sig))
1009 while (last_sig->next) last_sig = last_sig->next;
1010 last_sig->next = sig;
1013 if (--dkim_collect_input == 0)
1015 ctx->headers = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->s);
1016 ctx->cur_header->s[ctx->cur_header->ptr = 0] = '\0';
1017 return PDKIM_ERR_EXCESS_SIGS;
1021 /* all headers are stored for signature verification */
1022 ctx->headers = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->s);
1026 ctx->cur_header->s[ctx->cur_header->ptr = 0] = '\0'; /* leave buffer for reuse */
1032 /* -------------------------------------------------------------------------- */
1033 #define HEADER_BUFFER_FRAG_SIZE 256
1036 pdkim_feed(pdkim_ctx * ctx, uschar * data, int len)
1040 /* Alternate EOD signal, used in non-dotstuffing mode */
1042 pdkim_body_complete(ctx);
1044 else for (p = 0; p < len; p++)
1048 if (ctx->flags & PDKIM_PAST_HDRS)
1050 if (c == '\n' && !(ctx->flags & PDKIM_SEEN_CR)) /* emulate the CR */
1052 ctx->linebuf[ctx->linebuf_offset++] = '\r';
1053 if (ctx->linebuf_offset == PDKIM_MAX_BODY_LINE_LEN-1)
1054 return PDKIM_ERR_LONG_LINE;
1057 /* Processing body byte */
1058 ctx->linebuf[ctx->linebuf_offset++] = c;
1060 ctx->flags |= PDKIM_SEEN_CR;
1063 ctx->flags &= ~PDKIM_SEEN_CR;
1064 pdkim_bodyline_complete(ctx);
1067 if (ctx->linebuf_offset == PDKIM_MAX_BODY_LINE_LEN-1)
1068 return PDKIM_ERR_LONG_LINE;
1072 /* Processing header byte */
1074 ctx->flags |= PDKIM_SEEN_CR;
1077 if (!(ctx->flags & PDKIM_SEEN_CR)) /* emulate the CR */
1078 ctx->cur_header = string_catn(ctx->cur_header, CUS "\r", 1);
1080 if (ctx->flags & PDKIM_SEEN_LF) /* Seen last header line */
1082 if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1085 ctx->flags = (ctx->flags & ~(PDKIM_SEEN_LF|PDKIM_SEEN_CR)) | PDKIM_PAST_HDRS;
1086 DEBUG(D_acl) debug_printf(
1087 "PDKIM >> Body data for hash, canonicalized >>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1091 ctx->flags = (ctx->flags & ~PDKIM_SEEN_CR) | PDKIM_SEEN_LF;
1093 else if (ctx->flags & PDKIM_SEEN_LF)
1095 if (!(c == '\t' || c == ' ')) /* End of header */
1096 if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1098 ctx->flags &= ~PDKIM_SEEN_LF;
1101 if (!ctx->cur_header || ctx->cur_header->ptr < PDKIM_MAX_HEADER_LEN)
1102 ctx->cur_header = string_catn(ctx->cur_header, CUS &data[p], 1);
1110 /* Extend a growing header with a continuation-linebreak */
1112 pdkim_hdr_cont(gstring * str, int * col)
1115 return string_catn(str, US"\r\n\t", 3);
1121 * RFC 5322 specifies that header line length SHOULD be no more than 78
1125 * returns uschar * (not nul-terminated)
1127 * col: this int holds and receives column number (octets since last '\n')
1128 * str: partial string to append to
1129 * pad: padding, split line or space after before or after eg: ";"
1130 * intro: - must join to payload eg "h=", usually the tag name
1131 * payload: eg base64 data - long data can be split arbitrarily.
1133 * this code doesn't fold the header in some of the places that RFC4871
1134 * allows: As per RFC5322(2.2.3) it only folds before or after tag-value
1135 * pairs and inside long values. it also always spaces or breaks after the
1138 * no guarantees are made for output given out-of range input. like tag
1139 * names longer than 78, or bogus col. Input is assumed to be free of line breaks.
1143 pdkim_headcat(int * col, gstring * str,
1144 const uschar * pad, const uschar * intro, const uschar * payload)
1152 str = pdkim_hdr_cont(str, col);
1153 str = string_catn(str, pad, l);
1157 l = (pad?1:0) + (intro?Ustrlen(intro):0);
1160 { /*can't fit intro - start a new line to make room.*/
1161 str = pdkim_hdr_cont(str, col);
1162 l = intro?Ustrlen(intro):0;
1165 l += payload ? Ustrlen(payload):0 ;
1168 { /* this fragment will not fit on a single line */
1171 str = string_catn(str, US" ", 1);
1173 pad = NULL; /* only want this once */
1179 size_t sl = Ustrlen(intro);
1181 str = string_catn(str, intro, sl);
1184 intro = NULL; /* only want this once */
1189 size_t sl = Ustrlen(payload);
1190 size_t chomp = *col+sl < 77 ? sl : 78-*col;
1192 str = string_catn(str, payload, chomp);
1198 /* the while precondition tells us it didn't fit. */
1199 str = pdkim_hdr_cont(str, col);
1204 str = pdkim_hdr_cont(str, col);
1210 str = string_catn(str, US" ", 1);
1217 size_t sl = Ustrlen(intro);
1219 str = string_catn(str, intro, sl);
1227 size_t sl = Ustrlen(payload);
1229 str = string_catn(str, payload, sl);
1237 /* -------------------------------------------------------------------------- */
1239 /* Signing: create signature header
1242 pdkim_create_header(pdkim_signature * sig, BOOL final)
1248 gstring * canon_all;
1250 canon_all = string_cat (NULL, pdkim_canons[sig->canon_headers]);
1251 canon_all = string_catn(canon_all, US"/", 1);
1252 canon_all = string_cat (canon_all, pdkim_canons[sig->canon_body]);
1253 (void) string_from_gstring(canon_all);
1255 hdr = string_cat(NULL, US"DKIM-Signature: v="PDKIM_SIGNATURE_VERSION);
1258 /* Required and static bits */
1259 hdr = pdkim_headcat(&col, hdr, US";", US"a=", dkim_sig_to_a_tag(sig));
1260 hdr = pdkim_headcat(&col, hdr, US";", US"q=", pdkim_querymethods[sig->querymethod]);
1261 hdr = pdkim_headcat(&col, hdr, US";", US"c=", canon_all->s);
1262 hdr = pdkim_headcat(&col, hdr, US";", US"d=", sig->domain);
1263 hdr = pdkim_headcat(&col, hdr, US";", US"s=", sig->selector);
1265 /* list of header names can be split between items. */
1267 uschar * n = string_copy(sig->headernames);
1268 uschar * i = US"h=";
1273 uschar * c = Ustrchr(n, ':');
1278 hdr = pdkim_headcat(&col, hdr, NULL, NULL, US":");
1280 hdr = pdkim_headcat(&col, hdr, s, i, n);
1291 base64_bh = pdkim_encode_base64(&sig->calc_body_hash->bh);
1292 hdr = pdkim_headcat(&col, hdr, US";", US"bh=", base64_bh);
1296 hdr = pdkim_headcat(&col, hdr, US";", US"i=", sig->identity);
1298 if (sig->created > 0)
1302 snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->created);
1303 hdr = pdkim_headcat(&col, hdr, US";", US"t=", minibuf);
1306 if (sig->expires > 0)
1310 snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->expires);
1311 hdr = pdkim_headcat(&col, hdr, US";", US"x=", minibuf);
1314 if (sig->bodylength >= 0)
1318 snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->bodylength);
1319 hdr = pdkim_headcat(&col, hdr, US";", US"l=", minibuf);
1322 /* Preliminary or final version? */
1325 base64_b = pdkim_encode_base64(&sig->sighash);
1326 hdr = pdkim_headcat(&col, hdr, US";", US"b=", base64_b);
1328 /* add trailing semicolon: I'm not sure if this is actually needed */
1329 hdr = pdkim_headcat(&col, hdr, NULL, US";", US"");
1333 /* To satisfy the rule "all surrounding whitespace [...] deleted"
1334 ( RFC 6376 section 3.7 ) we ensure there is no whitespace here. Otherwise
1335 the headcat routine could insert a linebreak which the relaxer would reduce
1336 to a single space preceding the terminating semicolon, resulting in an
1337 incorrect header-hash. */
1338 hdr = pdkim_headcat(&col, hdr, US";", US"b=;", US"");
1341 return string_from_gstring(hdr);
1345 /* -------------------------------------------------------------------------- */
1347 /* According to draft-ietf-dcrup-dkim-crypto-07 "keys are 256 bits" (referring
1348 to DNS, hence the pubkey). Check for more than 32 bytes; if so assume the
1349 alternate possible representation (still) being discussed: a
1350 SubjectPublickeyInfo wrapped key - and drop all but the trailing 32-bytes (it
1351 should be a DER, with exactly 12 leading bytes - but we could accept a BER also,
1352 which could be any size). We still rely on the crypto library for checking for
1355 When the RFC is published this should be re-addressed. */
1358 check_bare_ed25519_pubkey(pdkim_pubkey * p)
1360 int excess = p->key.len - 32;
1363 DEBUG(D_acl) debug_printf("PDKIM: unexpected pubkey len %lu\n", p->key.len);
1364 p->key.data += excess; p->key.len = 32;
1369 static pdkim_pubkey *
1370 pdkim_key_from_dns(pdkim_ctx * ctx, pdkim_signature * sig, ev_ctx * vctx,
1371 const uschar ** errstr)
1373 uschar * dns_txt_name, * dns_txt_reply;
1376 /* Fetch public key for signing domain, from DNS */
1378 dns_txt_name = string_sprintf("%s._domainkey.%s.", sig->selector, sig->domain);
1380 if ( !(dns_txt_reply = ctx->dns_txt_callback(dns_txt_name))
1381 || dns_txt_reply[0] == '\0'
1384 sig->verify_status = PDKIM_VERIFY_INVALID;
1385 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE;
1392 "PDKIM >> Parsing public key record >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"
1396 pdkim_quoteprint(CUS dns_txt_reply, Ustrlen(dns_txt_reply));
1399 if ( !(p = pdkim_parse_pubkey_record(CUS dns_txt_reply))
1400 || (Ustrcmp(p->srvtype, "*") != 0 && Ustrcmp(p->srvtype, "email") != 0)
1403 sig->verify_status = PDKIM_VERIFY_INVALID;
1404 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD;
1409 debug_printf(" Invalid public key service type '%s'\n", p->srvtype);
1411 debug_printf(" Error while parsing public key record\n");
1413 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1418 DEBUG(D_acl) debug_printf(
1419 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1421 /* Import public key */
1423 /* Normally we use the signature a= tag to tell us the pubkey format.
1424 When signing under debug we do a test-import of the pubkey, and at that
1425 time we do not have a signature so we must interpret the pubkey k= tag
1426 instead. Assume writing on the sig is ok in that case. */
1428 if (sig->keytype < 0)
1431 for(i = 0; i < nelem(pdkim_keytypes); i++)
1432 if (Ustrcmp(p->keytype, pdkim_keytypes[i]) == 0)
1433 { sig->keytype = i; goto k_ok; }
1434 DEBUG(D_acl) debug_printf("verify_init: unhandled keytype %s\n", p->keytype);
1435 sig->verify_status = PDKIM_VERIFY_INVALID;
1436 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
1441 if (sig->keytype == KEYTYPE_ED25519)
1442 check_bare_ed25519_pubkey(p);
1444 if ((*errstr = exim_dkim_verify_init(&p->key,
1445 sig->keytype == KEYTYPE_ED25519 ? KEYFMT_ED25519_BARE : KEYFMT_DER,
1448 DEBUG(D_acl) debug_printf("verify_init: %s\n", *errstr);
1449 sig->verify_status = PDKIM_VERIFY_INVALID;
1450 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
1454 vctx->keytype = sig->keytype;
1459 /* -------------------------------------------------------------------------- */
1462 pdkim_feed_finish(pdkim_ctx * ctx, pdkim_signature ** return_signatures,
1463 const uschar ** err)
1466 pdkim_signature * sig;
1467 BOOL verify_pass = FALSE;
1469 /* Check if we must still flush a (partial) header. If that is the
1470 case, the message has no body, and we must compute a body hash
1471 out of '<CR><LF>' */
1472 if (ctx->cur_header && ctx->cur_header->ptr > 0)
1477 if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1480 for (b = ctx->bodyhash; b; b = b->next)
1481 rnl = pdkim_update_ctx_bodyhash(b, &lineending, rnl);
1482 if (rnl) store_free(rnl);
1485 DEBUG(D_acl) debug_printf(
1486 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1488 /* Build (and/or evaluate) body hash. Do this even if no DKIM sigs, in case we
1489 have a hash to do for ARC. */
1491 pdkim_finish_bodyhash(ctx);
1495 DEBUG(D_acl) debug_printf("PDKIM: no signatures\n");
1496 *return_signatures = NULL;
1500 for (sig = ctx->sig; sig; sig = sig->next)
1503 uschar * sig_hdr = US"";
1505 gstring * hdata = NULL;
1508 if ( !(ctx->flags & PDKIM_MODE_SIGN)
1509 && sig->verify_status == PDKIM_VERIFY_FAIL)
1512 debug_printf("PDKIM: [%s] abandoning this signature\n", sig->domain);
1516 /*XXX The hash of the headers is needed for GCrypt (for which we can do RSA
1517 suging only, as it happens) and for either GnuTLS and OpenSSL when we are
1518 signing with EC (specifically, Ed25519). The former is because the GCrypt
1519 signing operation is pure (does not do its own hash) so we must hash. The
1520 latter is because we (stupidly, but this is what the IETF draft is saying)
1521 must hash with the declared hash method, then pass the result to the library
1522 hash-and-sign routine (because that's all the libraries are providing. And
1523 we're stuck with whatever that hidden hash method is, too). We may as well
1524 do this hash incrementally.
1525 We don't need the hash we're calculating here for the GnuTLS and OpenSSL
1526 cases of RSA signing, since those library routines can do hash-and-sign.
1528 Some time in the future we could easily avoid doing the hash here for those
1529 cases (which will be common for a long while. We could also change from
1530 the current copy-all-the-headers-into-one-block, then call the hash-and-sign
1531 implementation - to a proper incremental one. Unfortunately, GnuTLS just
1532 cannot do incremental - either signing or verification. Unsure about GCrypt.
1535 /*XXX The header hash is also used (so far) by the verify operation */
1537 if (!exim_sha_init(&hhash_ctx, pdkim_hashes[sig->hashtype].exim_hashmethod))
1539 log_write(0, LOG_MAIN|LOG_PANIC,
1540 "PDKIM: hash setup error, possibly nonhandled hashtype");
1544 if (ctx->flags & PDKIM_MODE_SIGN)
1545 DEBUG(D_acl) debug_printf(
1546 "PDKIM >> Headers to be signed: >>>>>>>>>>>>\n"
1550 DEBUG(D_acl) debug_printf(
1551 "PDKIM >> Header data for hash, canonicalized (%-7s), in sequence >>\n",
1552 pdkim_canons[sig->canon_headers]);
1555 /* SIGNING ---------------------------------------------------------------- */
1556 /* When signing, walk through our header list and add them to the hash. As we
1557 go, construct a list of the header's names to use for the h= parameter.
1558 Then append to that list any remaining header names for which there was no
1561 if (ctx->flags & PDKIM_MODE_SIGN)
1564 pdkim_stringlist *p;
1569 /* Import private key, including the keytype which we need for building
1570 the signature header */
1572 /*XXX extend for non-RSA algos */
1573 if ((*err = exim_dkim_signing_init(CUS sig->privkey, &sctx)))
1575 log_write(0, LOG_MAIN|LOG_PANIC, "signing_init: %s", *err);
1576 return PDKIM_ERR_RSA_PRIVKEY;
1578 sig->keytype = sctx.keytype;
1580 for (sig->headernames = NULL, /* Collected signed header names */
1581 p = sig->headers; p; p = p->next)
1583 uschar * rh = p->value;
1585 if (header_name_match(rh, sig->sign_headers) == PDKIM_OK)
1587 /* Collect header names (Note: colon presence is guaranteed here) */
1588 g = string_append_listele_n(g, ':', rh, Ustrchr(rh, ':') - rh);
1590 if (sig->canon_headers == PDKIM_CANON_RELAXED)
1591 rh = pdkim_relax_header(rh, TRUE); /* cook header for relaxed canon */
1593 /* Feed header to the hash algorithm */
1594 exim_sha_update(&hhash_ctx, CUS rh, Ustrlen(rh));
1596 /* Remember headers block for signing (when the library cannot do incremental) */
1597 /*XXX we could avoid doing this for all but the GnuTLS/RSA case */
1598 hdata = exim_dkim_data_append(hdata, rh);
1600 DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1604 /* Any headers we wanted to sign but were not present must also be listed.
1605 Ignore elements that have been ticked-off or are marked as never-oversign. */
1607 l = sig->sign_headers;
1608 while((s = string_nextinlist(&l, &sep, NULL, 0)))
1610 if (*s == '+') /* skip oversigning marker */
1612 if (*s != '_' && *s != '=')
1613 g = string_append_listele(g, ':', s);
1615 sig->headernames = string_from_gstring(g);
1617 /* Create signature header with b= omitted */
1618 sig_hdr = pdkim_create_header(sig, FALSE);
1621 /* VERIFICATION ----------------------------------------------------------- */
1622 /* When verifying, walk through the header name list in the h= parameter and
1623 add the headers to the hash in that order. */
1626 uschar * p = sig->headernames;
1628 pdkim_stringlist * hdrs;
1633 for (hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1639 if ((q = Ustrchr(p, ':')))
1642 /*XXX walk the list of headers in same order as received. */
1643 for (hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1645 && strncasecmp(CCS hdrs->value, CCS p, Ustrlen(p)) == 0
1646 && (hdrs->value)[Ustrlen(p)] == ':'
1649 /* cook header for relaxed canon, or just copy it for simple */
1651 uschar * rh = sig->canon_headers == PDKIM_CANON_RELAXED
1652 ? pdkim_relax_header(hdrs->value, TRUE)
1653 : string_copy(CUS hdrs->value);
1655 /* Feed header to the hash algorithm */
1656 exim_sha_update(&hhash_ctx, CUS rh, Ustrlen(rh));
1658 DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1667 sig_hdr = string_copy(sig->rawsig_no_b_val);
1671 DEBUG(D_acl) debug_printf(
1672 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1677 "PDKIM >> Signed DKIM-Signature header, pre-canonicalized >>>>>>>>>>>>>\n");
1678 pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr));
1680 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1683 /* Relax header if necessary */
1684 if (sig->canon_headers == PDKIM_CANON_RELAXED)
1685 sig_hdr = pdkim_relax_header(sig_hdr, FALSE);
1689 debug_printf("PDKIM >> Signed DKIM-Signature header, canonicalized (%-7s) >>>>>>>\n",
1690 pdkim_canons[sig->canon_headers]);
1691 pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr));
1693 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1696 /* Finalize header hash */
1697 exim_sha_update(&hhash_ctx, CUS sig_hdr, Ustrlen(sig_hdr));
1698 exim_sha_finish(&hhash_ctx, &hhash);
1702 debug_printf("PDKIM [%s] Header %s computed: ",
1703 sig->domain, pdkim_hashes[sig->hashtype].dkim_hashname);
1704 pdkim_hexprint(hhash.data, hhash.len);
1707 /* Remember headers block for signing (when the signing library cannot do
1709 if (ctx->flags & PDKIM_MODE_SIGN)
1710 hdata = exim_dkim_data_append(hdata, US sig_hdr);
1712 /* SIGNING ---------------------------------------------------------------- */
1713 if (ctx->flags & PDKIM_MODE_SIGN)
1715 hashmethod hm = sig->keytype == KEYTYPE_ED25519
1716 #if defined(SIGN_OPENSSL)
1721 : pdkim_hashes[sig->hashtype].exim_hashmethod;
1723 #ifdef SIGN_HAVE_ED25519
1724 /* For GCrypt, and for EC, we pass the hash-of-headers to the signing
1725 routine. For anything else we just pass the headers. */
1727 if (sig->keytype != KEYTYPE_ED25519)
1730 hhash.data = hdata->s;
1731 hhash.len = hdata->ptr;
1734 if ((*err = exim_dkim_sign(&sctx, hm, &hhash, &sig->sighash)))
1736 log_write(0, LOG_MAIN|LOG_PANIC, "signing: %s", *err);
1737 return PDKIM_ERR_RSA_SIGNING;
1742 debug_printf( "PDKIM [%s] b computed: ", sig->domain);
1743 pdkim_hexprint(sig->sighash.data, sig->sighash.len);
1746 sig->signature_header = pdkim_create_header(sig, TRUE);
1749 /* VERIFICATION ----------------------------------------------------------- */
1755 /* Make sure we have all required signature tags */
1756 if (!( sig->domain && *sig->domain
1757 && sig->selector && *sig->selector
1758 && sig->headernames && *sig->headernames
1759 && sig->bodyhash.data
1760 && sig->sighash.data
1761 && sig->keytype >= 0
1762 && sig->hashtype >= 0
1766 sig->verify_status = PDKIM_VERIFY_INVALID;
1767 sig->verify_ext_status = PDKIM_VERIFY_INVALID_SIGNATURE_ERROR;
1769 DEBUG(D_acl) debug_printf(
1770 " Error in DKIM-Signature header: tags missing or invalid (%s)\n"
1771 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
1772 !(sig->domain && *sig->domain) ? "d="
1773 : !(sig->selector && *sig->selector) ? "s="
1774 : !(sig->headernames && *sig->headernames) ? "h="
1775 : !sig->bodyhash.data ? "bh="
1776 : !sig->sighash.data ? "b="
1777 : sig->keytype < 0 || sig->hashtype < 0 ? "a="
1783 /* Make sure sig uses supported DKIM version (only v1) */
1784 if (sig->version != 1)
1786 sig->verify_status = PDKIM_VERIFY_INVALID;
1787 sig->verify_ext_status = PDKIM_VERIFY_INVALID_DKIM_VERSION;
1789 DEBUG(D_acl) debug_printf(
1790 " Error in DKIM-Signature header: unsupported DKIM version\n"
1791 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1797 debug_printf( "PDKIM [%s] b from mail: ", sig->domain);
1798 pdkim_hexprint(sig->sighash.data, sig->sighash.len);
1801 if (!(sig->pubkey = pdkim_key_from_dns(ctx, sig, &vctx, err)))
1803 log_write(0, LOG_MAIN, "PDKIM: %s%s %s%s [failed key import]",
1804 sig->domain ? "d=" : "", sig->domain ? sig->domain : US"",
1805 sig->selector ? "s=" : "", sig->selector ? sig->selector : US"");
1809 /* If the pubkey limits to a list of specific hashes, ignore sigs that
1810 do not have the hash part of the sig algorithm matching */
1812 if (sig->pubkey->hashes)
1814 const uschar * list = sig->pubkey->hashes, * ele;
1816 while ((ele = string_nextinlist(&list, &sep, NULL, 0)))
1817 if (Ustrcmp(ele, pdkim_hashes[sig->hashtype].dkim_hashname) == 0) break;
1820 DEBUG(D_acl) debug_printf("pubkey h=%s vs. sig a=%s_%s\n",
1821 sig->pubkey->hashes,
1822 pdkim_keytypes[sig->keytype],
1823 pdkim_hashes[sig->hashtype].dkim_hashname);
1824 sig->verify_status = PDKIM_VERIFY_FAIL;
1825 sig->verify_ext_status = PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH;
1830 hm = sig->keytype == KEYTYPE_ED25519
1831 #if defined(SIGN_OPENSSL)
1836 : pdkim_hashes[sig->hashtype].exim_hashmethod;
1838 /* Check the signature */
1840 if ((*err = exim_dkim_verify(&vctx, hm, &hhash, &sig->sighash)))
1842 DEBUG(D_acl) debug_printf("headers verify: %s\n", *err);
1843 sig->verify_status = PDKIM_VERIFY_FAIL;
1844 sig->verify_ext_status = PDKIM_VERIFY_FAIL_MESSAGE;
1849 /* We have a winner! (if bodyhash was correct earlier) */
1850 if (sig->verify_status == PDKIM_VERIFY_NONE)
1852 sig->verify_status = PDKIM_VERIFY_PASS;
1860 debug_printf("PDKIM [%s] %s signature status: %s",
1861 sig->domain, dkim_sig_to_a_tag(sig),
1862 pdkim_verify_status_str(sig->verify_status));
1863 if (sig->verify_ext_status > 0)
1864 debug_printf(" (%s)\n",
1865 pdkim_verify_ext_status_str(sig->verify_ext_status));
1872 /* If requested, set return pointer to signature(s) */
1873 if (return_signatures)
1874 *return_signatures = ctx->sig;
1876 return ctx->flags & PDKIM_MODE_SIGN || verify_pass
1877 ? PDKIM_OK : PDKIM_FAIL;
1881 /* -------------------------------------------------------------------------- */
1883 DLLEXPORT pdkim_ctx *
1884 pdkim_init_verify(uschar * (*dns_txt_callback)(uschar *), BOOL dot_stuffing)
1888 ctx = store_get(sizeof(pdkim_ctx));
1889 memset(ctx, 0, sizeof(pdkim_ctx));
1891 if (dot_stuffing) ctx->flags = PDKIM_DOT_TERM;
1892 ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN);
1893 ctx->dns_txt_callback = dns_txt_callback;
1899 /* -------------------------------------------------------------------------- */
1901 DLLEXPORT pdkim_signature *
1902 pdkim_init_sign(pdkim_ctx * ctx,
1903 uschar * domain, uschar * selector, uschar * privkey,
1904 uschar * hashname, const uschar ** errstr)
1907 pdkim_signature * sig;
1909 if (!domain || !selector || !privkey)
1912 /* Allocate & init one signature struct */
1914 sig = store_get(sizeof(pdkim_signature));
1915 memset(sig, 0, sizeof(pdkim_signature));
1917 sig->bodylength = -1;
1919 sig->domain = string_copy(US domain);
1920 sig->selector = string_copy(US selector);
1921 sig->privkey = string_copy(US privkey);
1924 for (hashtype = 0; hashtype < nelem(pdkim_hashes); hashtype++)
1925 if (Ustrcmp(hashname, pdkim_hashes[hashtype].dkim_hashname) == 0)
1926 { sig->hashtype = hashtype; break; }
1927 if (hashtype >= nelem(pdkim_hashes))
1929 log_write(0, LOG_MAIN|LOG_PANIC,
1930 "PDKIM: unrecognised hashname '%s'", hashname);
1936 pdkim_signature s = *sig;
1939 debug_printf("PDKIM (checking verify key)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1940 if (!pdkim_key_from_dns(ctx, &s, &vctx, errstr))
1941 debug_printf("WARNING: bad dkim key in dns\n");
1942 debug_printf("PDKIM (finished checking verify key)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1948 /* -------------------------------------------------------------------------- */
1951 pdkim_set_optional(pdkim_signature * sig,
1952 char * sign_headers,
1957 unsigned long created,
1958 unsigned long expires)
1961 sig->identity = string_copy(US identity);
1963 sig->sign_headers = string_copy(sign_headers
1964 ? US sign_headers : US PDKIM_DEFAULT_SIGN_HEADERS);
1966 sig->canon_headers = canon_headers;
1967 sig->canon_body = canon_body;
1968 sig->bodylength = bodylength;
1969 sig->created = created;
1970 sig->expires = expires;
1977 /* Set up a blob for calculating the bodyhash according to the
1978 given needs. Use an existing one if possible, or create a new one.
1980 Return: hashblob pointer, or NULL on error
1983 pdkim_set_bodyhash(pdkim_ctx * ctx, int hashtype, int canon_method,
1988 for (b = ctx->bodyhash; b; b = b->next)
1989 if ( hashtype == b->hashtype
1990 && canon_method == b->canon_method
1991 && bodylength == b->bodylength)
1993 DEBUG(D_receive) debug_printf("PDKIM: using existing bodyhash %d/%d/%ld\n",
1994 hashtype, canon_method, bodylength);
1998 DEBUG(D_receive) debug_printf("PDKIM: new bodyhash %d/%d/%ld\n",
1999 hashtype, canon_method, bodylength);
2000 b = store_get(sizeof(pdkim_bodyhash));
2001 b->next = ctx->bodyhash;
2002 b->hashtype = hashtype;
2003 b->canon_method = canon_method;
2004 b->bodylength = bodylength;
2005 if (!exim_sha_init(&b->body_hash_ctx, /*XXX hash method: extend for sha512 */
2006 pdkim_hashes[hashtype].exim_hashmethod))
2009 debug_printf("PDKIM: hash init error, possibly nonhandled hashtype\n");
2012 b->signed_body_bytes = 0;
2013 b->num_buffered_blanklines = 0;
2019 /* Set up a blob for calculating the bodyhash according to the
2020 needs of this signature. Use an existing one if possible, or
2023 Return: hashblob pointer, or NULL on error (only used as a boolean).
2026 pdkim_set_sig_bodyhash(pdkim_ctx * ctx, pdkim_signature * sig)
2028 pdkim_bodyhash * b = pdkim_set_bodyhash(ctx,
2029 sig->hashtype, sig->canon_body, sig->bodylength);
2030 sig->calc_body_hash = b;
2035 /* -------------------------------------------------------------------------- */
2039 pdkim_init_context(pdkim_ctx * ctx, BOOL dot_stuffed,
2040 uschar * (*dns_txt_callback)(uschar *))
2042 memset(ctx, 0, sizeof(pdkim_ctx));
2043 ctx->flags = dot_stuffed ? PDKIM_MODE_SIGN | PDKIM_DOT_TERM : PDKIM_MODE_SIGN;
2044 ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN);
2045 DEBUG(D_acl) ctx->dns_txt_callback = dns_txt_callback;
2057 #endif /*DISABLE_DKIM*/