2 * PDKIM - a RFC4871 (DKIM) implementation
4 * Copyright (c) The Exim Maintainers 2021 - 2024
5 * Copyright (C) 2016 - 2020 Jeremy Harris <jgh@exim.org>
6 * Copyright (C) 2009 - 2016 Tom Kistner <tom@duncanthrax.net>
7 * SPDX-License-Identifier: GPL-2.0-or-later
9 * http://duncanthrax.net/pdkim/
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #ifndef DISABLE_DKIM /* entire file */
32 # error Must not DISABLE_TLS, for DKIM
35 #include "crypt_ver.h"
38 # include <openssl/rsa.h>
39 # include <openssl/ssl.h>
40 # include <openssl/err.h>
41 #elif defined(SIGN_GNUTLS)
42 # include <gnutls/gnutls.h>
43 # include <gnutls/x509.h>
49 #define PDKIM_SIGNATURE_VERSION "1"
50 #define PDKIM_PUB_RECORD_VERSION US "DKIM1"
52 #define PDKIM_MAX_HEADER_LEN 65536
53 #define PDKIM_MAX_HEADERS 512
54 #define PDKIM_MAX_BODY_LINE_LEN 16384
55 #define PDKIM_DNS_TXT_MAX_NAMELEN 1024
57 /* -------------------------------------------------------------------------- */
58 struct pdkim_stringlist {
64 /* -------------------------------------------------------------------------- */
65 /* A bunch of list constants */
66 const uschar * pdkim_querymethods[] = {
70 const uschar * pdkim_canons[] = {
76 const pdkim_hashtype pdkim_hashes[] = {
77 { US"sha1", HASH_SHA1 },
78 { US"sha256", HASH_SHA2_256 },
79 { US"sha512", HASH_SHA2_512 }
82 const uschar * pdkim_keytypes[] = {
83 [KEYTYPE_RSA] = US"rsa",
84 #ifdef SIGN_HAVE_ED25519
85 [KEYTYPE_ED25519] = US"ed25519", /* Works for 3.6.0 GnuTLS, OpenSSL 1.1.1 */
88 #ifdef notyet_EC_dkim_extensions /* https://tools.ietf.org/html/draft-srose-dkim-ecc-00 */
95 typedef struct pdkim_combined_canon_entry {
99 } pdkim_combined_canon_entry;
101 pdkim_combined_canon_entry pdkim_combined_canons[] = {
102 { US"simple/simple", PDKIM_CANON_SIMPLE, PDKIM_CANON_SIMPLE },
103 { US"simple/relaxed", PDKIM_CANON_SIMPLE, PDKIM_CANON_RELAXED },
104 { US"relaxed/simple", PDKIM_CANON_RELAXED, PDKIM_CANON_SIMPLE },
105 { US"relaxed/relaxed", PDKIM_CANON_RELAXED, PDKIM_CANON_RELAXED },
106 { US"simple", PDKIM_CANON_SIMPLE, PDKIM_CANON_SIMPLE },
107 { US"relaxed", PDKIM_CANON_RELAXED, PDKIM_CANON_SIMPLE },
112 static const blob lineending = {.data = US"\r\n", .len = 2};
114 /* -------------------------------------------------------------------------- */
116 dkim_sig_to_a_tag(const pdkim_signature * sig)
118 if ( sig->keytype < 0 || sig->keytype > nelem(pdkim_keytypes)
119 || sig->hashtype < 0 || sig->hashtype > nelem(pdkim_hashes))
121 return string_sprintf("%s-%s",
122 pdkim_keytypes[sig->keytype], pdkim_hashes[sig->hashtype].dkim_hashname);
127 pdkim_keyname_to_keytype(const uschar * s)
129 for (int i = 0; i < nelem(pdkim_keytypes); i++)
130 if (Ustrcmp(s, pdkim_keytypes[i]) == 0) return i;
135 pdkim_hashname_to_hashtype(const uschar * s, unsigned len)
137 if (!len) len = Ustrlen(s);
138 for (int i = 0; i < nelem(pdkim_hashes); i++)
139 if (Ustrncmp(s, pdkim_hashes[i].dkim_hashname, len) == 0)
145 pdkim_cstring_to_canons(const uschar * s, unsigned len,
146 int * canon_head, int * canon_body)
148 if (!len) len = Ustrlen(s);
149 for (int i = 0; pdkim_combined_canons[i].str; i++)
150 if ( Ustrncmp(s, pdkim_combined_canons[i].str, len) == 0
151 && len == Ustrlen(pdkim_combined_canons[i].str))
153 *canon_head = pdkim_combined_canons[i].canon_headers;
154 *canon_body = pdkim_combined_canons[i].canon_body;
162 pdkim_verify_status_str(int status)
166 case PDKIM_VERIFY_NONE: return "PDKIM_VERIFY_NONE";
167 case PDKIM_VERIFY_INVALID: return "PDKIM_VERIFY_INVALID";
168 case PDKIM_VERIFY_FAIL: return "PDKIM_VERIFY_FAIL";
169 case PDKIM_VERIFY_PASS: return "PDKIM_VERIFY_PASS";
170 default: return "PDKIM_VERIFY_UNKNOWN";
175 pdkim_verify_ext_status_str(int ext_status)
179 case PDKIM_VERIFY_FAIL_BODY: return "PDKIM_VERIFY_FAIL_BODY";
180 case PDKIM_VERIFY_FAIL_MESSAGE: return "PDKIM_VERIFY_FAIL_MESSAGE";
181 case PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH: return "PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH";
182 case PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE: return "PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE";
183 case PDKIM_VERIFY_INVALID_BUFFER_SIZE: return "PDKIM_VERIFY_INVALID_BUFFER_SIZE";
184 case PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD: return "PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD";
185 case PDKIM_VERIFY_INVALID_PUBKEY_IMPORT: return "PDKIM_VERIFY_INVALID_PUBKEY_IMPORT";
186 case PDKIM_VERIFY_INVALID_PUBKEY_KEYSIZE: return "PDKIM_VERIFY_INVALID_PUBKEY_KEYSIZE";
187 case PDKIM_VERIFY_INVALID_SIGNATURE_ERROR: return "PDKIM_VERIFY_INVALID_SIGNATURE_ERROR";
188 case PDKIM_VERIFY_INVALID_DKIM_VERSION: return "PDKIM_VERIFY_INVALID_DKIM_VERSION";
189 default: return "PDKIM_VERIFY_UNKNOWN";
194 pdkim_errstr(int status)
198 case PDKIM_OK: return US"OK";
199 case PDKIM_FAIL: return US"FAIL";
200 case PDKIM_ERR_RSA_PRIVKEY: return US"PRIVKEY";
201 case PDKIM_ERR_RSA_SIGNING: return US"SIGNING";
202 case PDKIM_ERR_LONG_LINE: return US"LONG_LINE";
203 case PDKIM_ERR_BUFFER_TOO_SMALL: return US"BUFFER_TOO_SMALL";
204 case PDKIM_ERR_EXCESS_SIGS: return US"EXCESS_SIGS";
205 case PDKIM_SIGN_PRIVKEY_WRAP: return US"PRIVKEY_WRAP";
206 case PDKIM_SIGN_PRIVKEY_B64D: return US"PRIVKEY_B64D";
207 default: return US"(unknown)";
212 /* -------------------------------------------------------------------------- */
213 /* Print debugging functions */
215 pdkim_quoteprint(const uschar *data, int len)
217 for (int i = 0; i < len; i++)
219 const int c = data[i];
222 case ' ' : debug_printf("{SP}"); break;
223 case '\t': debug_printf("{TB}"); break;
224 case '\r': debug_printf("{CR}"); break;
225 case '\n': debug_printf("{LF}"); break;
226 case '{' : debug_printf("{BO}"); break;
227 case '}' : debug_printf("{BC}"); break;
229 if ( (c < 32) || (c > 127) )
230 debug_printf("{%02x}", c);
232 debug_printf("%c", c);
240 pdkim_hexprint(const uschar *data, int len)
242 if (data) for (int i = 0 ; i < len; i++) debug_printf("%02x", data[i]);
243 else debug_printf("<NULL>");
249 static pdkim_stringlist *
250 pdkim_prepend_stringlist(pdkim_stringlist * base, const uschar * str)
252 pdkim_stringlist * new_entry = store_get(sizeof(pdkim_stringlist), GET_UNTAINTED);
254 memset(new_entry, 0, sizeof(pdkim_stringlist));
255 new_entry->value = string_copy(str);
256 if (base) new_entry->next = base;
262 /* Trim whitespace fore & aft */
265 pdkim_strtrim(gstring * str)
270 while (*p == '\t' || *p == ' ') /* dump the leading whitespace */
271 { str->size--; str->ptr--; str->s++; }
274 && ((q = str->s + str->ptr - 1), (*q == '\t' || *q == ' '))
276 str->ptr--; /* dump trailing whitespace */
278 (void) string_from_gstring(str);
283 /* -------------------------------------------------------------------------- */
286 pdkim_free_ctx(pdkim_ctx *ctx)
291 /* -------------------------------------------------------------------------- */
292 /* Matches the name of the passed raw "header" against
293 the passed colon-separated "tick", and invalidates
294 the entry in tick. Entries can be prefixed for multi- or over-signing,
295 in which case do not invalidate.
297 Returns OK for a match, or fail-code
301 header_name_match(const uschar * header, uschar * tick)
303 const uschar * ticklist = tick;
306 uschar * hname, * p, * ele;
307 uschar * hcolon = Ustrchr(header, ':'); /* Get header name */
310 return PDKIM_FAIL; /* This isn't a header */
312 /* if we had strncmpic() we wouldn't need this copy */
313 hname = string_copyn(header, hcolon-header);
315 while (p = US ticklist, ele = string_nextinlist(&ticklist, &sep, NULL, 0))
319 case '=': case '+': multisign = TRUE; ele++; break;
320 default: multisign = FALSE; break;
323 if (strcmpic(ele, hname) == 0)
326 *p = '_'; /* Invalidate this header name instance in tick-off list */
334 /* -------------------------------------------------------------------------- */
335 /* Performs "relaxed" canonicalization of a header. */
338 pdkim_relax_header_n(const uschar * header, int len, BOOL append_crlf)
340 BOOL past_field_name = FALSE;
341 BOOL seen_wsp = FALSE;
342 uschar * relaxed = store_get(len+3, GET_TAINTED);
343 uschar * q = relaxed;
345 for (const uschar * p = header; p - header < len; p++)
349 if (c == '\r' || c == '\n') /* Ignore CR & LF */
351 if (c == '\t' || c == ' ')
355 c = ' '; /* Turns WSP into SP */
359 if (!past_field_name && c == ':')
361 if (seen_wsp) q--; /* This removes WSP immediately before the colon */
362 seen_wsp = TRUE; /* This removes WSP immediately after the colon */
363 past_field_name = TRUE;
368 /* Lowercase header name */
369 if (!past_field_name) c = tolower(c);
373 if (q > relaxed && q[-1] == ' ') q--; /* Squash eventual trailing SP */
375 if (append_crlf) { *q++ = '\r'; *q++ = '\n'; }
382 pdkim_relax_header(const uschar * header, BOOL append_crlf)
384 return pdkim_relax_header_n(header, Ustrlen(header), append_crlf);
388 /* -------------------------------------------------------------------------- */
389 #define PDKIM_QP_ERROR_DECODE -1
391 static const uschar *
392 pdkim_decode_qp_char(const uschar *qp_p, int *c)
394 const uschar *initial_pos = qp_p;
396 /* Advance one char */
399 /* Check for two hex digits and decode them */
400 if (isxdigit(*qp_p) && isxdigit(qp_p[1]))
402 /* Do hex conversion */
403 *c = (isdigit(*qp_p) ? *qp_p - '0' : toupper(*qp_p) - 'A' + 10) << 4;
404 *c |= isdigit(qp_p[1]) ? qp_p[1] - '0' : toupper(qp_p[1]) - 'A' + 10;
408 /* Illegal char here */
409 *c = PDKIM_QP_ERROR_DECODE;
414 /* -------------------------------------------------------------------------- */
417 pdkim_decode_qp(const uschar * str)
421 const uschar * p = str;
422 uschar * n = store_get(Ustrlen(str)+1, GET_TAINTED);
430 p = pdkim_decode_qp_char(p, &nchar);
446 /* -------------------------------------------------------------------------- */
449 pdkim_decode_base64(const uschar * str, blob * b)
451 int dlen = b64decode(str, &b->data, str);
452 if (dlen < 0) b->data = NULL;
457 pdkim_encode_base64(blob * b)
459 return b64encode(CUS b->data, b->len);
463 /* -------------------------------------------------------------------------- */
464 #define PDKIM_HDR_LIMBO 0
465 #define PDKIM_HDR_TAG 1
466 #define PDKIM_HDR_VALUE 2
468 static pdkim_signature *
469 pdkim_parse_sig_header(pdkim_ctx * ctx, uschar * raw_hdr)
471 pdkim_signature * sig = store_get(sizeof(pdkim_signature), GET_UNTAINTED);
473 gstring * cur_tag = NULL, * cur_val = NULL;
474 BOOL past_hname = FALSE, in_b_val = FALSE;
475 int where = PDKIM_HDR_LIMBO;
477 memset(sig, 0, sizeof(pdkim_signature));
478 sig->bodylength = -1;
480 /* Set so invalid/missing data error display is accurate */
485 q = sig->rawsig_no_b_val = store_get(Ustrlen(raw_hdr)+1, GET_TAINTED);
487 for (uschar * p = raw_hdr; ; p++)
492 if (c == '\r' || c == '\n')
495 /* Fast-forward through header name */
498 if (c == ':') past_hname = TRUE;
502 if (where == PDKIM_HDR_LIMBO)
504 /* In limbo, just wait for a tag-char to appear */
505 if (!(c >= 'a' && c <= 'z'))
508 where = PDKIM_HDR_TAG;
511 if (where == PDKIM_HDR_TAG)
514 if (Ustrcmp(string_from_gstring(cur_tag), "b") == 0)
519 where = PDKIM_HDR_VALUE;
522 else if (!isspace(c))
523 cur_tag = string_catn(cur_tag, p, 1);
525 if (where == PDKIM_HDR_VALUE)
527 if (c == '\r' || c == '\n' || c == ' ' || c == '\t')
530 if (c == ';' || c == '\0')
532 /* We must have both tag and value, and tags must be one char except
533 for the possibility of "bh". */
535 if ( cur_tag && cur_val
536 && (cur_tag->ptr == 1 || *cur_tag->s == 'b')
539 (void) string_from_gstring(cur_val);
540 pdkim_strtrim(cur_val);
542 DEBUG(D_acl) debug_printf(" %s=%s\n", cur_tag->s, cur_val->s);
546 case 'b': /* sig-data or body-hash */
547 switch (cur_tag->s[1])
549 case '\0': pdkim_decode_base64(cur_val->s, &sig->sighash); break;
550 case 'h': if (cur_tag->ptr != 2) goto bad_tag;
551 pdkim_decode_base64(cur_val->s, &sig->bodyhash);
553 default: goto bad_tag;
556 case 'v': /* version */
557 /* We only support version 1, and that is currently the
558 only version there is. */
560 Ustrcmp(cur_val->s, PDKIM_SIGNATURE_VERSION) == 0 ? 1 : -1;
562 case 'a': /* algorithm */
564 const uschar * list = cur_val->s;
568 if ((elem = string_nextinlist(&list, &sep, NULL, 0)))
569 sig->keytype = pdkim_keyname_to_keytype(elem);
570 if ((elem = string_nextinlist(&list, &sep, NULL, 0)))
571 for (int i = 0; i < nelem(pdkim_hashes); i++)
572 if (Ustrcmp(elem, pdkim_hashes[i].dkim_hashname) == 0)
573 { sig->hashtype = i; break; }
577 case 'c': /* canonicalization */
578 pdkim_cstring_to_canons(cur_val->s, 0,
579 &sig->canon_headers, &sig->canon_body);
581 case 'q': /* Query method (for pubkey)*/
582 for (int i = 0; pdkim_querymethods[i]; i++)
583 if (Ustrcmp(cur_val->s, pdkim_querymethods[i]) == 0)
585 sig->querymethod = i; /* we never actually use this */
589 case 's': /* Selector */
590 sig->selector = string_copy_from_gstring(cur_val); break;
592 sig->domain = string_copy_from_gstring(cur_val); break;
594 sig->identity = pdkim_decode_qp(cur_val->s); break;
595 case 't': /* Timestamp */
596 sig->created = strtoul(CS cur_val->s, NULL, 10); break;
597 case 'x': /* Expiration */
598 sig->expires = strtoul(CS cur_val->s, NULL, 10); break;
599 case 'l': /* Body length count */
600 sig->bodylength = strtol(CS cur_val->s, NULL, 10); break;
601 case 'h': /* signed header fields */
602 sig->headernames = string_copy_from_gstring(cur_val); break;
603 case 'z': /* Copied headfields */
604 sig->copiedheaders = pdkim_decode_qp(cur_val->s); break;
605 /*XXX draft-ietf-dcrup-dkim-crypto-05 would need 'p' tag support
606 for rsafp signatures. But later discussion is dropping those. */
612 bad_tag: DEBUG(D_acl) debug_printf(" Unknown tag encountered: %Y\n", cur_tag);
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 "DKIM >> Raw signature w/o b= tag value >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
642 pdkim_quoteprint(US sig->rawsig_no_b_val, Ustrlen(sig->rawsig_no_b_val));
644 "DKIM >> Sig size: %4u bits\n", (unsigned) sig->sighash.len*8);
646 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
649 if (!pdkim_set_sig_bodyhash(ctx, sig))
656 /* -------------------------------------------------------------------------- */
659 pdkim_parse_pubkey_record(const uschar * raw_record)
661 pdkim_pubkey * pub = store_get(sizeof(pdkim_pubkey), GET_TAINTED);
663 memset(pub, 0, sizeof(pdkim_pubkey));
665 for (const uschar * ele = raw_record, * tspec, * end, * val; *ele; ele = end)
667 Uskip_whitespace(&ele);
668 end = Ustrchrnul(ele, ';');
669 tspec = string_copyn(ele, end - ele);
670 if (*end) end++; /* skip the ; */
672 if ((val = Ustrchr(tspec, '=')))
674 int taglen = val++ - tspec;
676 DEBUG(D_acl) debug_printf(" %.*s=%s\n", taglen, tspec, val);
677 while (taglen > 1 && isspace(tspec[taglen-1]))
678 taglen--; /* Ignore whitespace before = */
679 Uskip_whitespace(&val); /* Ignore whitespace after = */
680 if (isspace(val[ Ustrlen(val)-1 ]))
681 { /* Ignore whitespace after value */
682 gstring * g = string_cat(NULL, val);
683 while (isspace(gstring_last_char(g)))
685 val = string_from_gstring(g);
688 if (taglen == 1) switch (tspec[0])
690 case 'v': pub->version = val; break;
691 case 'h': pub->hashes = val; break;
692 case 'k': pub->keytype = val; break;
693 case 'g': pub->granularity = val; break;
694 case 'n': pub->notes = pdkim_decode_qp(val); break;
695 case 'p': pdkim_decode_base64(val, &pub->key); break;
696 case 's': pub->srvtype = val; break;
697 case 't': if (Ustrchr(val, 'y')) pub->testing = 1;
698 if (Ustrchr(val, 's')) pub->no_subdomaining = 1;
700 default: goto bad_tag;
704 DEBUG(D_acl) debug_printf(" Unknown tag encountered\n");
708 /* Set fallback defaults */
710 pub->version = string_copy(PDKIM_PUB_RECORD_VERSION);
711 else if (Ustrcmp(pub->version, PDKIM_PUB_RECORD_VERSION) != 0)
713 DEBUG(D_acl) debug_printf(" Bad v= field\n");
717 if (!pub->granularity) pub->granularity = US"*";
718 if (!pub->keytype ) pub->keytype = US"rsa";
719 if (!pub->srvtype ) pub->srvtype = US"*";
725 DEBUG(D_acl) debug_printf(" Missing p= field\n");
730 /* -------------------------------------------------------------------------- */
732 /* Update one bodyhash with some additional data.
733 If we have to relax the data for this sig, return our copy of it. */
736 pdkim_update_ctx_bodyhash(pdkim_bodyhash * b, const blob * orig_data, blob * relaxed_data)
738 const blob * canon_data = orig_data;
741 /* Defaults to simple canon (no further treatment necessary) */
743 if (b->canon_method == PDKIM_CANON_RELAXED)
745 /* Relax the line if not done already */
748 BOOL seen_wsp = FALSE;
751 /* We want to be able to free this else we allocate
752 for the entire message which could be many MB. Since
753 we don't know what allocations the SHA routines might
754 do, not safe to use store_get()/store_reset(). */
756 relaxed_data = store_malloc(sizeof(blob) + orig_data->len+1);
757 relaxed_data->data = US (relaxed_data+1);
759 for (const uschar * p = orig_data->data, * r = p + orig_data->len; p < r; p++)
764 if (q > 0 && relaxed_data->data[q-1] == ' ')
767 else if (c == '\t' || c == ' ')
769 c = ' '; /* Turns WSP into SP */
776 relaxed_data->data[q++] = c;
778 relaxed_data->data[q] = '\0';
779 relaxed_data->len = q;
781 canon_data = relaxed_data;
784 /* Make sure we don't exceed the to-be-signed body length */
785 left = canon_data->len;
786 if ( b->bodylength >= 0
787 && left > (unsigned long)b->bodylength - b->signed_body_bytes
789 left = (unsigned long)b->bodylength - b->signed_body_bytes;
793 exim_sha_update(&b->body_hash_ctx, CUS canon_data->data, left);
794 b->signed_body_bytes += left;
795 DEBUG(D_acl) pdkim_quoteprint(canon_data->data, left);
802 /* -------------------------------------------------------------------------- */
805 pdkim_finish_bodyhash(pdkim_ctx * ctx)
807 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next) /* Finish hashes */
809 DEBUG(D_acl) debug_printf("DKIM: finish bodyhash %s/%s/%ld len %ld\n",
810 pdkim_hashes[b->hashtype].dkim_hashname, pdkim_canons[b->canon_method],
811 b->bodylength, b->signed_body_bytes);
812 exim_sha_finish(&b->body_hash_ctx, &b->bh);
815 /* Traverse all signatures */
816 for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next)
818 pdkim_bodyhash * b = sig->calc_body_hash;
822 debug_printf("DKIM [%s]%s Body bytes (%s) hashed: %lu\n"
823 "DKIM [%s]%s Body %s computed: ",
824 sig->domain, sig->selector, pdkim_canons[b->canon_method], b->signed_body_bytes,
825 sig->domain, sig->selector, pdkim_hashes[b->hashtype].dkim_hashname);
826 pdkim_hexprint(CUS b->bh.data, b->bh.len);
829 /* SIGNING -------------------------------------------------------------- */
830 if (ctx->flags & PDKIM_MODE_SIGN)
832 /* If bodylength limit is set, and we have received less bytes
833 than the requested amount, effectively remove the limit tag. */
834 if (b->signed_body_bytes < sig->bodylength)
835 sig->bodylength = -1;
839 /* VERIFICATION --------------------------------------------------------- */
840 /* Be careful that the header sig included a bodyash */
842 if (sig->bodyhash.data && sig->bodyhash.len == b->bh.len
843 && memcmp(b->bh.data, sig->bodyhash.data, b->bh.len) == 0)
845 DEBUG(D_acl) debug_printf("DKIM [%s] Body hash compared OK\n", sig->domain);
851 debug_printf("DKIM [%s] Body hash signature from headers: ", sig->domain);
852 pdkim_hexprint(sig->bodyhash.data, sig->bodyhash.len);
853 debug_printf("DKIM [%s] Body hash did NOT verify\n", sig->domain);
855 sig->verify_status = PDKIM_VERIFY_FAIL;
856 sig->verify_ext_status = PDKIM_VERIFY_FAIL_BODY;
864 pdkim_body_complete(pdkim_ctx * ctx)
866 /* In simple body mode, if any empty lines were buffered,
867 replace with one. rfc 4871 3.4.3 */
868 /*XXX checking the signed-body-bytes is a gross hack; I think
869 it indicates that all linebreaks should be buffered, including
870 the one terminating a text line */
872 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
873 if ( b->canon_method == PDKIM_CANON_SIMPLE
874 && b->signed_body_bytes == 0
875 && b->num_buffered_blanklines > 0
877 (void) pdkim_update_ctx_bodyhash(b, &lineending, NULL);
879 ctx->flags |= PDKIM_SEEN_EOD;
880 ctx->linebuf_offset = 0;
885 /* -------------------------------------------------------------------------- */
886 /* Call from pdkim_feed below for processing complete body lines */
887 /* NOTE: the line is not NUL-terminated; but we have a count */
890 pdkim_bodyline_complete(pdkim_ctx * ctx)
892 blob line = {.data = ctx->linebuf, .len = ctx->linebuf_offset};
896 /* Ignore extra data if we've seen the end-of-data marker */
897 if (ctx->flags & PDKIM_SEEN_EOD) goto all_skip;
899 /* We've always got one extra byte to stuff a zero ... */
900 ctx->linebuf[line.len] = '\0';
902 /* Terminate on EOD marker */
903 if (ctx->flags & PDKIM_DOT_TERM)
905 if (memcmp(line.data, ".\r\n", 3) == 0)
906 { pdkim_body_complete(ctx); return; }
909 if (memcmp(line.data, "..", 2) == 0)
910 { line.data++; line.len--; }
913 /* Empty lines need to be buffered until we find a non-empty line */
914 if (memcmp(line.data, "\r\n", 2) == 0)
916 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
917 b->num_buffered_blanklines++;
921 /* Process line for each bodyhash separately */
922 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
924 if (b->canon_method == PDKIM_CANON_RELAXED)
926 /* Lines with just spaces need to be buffered too */
927 uschar * cp = line.data;
932 if (c == '\r' && cp[1] == '\n') break;
933 if (c != ' ' && c != '\t') goto hash_process;
937 b->num_buffered_blanklines++;
942 /* At this point, we have a non-empty line, so release the buffered ones. */
944 while (b->num_buffered_blanklines)
946 rnl = pdkim_update_ctx_bodyhash(b, &lineending, rnl);
947 b->num_buffered_blanklines--;
950 rline = pdkim_update_ctx_bodyhash(b, &line, rline);
954 if (rnl) store_free(rnl);
955 if (rline) store_free(rline);
959 ctx->linebuf_offset = 0;
964 /* -------------------------------------------------------------------------- */
965 /* Callback from pdkim_feed below for processing complete headers */
966 #define DKIM_SIGNATURE_HEADERNAME "DKIM-Signature:"
969 pdkim_header_complete(pdkim_ctx * ctx)
971 if (ctx->cur_header->ptr > 1)
972 gstring_trim_trailing(ctx->cur_header, '\r');
973 (void) string_from_gstring(ctx->cur_header);
975 #ifdef EXPERIMENTAL_ARC
976 /* Feed the header line to ARC processing */
977 (void) arc_header_feed(ctx->cur_header, !(ctx->flags & PDKIM_MODE_SIGN));
980 if (++ctx->num_headers > PDKIM_MAX_HEADERS) goto BAIL;
982 /* SIGNING -------------------------------------------------------------- */
983 if (ctx->flags & PDKIM_MODE_SIGN)
984 for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) /* Traverse all signatures */
986 /* Add header to the signed headers list (in reverse order) */
987 sig->headers = pdkim_prepend_stringlist(sig->headers, ctx->cur_header->s);
989 /* VERIFICATION ----------------------------------------------------------- */
990 /* DKIM-Signature: headers are added to the verification list */
996 debug_printf("DKIM >> raw hdr: ");
997 pdkim_quoteprint(CUS ctx->cur_header->s, ctx->cur_header->ptr);
1000 if (strncasecmp(CCS ctx->cur_header->s,
1001 DKIM_SIGNATURE_HEADERNAME,
1002 Ustrlen(DKIM_SIGNATURE_HEADERNAME)) == 0)
1004 pdkim_signature * sig, * last_sig;
1005 /* Create and chain new signature block. We could error-check for all
1006 required tags here, but prefer to create the internal sig and expicitly
1007 fail verification of it later. */
1009 DEBUG(D_acl) debug_printf(
1010 "DKIM >> Found sig, trying to parse >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1012 sig = pdkim_parse_sig_header(ctx, ctx->cur_header->s);
1014 if (!(last_sig = ctx->sig))
1018 while (last_sig->next) last_sig = last_sig->next;
1019 last_sig->next = sig;
1022 if (dkim_collect_input && --dkim_collect_input == 0)
1024 ctx->headers = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->s);
1025 ctx->cur_header->s[ctx->cur_header->ptr = 0] = '\0';
1026 return PDKIM_ERR_EXCESS_SIGS;
1030 /* all headers are stored for signature verification */
1031 ctx->headers = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->s);
1035 ctx->cur_header->s[ctx->cur_header->ptr = 0] = '\0'; /* leave buffer for reuse */
1041 /* -------------------------------------------------------------------------- */
1042 #define HEADER_BUFFER_FRAG_SIZE 256
1045 pdkim_feed(pdkim_ctx * ctx, uschar * data, int len)
1047 /* Alternate EOD signal, used in non-dotstuffing mode */
1049 pdkim_body_complete(ctx);
1051 else for (int p = 0; p < len; p++)
1056 if (ctx->flags & PDKIM_PAST_HDRS)
1058 if (c == '\n' && !(ctx->flags & PDKIM_SEEN_CR)) /* emulate the CR */
1060 ctx->linebuf[ctx->linebuf_offset++] = '\r';
1061 if (ctx->linebuf_offset == PDKIM_MAX_BODY_LINE_LEN-1)
1062 return PDKIM_ERR_LONG_LINE;
1065 /* Processing body byte */
1066 ctx->linebuf[ctx->linebuf_offset++] = c;
1068 ctx->flags |= PDKIM_SEEN_CR;
1071 ctx->flags &= ~PDKIM_SEEN_CR;
1072 pdkim_bodyline_complete(ctx);
1075 if (ctx->linebuf_offset == PDKIM_MAX_BODY_LINE_LEN-1)
1076 return PDKIM_ERR_LONG_LINE;
1080 /* Processing header byte */
1082 ctx->flags |= PDKIM_SEEN_CR;
1085 if (!(ctx->flags & PDKIM_SEEN_CR)) /* emulate the CR */
1086 ctx->cur_header = string_catn(ctx->cur_header, CUS "\r", 1);
1088 if (ctx->flags & PDKIM_SEEN_LF) /* Seen last header line */
1090 if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1093 ctx->flags = (ctx->flags & ~(PDKIM_SEEN_LF|PDKIM_SEEN_CR)) | PDKIM_PAST_HDRS;
1094 DEBUG(D_acl) debug_printf(
1095 "DKIM >> Body data for hash, canonicalized >>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1099 ctx->flags = (ctx->flags & ~PDKIM_SEEN_CR) | PDKIM_SEEN_LF;
1101 else if (ctx->flags & PDKIM_SEEN_LF)
1103 if (!(c == '\t' || c == ' ')) /* End of header */
1104 if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1106 ctx->flags &= ~PDKIM_SEEN_LF;
1109 if (!ctx->cur_header || ctx->cur_header->ptr < PDKIM_MAX_HEADER_LEN)
1110 ctx->cur_header = string_catn(ctx->cur_header, CUS &data[p], 1);
1118 /* Extend a growing header with a continuation-linebreak */
1120 pdkim_hdr_cont(gstring * str, int * col)
1123 return string_catn(str, US"\r\n\t", 3);
1129 * RFC 5322 specifies that header line length SHOULD be no more than 78
1132 * Returns gstring (not nul-terminated) appending to one supplied
1134 * col: this int holds and receives column number (octets since last '\n')
1135 * str: partial string to append to
1136 * pad: padding, split line or space after before or after eg: ";".
1137 * Only the initial charater is used.
1138 * intro: - must join to payload eg "h=", usually the tag name
1139 * payload: eg base64 data - long data can be split arbitrarily.
1141 * this code doesn't fold the header in some of the places that RFC4871
1142 * allows: As per RFC5322(2.2.3) it only folds before or after tag-value
1143 * pairs and inside long values. it also always spaces or breaks after the
1146 * No guarantees are made for output given out-of range input. like tag
1147 * names longer than 78, or bogus col. Input is assumed to be free of line breaks.
1151 pdkim_headcat(int * col, gstring * str,
1152 const uschar * pad, const uschar * intro, const uschar * payload)
1154 int len, chomp, padded = 0;
1156 /* If we can fit at least the pad at the end of current line, do it now.
1157 Otherwise, wrap if there is a pad. */
1162 str = string_catn(str, pad, 1);
1168 str = pdkim_hdr_cont(str, col);
1170 /* Special case: if the whole addition does not fit at the end of the current
1171 line, but could fit on a new line, wrap to give it its full, dedicated line. */
1173 len = (pad ? 2 : padded)
1174 + (intro ? Ustrlen(intro) : 0)
1175 + (payload ? Ustrlen(payload) : 0);
1176 if (len <= 77 && *col+len > 78)
1178 str = pdkim_hdr_cont(str, col);
1182 /* Either we already dealt with the pad or we know there is room */
1186 str = string_catn(str, pad, 1);
1187 str = string_catn(str, US" ", 1);
1190 else if (padded && *col < 78)
1192 str = string_catn(str, US" ", 1);
1196 /* Call recursively with intro as payload: it gets the same, special treatment
1197 (that is, not split if < 78). */
1200 str = pdkim_headcat(col, str, NULL, NULL, intro);
1203 for (len = Ustrlen(payload); len; len -= chomp)
1206 str = pdkim_hdr_cont(str, col);
1207 chomp = *col+len > 78 ? 78 - *col : len;
1208 str = string_catn(str, payload, chomp);
1217 /* -------------------------------------------------------------------------- */
1219 /* Signing: create signature header
1222 pdkim_create_header(pdkim_signature * sig, BOOL final)
1228 gstring * canon_all;
1230 canon_all = string_cat (NULL, pdkim_canons[sig->canon_headers]);
1231 canon_all = string_catn(canon_all, US"/", 1);
1232 canon_all = string_cat (canon_all, pdkim_canons[sig->canon_body]);
1233 (void) string_from_gstring(canon_all);
1235 hdr = string_cat(NULL, US"DKIM-Signature: v="PDKIM_SIGNATURE_VERSION);
1238 /* Required and static bits */
1239 hdr = pdkim_headcat(&col, hdr, US";", US"a=", dkim_sig_to_a_tag(sig));
1240 hdr = pdkim_headcat(&col, hdr, US";", US"q=", pdkim_querymethods[sig->querymethod]);
1241 hdr = pdkim_headcat(&col, hdr, US";", US"c=", canon_all->s);
1242 hdr = pdkim_headcat(&col, hdr, US";", US"d=", sig->domain);
1243 hdr = pdkim_headcat(&col, hdr, US";", US"s=", sig->selector);
1245 /* list of header names can be split between items. */
1247 uschar * n = string_copy(sig->headernames);
1248 uschar * i = US"h=";
1253 uschar * c = Ustrchr(n, ':');
1258 hdr = pdkim_headcat(&col, hdr, NULL, NULL, US":");
1260 hdr = pdkim_headcat(&col, hdr, s, i, n);
1271 base64_bh = pdkim_encode_base64(&sig->calc_body_hash->bh);
1272 hdr = pdkim_headcat(&col, hdr, US";", US"bh=", base64_bh);
1276 hdr = pdkim_headcat(&col, hdr, US";", US"i=", sig->identity);
1278 if (sig->created > 0)
1282 snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->created);
1283 hdr = pdkim_headcat(&col, hdr, US";", US"t=", minibuf);
1286 if (sig->expires > 0)
1290 snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->expires);
1291 hdr = pdkim_headcat(&col, hdr, US";", US"x=", minibuf);
1294 if (sig->bodylength >= 0)
1298 snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->bodylength);
1299 hdr = pdkim_headcat(&col, hdr, US";", US"l=", minibuf);
1302 /* Preliminary or final version? */
1305 base64_b = pdkim_encode_base64(&sig->sighash);
1306 hdr = pdkim_headcat(&col, hdr, US";", US"b=", base64_b);
1308 /* add trailing semicolon: I'm not sure if this is actually needed */
1309 hdr = pdkim_headcat(&col, hdr, NULL, US";", US"");
1313 /* To satisfy the rule "all surrounding whitespace [...] deleted"
1314 ( RFC 6376 section 3.7 ) we ensure there is no whitespace here. Otherwise
1315 the headcat routine could insert a linebreak which the relaxer would reduce
1316 to a single space preceding the terminating semicolon, resulting in an
1317 incorrect header-hash. */
1318 hdr = pdkim_headcat(&col, hdr, US";", US"b=;", US"");
1321 return string_from_gstring(hdr);
1325 /* -------------------------------------------------------------------------- */
1327 /* According to draft-ietf-dcrup-dkim-crypto-07 "keys are 256 bits" (referring
1328 to DNS, hence the pubkey). Check for more than 32 bytes; if so assume the
1329 alternate possible representation (still) being discussed: a
1330 SubjectPublickeyInfo wrapped key - and drop all but the trailing 32-bytes (it
1331 should be a DER, with exactly 12 leading bytes - but we could accept a BER also,
1332 which could be any size). We still rely on the crypto library for checking for
1335 When the RFC is published this should be re-addressed. */
1338 check_bare_ed25519_pubkey(pdkim_pubkey * p)
1340 int excess = p->key.len - 32;
1344 debug_printf("DKIM: unexpected pubkey len %lu\n", (unsigned long) p->key.len);
1345 p->key.data += excess; p->key.len = 32;
1350 static pdkim_pubkey *
1351 pdkim_key_from_dns(pdkim_ctx * ctx, pdkim_signature * sig, ev_ctx * vctx,
1352 const uschar ** errstr)
1354 uschar * dns_txt_name, * dns_txt_reply;
1357 /* Fetch public key for signing domain, from DNS */
1359 dns_txt_name = string_sprintf("%s._domainkey.%s.", sig->selector, sig->domain);
1361 if ( !(dns_txt_reply = ctx->dns_txt_callback(dns_txt_name))
1362 || dns_txt_reply[0] == '\0'
1365 sig->verify_status = PDKIM_VERIFY_INVALID;
1366 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE;
1373 "DKIM >> Parsing public key record >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"
1377 pdkim_quoteprint(CUS dns_txt_reply, Ustrlen(dns_txt_reply));
1380 if ( !(p = pdkim_parse_pubkey_record(CUS dns_txt_reply))
1381 || (Ustrcmp(p->srvtype, "*") != 0 && Ustrcmp(p->srvtype, "email") != 0)
1384 sig->verify_status = PDKIM_VERIFY_INVALID;
1385 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD;
1390 debug_printf(" Invalid public key service type '%s'\n", p->srvtype);
1392 debug_printf(" Error while parsing public key record\n");
1394 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1399 DEBUG(D_acl) debug_printf(
1400 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1402 /* Import public key */
1404 /* Normally we use the signature a= tag to tell us the pubkey format.
1405 When signing under debug we do a test-import of the pubkey, and at that
1406 time we do not have a signature so we must interpret the pubkey k= tag
1407 instead. Assume writing on the sig is ok in that case. */
1409 if (sig->keytype < 0)
1410 if ((sig->keytype = pdkim_keyname_to_keytype(p->keytype)) < 0)
1412 DEBUG(D_acl) debug_printf("verify_init: unhandled keytype %s\n", p->keytype);
1413 sig->verify_status = PDKIM_VERIFY_INVALID;
1414 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
1418 if (sig->keytype == KEYTYPE_ED25519)
1419 check_bare_ed25519_pubkey(p);
1421 if ((*errstr = exim_dkim_verify_init(&p->key,
1422 sig->keytype == KEYTYPE_ED25519 ? KEYFMT_ED25519_BARE : KEYFMT_DER,
1423 vctx, &sig->keybits)))
1425 DEBUG(D_acl) debug_printf("verify_init: %s\n", *errstr);
1426 sig->verify_status = PDKIM_VERIFY_INVALID;
1427 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
1431 vctx->keytype = sig->keytype;
1436 /* -------------------------------------------------------------------------- */
1437 /* Sort and filter the sigs developed from the message */
1439 static pdkim_signature *
1440 sort_sig_methods(pdkim_signature * siglist)
1442 pdkim_signature * yield, ** ss;
1443 const uschar * prefs;
1447 if (!siglist) return NULL;
1449 /* first select in order of hashtypes */
1450 DEBUG(D_acl) debug_printf("DKIM: dkim_verify_hashes '%s'\n", dkim_verify_hashes);
1451 for (prefs = dkim_verify_hashes, sep = 0, yield = NULL, ss = &yield;
1452 ele = string_nextinlist(&prefs, &sep, NULL, 0); )
1454 int i = pdkim_hashname_to_hashtype(CUS ele, 0);
1455 for (pdkim_signature * s = siglist, * next, ** prev = &siglist; s;
1459 if (s->hashtype == i)
1460 { *prev = next; s->next = NULL; *ss = s; ss = &s->next; }
1466 /* then in order of keytypes */
1468 DEBUG(D_acl) debug_printf("DKIM: dkim_verify_keytypes '%s'\n", dkim_verify_keytypes);
1469 for (prefs = dkim_verify_keytypes, sep = 0, yield = NULL, ss = &yield;
1470 ele = string_nextinlist(&prefs, &sep, NULL, 0); )
1472 int i = pdkim_keyname_to_keytype(CUS ele);
1473 for (pdkim_signature * s = siglist, * next, ** prev = &siglist; s;
1477 if (s->keytype == i)
1478 { *prev = next; s->next = NULL; *ss = s; ss = &s->next; }
1484 DEBUG(D_acl) for (pdkim_signature * s = yield; s; s = s->next)
1485 debug_printf(" retain d=%s s=%s a=%s\n",
1486 s->domain, s->selector, dkim_sig_to_a_tag(s));
1491 /* -------------------------------------------------------------------------- */
1494 pdkim_feed_finish(pdkim_ctx * ctx, pdkim_signature ** return_signatures,
1495 const uschar ** err)
1497 BOOL verify_pass = FALSE;
1499 /* Check if we must still flush a (partial) header. If that is the
1500 case, the message has no body, and we must compute a body hash
1501 out of '<CR><LF>' */
1502 if (ctx->cur_header && ctx->cur_header->ptr > 0)
1507 if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1510 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
1511 rnl = pdkim_update_ctx_bodyhash(b, &lineending, rnl);
1512 if (rnl) store_free(rnl);
1515 DEBUG(D_acl) debug_printf(
1516 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1518 /* Build (and/or evaluate) body hash. Do this even if no DKIM sigs, in case we
1519 have a hash to do for ARC. */
1521 pdkim_finish_bodyhash(ctx);
1523 /* Sort and filter the recived signatures */
1525 if (!(ctx->flags & PDKIM_MODE_SIGN))
1526 ctx->sig = sort_sig_methods(ctx->sig);
1530 DEBUG(D_acl) debug_printf("DKIM: no signatures\n");
1531 *return_signatures = NULL;
1535 for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next)
1538 uschar * sig_hdr = US"";
1540 gstring * hdata = NULL;
1543 if ( !(ctx->flags & PDKIM_MODE_SIGN)
1544 && sig->verify_status == PDKIM_VERIFY_FAIL)
1547 debug_printf("DKIM: [%s] abandoning this signature\n", sig->domain);
1551 /*XXX The hash of the headers is needed for GCrypt (for which we can do RSA
1552 signing only, as it happens) and for either GnuTLS and OpenSSL when we are
1553 signing with EC (specifically, Ed25519). The former is because the GCrypt
1554 signing operation is pure (does not do its own hash) so we must hash. The
1555 latter is because we (stupidly, but this is what the IETF draft is saying)
1556 must hash with the declared hash method, then pass the result to the library
1557 hash-and-sign routine (because that's all the libraries are providing. And
1558 we're stuck with whatever that hidden hash method is, too). We may as well
1559 do this hash incrementally.
1560 We don't need the hash we're calculating here for the GnuTLS and OpenSSL
1561 cases of RSA signing, since those library routines can do hash-and-sign.
1563 Some time in the future we could easily avoid doing the hash here for those
1564 cases (which will be common for a long while. We could also change from
1565 the current copy-all-the-headers-into-one-block, then call the hash-and-sign
1566 implementation - to a proper incremental one. Unfortunately, GnuTLS just
1567 cannot do incremental - either signing or verification. Unsure about GCrypt.
1570 /*XXX The header hash is also used (so far) by the verify operation */
1572 if (!exim_sha_init(&hhash_ctx, pdkim_hashes[sig->hashtype].exim_hashmethod))
1574 log_write(0, LOG_MAIN|LOG_PANIC,
1575 "DKIM: hash setup error, possibly nonhandled hashtype");
1579 if (ctx->flags & PDKIM_MODE_SIGN)
1580 DEBUG(D_acl) debug_printf(
1581 "DKIM >> Headers to be signed: >>>>>>>>>>>>\n"
1585 DEBUG(D_acl) debug_printf(
1586 "DKIM >> Header data for hash, canonicalized (%-7s), in sequence >>\n",
1587 pdkim_canons[sig->canon_headers]);
1590 /* SIGNING ---------------------------------------------------------------- */
1591 /* When signing, walk through our header list and add them to the hash. As we
1592 go, construct a list of the header's names to use for the h= parameter.
1593 Then append to that list any remaining header names for which there was no
1596 if (ctx->flags & PDKIM_MODE_SIGN)
1603 /* Import private key, including the keytype which we need for building
1604 the signature header */
1606 if ((*err = exim_dkim_signing_init(CUS sig->privkey, &sctx)))
1608 log_write(0, LOG_MAIN|LOG_PANIC, "signing_init: %s", *err);
1609 return PDKIM_ERR_RSA_PRIVKEY;
1611 sig->keytype = sctx.keytype;
1613 sig->headernames = NULL; /* Collected signed header names */
1614 for (pdkim_stringlist * p = sig->headers; p; p = p->next)
1616 uschar * rh = p->value;
1618 if (header_name_match(rh, sig->sign_headers) == PDKIM_OK)
1620 /* Collect header names (Note: colon presence is guaranteed here) */
1621 g = string_append_listele_n(g, ':', rh, Ustrchr(rh, ':') - rh);
1623 if (sig->canon_headers == PDKIM_CANON_RELAXED)
1624 rh = pdkim_relax_header(rh, TRUE); /* cook header for relaxed canon */
1626 /* Feed header to the hash algorithm */
1627 exim_sha_update_string(&hhash_ctx, CUS rh);
1629 /* Remember headers block for signing (when the library cannot do incremental) */
1630 /*XXX we could avoid doing this for all but the GnuTLS/RSA case */
1631 hdata = exim_dkim_data_append(hdata, rh);
1633 DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1637 /* Any headers we wanted to sign but were not present must also be listed.
1638 Ignore elements that have been ticked-off or are marked as never-oversign. */
1640 l = sig->sign_headers;
1641 while((s = string_nextinlist(&l, &sep, NULL, 0)))
1643 if (*s == '+') /* skip oversigning marker */
1645 if (*s != '_' && *s != '=')
1646 g = string_append_listele(g, ':', s);
1648 sig->headernames = string_from_gstring(g);
1650 /* Create signature header with b= omitted */
1651 sig_hdr = pdkim_create_header(sig, FALSE);
1654 /* VERIFICATION ----------------------------------------------------------- */
1655 /* When verifying, walk through the header name list in the h= parameter and
1656 add the headers to the hash in that order. */
1659 uschar * p = sig->headernames;
1665 for (pdkim_stringlist * hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1671 if ((q = Ustrchr(p, ':')))
1674 /*XXX walk the list of headers in same order as received. */
1675 for (pdkim_stringlist * hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1677 && strncasecmp(CCS hdrs->value, CCS p, Ustrlen(p)) == 0
1678 && (hdrs->value)[Ustrlen(p)] == ':'
1681 /* cook header for relaxed canon, or just copy it for simple */
1683 uschar * rh = sig->canon_headers == PDKIM_CANON_RELAXED
1684 ? pdkim_relax_header(hdrs->value, TRUE)
1685 : string_copy(CUS hdrs->value);
1687 /* Feed header to the hash algorithm */
1688 exim_sha_update_string(&hhash_ctx, CUS rh);
1690 DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1699 sig_hdr = string_copy(sig->rawsig_no_b_val);
1703 DEBUG(D_acl) debug_printf(
1704 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1709 "DKIM >> Signed DKIM-Signature header, pre-canonicalized >>>>>>>>>>>>>\n");
1710 pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr));
1712 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1715 /* Relax header if necessary */
1716 if (sig->canon_headers == PDKIM_CANON_RELAXED)
1717 sig_hdr = pdkim_relax_header(sig_hdr, FALSE);
1721 debug_printf("DKIM >> Signed DKIM-Signature header, canonicalized (%-7s) >>>>>>>\n",
1722 pdkim_canons[sig->canon_headers]);
1723 pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr));
1725 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1728 /* Finalize header hash */
1729 exim_sha_update_string(&hhash_ctx, CUS sig_hdr);
1730 exim_sha_finish(&hhash_ctx, &hhash);
1734 debug_printf("DKIM [%s] Header %s computed: ",
1735 sig->domain, pdkim_hashes[sig->hashtype].dkim_hashname);
1736 pdkim_hexprint(hhash.data, hhash.len);
1739 /* Remember headers block for signing (when the signing library cannot do
1741 if (ctx->flags & PDKIM_MODE_SIGN)
1742 hdata = exim_dkim_data_append(hdata, US sig_hdr);
1744 /* SIGNING ---------------------------------------------------------------- */
1745 if (ctx->flags & PDKIM_MODE_SIGN)
1747 hashmethod hm = sig->keytype == KEYTYPE_ED25519
1748 #if defined(SIGN_OPENSSL)
1753 : pdkim_hashes[sig->hashtype].exim_hashmethod;
1755 #ifdef SIGN_HAVE_ED25519
1756 /* For GCrypt, and for EC, we pass the hash-of-headers to the signing
1757 routine. For anything else we just pass the headers. */
1759 if (sig->keytype != KEYTYPE_ED25519)
1762 hhash.data = hdata->s;
1763 hhash.len = hdata->ptr;
1766 if ((*err = exim_dkim_sign(&sctx, hm, &hhash, &sig->sighash)))
1768 log_write(0, LOG_MAIN|LOG_PANIC, "signing: %s", *err);
1769 return PDKIM_ERR_RSA_SIGNING;
1774 debug_printf( "DKIM [%s] b computed: ", sig->domain);
1775 pdkim_hexprint(sig->sighash.data, sig->sighash.len);
1778 sig->signature_header = pdkim_create_header(sig, TRUE);
1781 /* VERIFICATION ----------------------------------------------------------- */
1787 /* Make sure we have all required signature tags */
1788 if (!( sig->domain && *sig->domain
1789 && sig->selector && *sig->selector
1790 && sig->headernames && *sig->headernames
1791 && sig->bodyhash.data
1792 && sig->sighash.data
1793 && sig->keytype >= 0
1794 && sig->hashtype >= 0
1798 sig->verify_status = PDKIM_VERIFY_INVALID;
1799 sig->verify_ext_status = PDKIM_VERIFY_INVALID_SIGNATURE_ERROR;
1801 DEBUG(D_acl) debug_printf(
1802 " Error in DKIM-Signature header: tags missing or invalid (%s)\n"
1803 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
1804 !(sig->domain && *sig->domain) ? "d="
1805 : !(sig->selector && *sig->selector) ? "s="
1806 : !(sig->headernames && *sig->headernames) ? "h="
1807 : !sig->bodyhash.data ? "bh="
1808 : !sig->sighash.data ? "b="
1809 : sig->keytype < 0 || sig->hashtype < 0 ? "a="
1815 /* Make sure sig uses supported DKIM version (only v1) */
1816 if (sig->version != 1)
1818 sig->verify_status = PDKIM_VERIFY_INVALID;
1819 sig->verify_ext_status = PDKIM_VERIFY_INVALID_DKIM_VERSION;
1821 DEBUG(D_acl) debug_printf(
1822 " Error in DKIM-Signature header: unsupported DKIM version\n"
1823 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1829 debug_printf( "DKIM [%s] b from mail: ", sig->domain);
1830 pdkim_hexprint(sig->sighash.data, sig->sighash.len);
1833 if (!(sig->pubkey = pdkim_key_from_dns(ctx, sig, &vctx, err)))
1835 log_write(0, LOG_MAIN, "DKIM: %s%s %s%s [failed key import]",
1836 sig->domain ? "d=" : "", sig->domain ? sig->domain : US"",
1837 sig->selector ? "s=" : "", sig->selector ? sig->selector : US"");
1841 /* If the pubkey limits to a list of specific hashes, ignore sigs that
1842 do not have the hash part of the sig algorithm matching */
1844 if (sig->pubkey->hashes)
1846 const uschar * list = sig->pubkey->hashes, * ele;
1848 while ((ele = string_nextinlist(&list, &sep, NULL, 0)))
1849 if (Ustrcmp(ele, pdkim_hashes[sig->hashtype].dkim_hashname) == 0) break;
1852 DEBUG(D_acl) debug_printf("pubkey h=%s vs. sig a=%s_%s\n",
1853 sig->pubkey->hashes,
1854 pdkim_keytypes[sig->keytype],
1855 pdkim_hashes[sig->hashtype].dkim_hashname);
1856 sig->verify_status = PDKIM_VERIFY_FAIL;
1857 sig->verify_ext_status = PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH;
1862 hm = sig->keytype == KEYTYPE_ED25519
1863 #if defined(SIGN_OPENSSL)
1868 : pdkim_hashes[sig->hashtype].exim_hashmethod;
1870 /* Check the signature */
1872 if ((*err = exim_dkim_verify(&vctx, hm, &hhash, &sig->sighash)))
1874 DEBUG(D_acl) debug_printf("headers verify: %s\n", *err);
1875 sig->verify_status = PDKIM_VERIFY_FAIL;
1876 sig->verify_ext_status = PDKIM_VERIFY_FAIL_MESSAGE;
1879 if (*dkim_verify_min_keysizes)
1882 const uschar * ss = expand_getkeyed(US pdkim_keytypes[sig->keytype],
1883 dkim_verify_min_keysizes);
1884 if (ss && (minbits = atoi(CCS ss)) > sig->keybits)
1886 DEBUG(D_acl) debug_printf("Key too short: Actual: %s %u Minima '%s'\n",
1887 pdkim_keytypes[sig->keytype], sig->keybits, dkim_verify_min_keysizes);
1888 sig->verify_status = PDKIM_VERIFY_FAIL;
1889 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_KEYSIZE;
1894 /* We have a winner! (if bodyhash was correct earlier) */
1895 if (sig->verify_status == PDKIM_VERIFY_NONE)
1897 sig->verify_status = PDKIM_VERIFY_PASS;
1899 /*XXX We used to "break" here if dkim_verify_minimal, but that didn't
1900 stop the ACL being called. So move that test. Unfortunately, we
1901 need to eval all the sigs here only to possibly ignore some later,
1902 because we don't know what verify options might say.
1903 Could we change to a later eval of the sig?
1904 Both bits are called from receive_msg().
1905 Moving the test is also suboptimal for the case of no ACL (or no
1906 signers to check!) so keep it for that case, but after debug output */
1912 debug_printf("DKIM [%s] %s signature status: %s",
1913 sig->domain, dkim_sig_to_a_tag(sig),
1914 pdkim_verify_status_str(sig->verify_status));
1915 if (sig->verify_ext_status > 0)
1916 debug_printf(" (%s)\n",
1917 pdkim_verify_ext_status_str(sig->verify_ext_status));
1922 if ( verify_pass && dkim_verify_minimal
1923 && !(acl_smtp_dkim && dkim_verify_signers && *dkim_verify_signers))
1928 /* If requested, set return pointer to signature(s) */
1929 if (return_signatures)
1930 *return_signatures = ctx->sig;
1932 return ctx->flags & PDKIM_MODE_SIGN || verify_pass
1933 ? PDKIM_OK : PDKIM_FAIL;
1937 /* -------------------------------------------------------------------------- */
1939 DLLEXPORT pdkim_ctx *
1940 pdkim_init_verify(uschar * (*dns_txt_callback)(const uschar *), BOOL dot_stuffing)
1944 ctx = store_get(sizeof(pdkim_ctx), GET_UNTAINTED);
1945 memset(ctx, 0, sizeof(pdkim_ctx));
1947 if (dot_stuffing) ctx->flags = PDKIM_DOT_TERM;
1948 /* The line-buffer is for message data, hence tainted */
1949 ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN, GET_TAINTED);
1950 ctx->dns_txt_callback = dns_txt_callback;
1951 ctx->cur_header = string_get_tainted(36, GET_TAINTED);
1957 /* -------------------------------------------------------------------------- */
1959 DLLEXPORT pdkim_signature *
1960 pdkim_init_sign(pdkim_ctx * ctx,
1961 uschar * domain, uschar * selector, uschar * privkey,
1962 uschar * hashname, const uschar ** errstr)
1965 pdkim_signature * sig;
1967 if (!domain || !selector || !privkey)
1970 /* Allocate & init one signature struct */
1972 sig = store_get(sizeof(pdkim_signature), GET_UNTAINTED);
1973 memset(sig, 0, sizeof(pdkim_signature));
1975 sig->bodylength = -1;
1977 sig->domain = string_copy(US domain);
1978 sig->selector = string_copy(US selector);
1979 sig->privkey = string_copy(US privkey);
1982 for (hashtype = 0; hashtype < nelem(pdkim_hashes); hashtype++)
1983 if (Ustrcmp(hashname, pdkim_hashes[hashtype].dkim_hashname) == 0)
1984 { sig->hashtype = hashtype; break; }
1985 if (hashtype >= nelem(pdkim_hashes))
1987 log_write(0, LOG_MAIN|LOG_PANIC,
1988 "DKIM: unrecognised hashname '%s'", hashname);
1994 pdkim_signature s = *sig;
1997 debug_printf("DKIM (checking verify key)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1998 if (!pdkim_key_from_dns(ctx, &s, &vctx, errstr))
1999 debug_printf("WARNING: bad dkim key in dns\n");
2000 debug_printf("DKIM (finished checking verify key)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
2006 /* -------------------------------------------------------------------------- */
2009 pdkim_set_optional(pdkim_signature * sig,
2010 char * sign_headers,
2015 unsigned long created,
2016 unsigned long expires)
2019 sig->identity = string_copy(US identity);
2021 sig->sign_headers = string_copy(sign_headers
2022 ? US sign_headers : US PDKIM_DEFAULT_SIGN_HEADERS);
2024 sig->canon_headers = canon_headers;
2025 sig->canon_body = canon_body;
2026 sig->bodylength = bodylength;
2027 sig->created = created;
2028 sig->expires = expires;
2035 /* Set up a blob for calculating the bodyhash according to the
2036 given needs. Use an existing one if possible, or create a new one.
2038 Return: hashblob pointer, or NULL on error
2041 pdkim_set_bodyhash(pdkim_ctx * ctx, int hashtype, int canon_method,
2046 if (hashtype == -1 || canon_method == -1) return NULL;
2048 for (b = ctx->bodyhash; b; b = b->next)
2049 if ( hashtype == b->hashtype
2050 && canon_method == b->canon_method
2051 && bodylength == b->bodylength)
2053 DEBUG(D_receive) debug_printf("DKIM: using existing bodyhash %s/%s/%ld\n",
2054 pdkim_hashes[hashtype].dkim_hashname, pdkim_canons[canon_method], bodylength);
2058 DEBUG(D_receive) debug_printf("DKIM: new bodyhash %s/%s/%ld\n",
2059 pdkim_hashes[hashtype].dkim_hashname, pdkim_canons[canon_method], bodylength);
2060 b = store_get(sizeof(pdkim_bodyhash), GET_UNTAINTED);
2061 b->next = ctx->bodyhash;
2062 b->hashtype = hashtype;
2063 b->canon_method = canon_method;
2064 b->bodylength = bodylength;
2065 if (!exim_sha_init(&b->body_hash_ctx, /*XXX hash method: extend for sha512 */
2066 pdkim_hashes[hashtype].exim_hashmethod))
2069 debug_printf("DKIM: hash init error, possibly nonhandled hashtype\n");
2072 b->signed_body_bytes = 0;
2073 b->num_buffered_blanklines = 0;
2079 /* Set up a blob for calculating the bodyhash according to the
2080 needs of this signature. Use an existing one if possible, or
2083 Return: hashblob pointer, or NULL on error (only used as a boolean).
2086 pdkim_set_sig_bodyhash(pdkim_ctx * ctx, pdkim_signature * sig)
2088 pdkim_bodyhash * b = pdkim_set_bodyhash(ctx,
2089 sig->hashtype, sig->canon_body, sig->bodylength);
2090 sig->calc_body_hash = b;
2095 /* -------------------------------------------------------------------------- */
2099 pdkim_init_context(pdkim_ctx * ctx, BOOL dot_stuffed,
2100 uschar * (*dns_txt_callback)(const uschar *))
2102 memset(ctx, 0, sizeof(pdkim_ctx));
2103 ctx->flags = dot_stuffed ? PDKIM_MODE_SIGN | PDKIM_DOT_TERM : PDKIM_MODE_SIGN;
2104 /* The line buffer is for message data, hence tainted */
2105 ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN, GET_TAINTED);
2106 DEBUG(D_acl) ctx->dns_txt_callback = dns_txt_callback;
2118 #endif /*DISABLE_DKIM*/