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 */
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_SIGN_PRIVKEY_WRAP: return US"PRIVKEY_WRAP";
196 case PDKIM_SIGN_PRIVKEY_B64D: return US"PRIVKEY_B64D";
197 default: return US"(unknown)";
202 /* -------------------------------------------------------------------------- */
203 /* Print debugging functions */
205 pdkim_quoteprint(const uschar *data, int len)
208 for (i = 0; i < len; i++)
210 const int c = data[i];
213 case ' ' : debug_printf("{SP}"); break;
214 case '\t': debug_printf("{TB}"); break;
215 case '\r': debug_printf("{CR}"); break;
216 case '\n': debug_printf("{LF}"); break;
217 case '{' : debug_printf("{BO}"); break;
218 case '}' : debug_printf("{BC}"); break;
220 if ( (c < 32) || (c > 127) )
221 debug_printf("{%02x}", c);
223 debug_printf("%c", c);
231 pdkim_hexprint(const uschar *data, int len)
234 if (data) for (i = 0 ; i < len; i++) debug_printf("%02x", data[i]);
235 else debug_printf("<NULL>");
241 static pdkim_stringlist *
242 pdkim_prepend_stringlist(pdkim_stringlist * base, const uschar * str)
244 pdkim_stringlist * new_entry = store_get(sizeof(pdkim_stringlist));
246 memset(new_entry, 0, sizeof(pdkim_stringlist));
247 new_entry->value = string_copy(str);
248 if (base) new_entry->next = base;
254 /* Trim whitespace fore & aft */
257 pdkim_strtrim(gstring * str)
262 while (*p == '\t' || *p == ' ') /* dump the leading whitespace */
263 { str->size--; str->ptr--; str->s++; }
266 && ((q = str->s + str->ptr - 1), (*q == '\t' || *q == ' '))
268 str->ptr--; /* dump trailing whitespace */
270 (void) string_from_gstring(str);
275 /* -------------------------------------------------------------------------- */
278 pdkim_free_ctx(pdkim_ctx *ctx)
283 /* -------------------------------------------------------------------------- */
284 /* Matches the name of the passed raw "header" against
285 the passed colon-separated "tick", and invalidates
286 the entry in tick. Entries can be prefixed for multi- or over-signing,
287 in which case do not invalidate.
289 Returns OK for a match, or fail-code
293 header_name_match(const uschar * header, uschar * tick)
295 const uschar * ticklist = tick;
298 uschar * hname, * p, * ele;
299 uschar * hcolon = Ustrchr(header, ':'); /* Get header name */
302 return PDKIM_FAIL; /* This isn't a header */
304 /* if we had strncmpic() we wouldn't need this copy */
305 hname = string_copyn(header, hcolon-header);
307 while (p = US ticklist, ele = string_nextinlist(&ticklist, &sep, NULL, 0))
311 case '=': case '+': multisign = TRUE; ele++; break;
312 default: multisign = FALSE; break;
315 if (strcmpic(ele, hname) == 0)
318 *p = '_'; /* Invalidate this header name instance in tick-off list */
326 /* -------------------------------------------------------------------------- */
327 /* Performs "relaxed" canonicalization of a header. */
330 pdkim_relax_header_n(const uschar * header, int len, BOOL append_crlf)
332 BOOL past_field_name = FALSE;
333 BOOL seen_wsp = FALSE;
335 uschar * relaxed = store_get(len+3);
336 uschar * q = relaxed;
338 for (p = header; p - header < len; p++)
342 if (c == '\r' || c == '\n') /* Ignore CR & LF */
344 if (c == '\t' || c == ' ')
348 c = ' '; /* Turns WSP into SP */
352 if (!past_field_name && c == ':')
354 if (seen_wsp) q--; /* This removes WSP immediately before the colon */
355 seen_wsp = TRUE; /* This removes WSP immediately after the colon */
356 past_field_name = TRUE;
361 /* Lowercase header name */
362 if (!past_field_name) c = tolower(c);
366 if (q > relaxed && q[-1] == ' ') q--; /* Squash eventual trailing SP */
368 if (append_crlf) { *q++ = '\r'; *q++ = '\n'; }
375 pdkim_relax_header(const uschar * header, BOOL append_crlf)
377 return pdkim_relax_header_n(header, Ustrlen(header), append_crlf);
381 /* -------------------------------------------------------------------------- */
382 #define PDKIM_QP_ERROR_DECODE -1
384 static const uschar *
385 pdkim_decode_qp_char(const uschar *qp_p, int *c)
387 const uschar *initial_pos = qp_p;
389 /* Advance one char */
392 /* Check for two hex digits and decode them */
393 if (isxdigit(*qp_p) && isxdigit(qp_p[1]))
395 /* Do hex conversion */
396 *c = (isdigit(*qp_p) ? *qp_p - '0' : toupper(*qp_p) - 'A' + 10) << 4;
397 *c |= isdigit(qp_p[1]) ? qp_p[1] - '0' : toupper(qp_p[1]) - 'A' + 10;
401 /* Illegal char here */
402 *c = PDKIM_QP_ERROR_DECODE;
407 /* -------------------------------------------------------------------------- */
410 pdkim_decode_qp(const uschar * str)
414 const uschar * p = str;
415 uschar * n = store_get(Ustrlen(str)+1);
423 p = pdkim_decode_qp_char(p, &nchar);
439 /* -------------------------------------------------------------------------- */
442 pdkim_decode_base64(const uschar * str, blob * b)
444 int dlen = b64decode(str, &b->data);
445 if (dlen < 0) b->data = NULL;
450 pdkim_encode_base64(blob * b)
452 return b64encode(b->data, b->len);
456 /* -------------------------------------------------------------------------- */
457 #define PDKIM_HDR_LIMBO 0
458 #define PDKIM_HDR_TAG 1
459 #define PDKIM_HDR_VALUE 2
461 static pdkim_signature *
462 pdkim_parse_sig_header(pdkim_ctx * ctx, uschar * raw_hdr)
464 pdkim_signature * sig;
466 gstring * cur_tag = NULL;
467 gstring * cur_val = NULL;
468 BOOL past_hname = FALSE;
469 BOOL in_b_val = FALSE;
470 int where = PDKIM_HDR_LIMBO;
473 sig = store_get(sizeof(pdkim_signature));
474 memset(sig, 0, sizeof(pdkim_signature));
475 sig->bodylength = -1;
477 /* Set so invalid/missing data error display is accurate */
482 q = sig->rawsig_no_b_val = store_get(Ustrlen(raw_hdr)+1);
484 for (p = raw_hdr; ; p++)
489 if (c == '\r' || c == '\n')
492 /* Fast-forward through header name */
495 if (c == ':') past_hname = TRUE;
499 if (where == PDKIM_HDR_LIMBO)
501 /* In limbo, just wait for a tag-char to appear */
502 if (!(c >= 'a' && c <= 'z'))
505 where = PDKIM_HDR_TAG;
508 if (where == PDKIM_HDR_TAG)
510 if (c >= 'a' && c <= 'z')
511 cur_tag = string_catn(cur_tag, p, 1);
515 if (Ustrcmp(string_from_gstring(cur_tag), "b") == 0)
520 where = PDKIM_HDR_VALUE;
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)
551 pdkim_decode_base64(cur_val->s, &sig->bodyhash);
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 for(i = 0; i < nelem(pdkim_keytypes); i++)
570 if (Ustrcmp(elem, pdkim_keytypes[i]) == 0)
571 { sig->keytype = i; break; }
572 if ((elem = string_nextinlist(&list, &sep, NULL, 0)))
573 for (i = 0; i < nelem(pdkim_hashes); i++)
574 if (Ustrcmp(elem, pdkim_hashes[i].dkim_hashname) == 0)
575 { sig->hashtype = i; break; }
578 case 'c': /* canonicalization */
579 pdkim_cstring_to_canons(cur_val->s, 0,
580 &sig->canon_headers, &sig->canon_body);
582 case 'q': /* Query method (for pubkey)*/
583 for (i = 0; pdkim_querymethods[i]; i++)
584 if (Ustrcmp(cur_val->s, pdkim_querymethods[i]) == 0)
586 sig->querymethod = i; /* we never actually use this */
590 case 's': /* Selector */
591 sig->selector = string_copyn(cur_val->s, cur_val->ptr); break;
593 sig->domain = string_copyn(cur_val->s, cur_val->ptr); break;
595 sig->identity = pdkim_decode_qp(cur_val->s); break;
596 case 't': /* Timestamp */
597 sig->created = strtoul(CS cur_val->s, NULL, 10); break;
598 case 'x': /* Expiration */
599 sig->expires = strtoul(CS cur_val->s, NULL, 10); break;
600 case 'l': /* Body length count */
601 sig->bodylength = strtol(CS cur_val->s, NULL, 10); break;
602 case 'h': /* signed header fields */
603 sig->headernames = string_copyn(cur_val->s, cur_val->ptr); break;
604 case 'z': /* Copied headfields */
605 sig->copiedheaders = pdkim_decode_qp(cur_val->s); break;
606 /*XXX draft-ietf-dcrup-dkim-crypto-05 would need 'p' tag support
607 for rsafp signatures. But later discussion is dropping those. */
609 DEBUG(D_acl) debug_printf(" Unknown tag encountered\n");
613 cur_tag = cur_val = NULL;
615 where = PDKIM_HDR_LIMBO;
618 cur_val = string_catn(cur_val, p, 1);
629 if (sig->keytype < 0 || sig->hashtype < 0) /* Cannot verify this signature */
633 /* Chomp raw header. The final newline must not be added to the signature. */
634 while (--q > sig->rawsig_no_b_val && (*q == '\r' || *q == '\n'))
640 "PDKIM >> Raw signature w/o b= tag value >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
641 pdkim_quoteprint(US sig->rawsig_no_b_val, Ustrlen(sig->rawsig_no_b_val));
643 "PDKIM >> Sig size: %4u bits\n", (unsigned) sig->sighash.len*8);
645 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
648 if (!pdkim_set_sig_bodyhash(ctx, sig))
655 /* -------------------------------------------------------------------------- */
658 pdkim_parse_pubkey_record(const uschar *raw_record)
664 pub = store_get(sizeof(pdkim_pubkey));
665 memset(pub, 0, sizeof(pdkim_pubkey));
667 while ((ele = string_nextinlist(&raw_record, &sep, NULL, 0)))
671 if ((val = Ustrchr(ele, '=')))
673 int taglen = val++ - ele;
675 DEBUG(D_acl) debug_printf(" %.*s=%s\n", taglen, ele, val);
678 case 'v': pub->version = val; break;
679 case 'h': pub->hashes = val; break;
680 case 'k': pub->keytype = val; break;
681 case 'g': pub->granularity = val; break;
682 case 'n': pub->notes = pdkim_decode_qp(val); break;
683 case 'p': pdkim_decode_base64(val, &pub->key); break;
684 case 's': pub->srvtype = val; break;
685 case 't': if (Ustrchr(val, 'y')) pub->testing = 1;
686 if (Ustrchr(val, 's')) pub->no_subdomaining = 1;
688 default: DEBUG(D_acl) debug_printf(" Unknown tag encountered\n"); break;
693 /* Set fallback defaults */
695 pub->version = string_copy(PDKIM_PUB_RECORD_VERSION);
696 else if (Ustrcmp(pub->version, PDKIM_PUB_RECORD_VERSION) != 0)
698 DEBUG(D_acl) debug_printf(" Bad v= field\n");
702 if (!pub->granularity) pub->granularity = US"*";
703 if (!pub->keytype ) pub->keytype = US"rsa";
704 if (!pub->srvtype ) pub->srvtype = US"*";
710 DEBUG(D_acl) debug_printf(" Missing p= field\n");
715 /* -------------------------------------------------------------------------- */
717 /* Update one bodyhash with some additional data.
718 If we have to relax the data for this sig, return our copy of it. */
721 pdkim_update_ctx_bodyhash(pdkim_bodyhash * b, blob * orig_data, blob * relaxed_data)
723 blob * canon_data = orig_data;
724 /* Defaults to simple canon (no further treatment necessary) */
726 if (b->canon_method == PDKIM_CANON_RELAXED)
728 /* Relax the line if not done already */
731 BOOL seen_wsp = FALSE;
732 const uschar * p, * r;
735 /* We want to be able to free this else we allocate
736 for the entire message which could be many MB. Since
737 we don't know what allocations the SHA routines might
738 do, not safe to use store_get()/store_reset(). */
740 relaxed_data = store_malloc(sizeof(blob) + orig_data->len+1);
741 relaxed_data->data = US (relaxed_data+1);
743 for (p = orig_data->data, r = p + orig_data->len; p < r; p++)
748 if (q > 0 && relaxed_data->data[q-1] == ' ')
751 else if (c == '\t' || c == ' ')
753 c = ' '; /* Turns WSP into SP */
760 relaxed_data->data[q++] = c;
762 relaxed_data->data[q] = '\0';
763 relaxed_data->len = q;
765 canon_data = relaxed_data;
768 /* Make sure we don't exceed the to-be-signed body length */
769 if ( b->bodylength >= 0
770 && b->signed_body_bytes + (unsigned long)canon_data->len > b->bodylength
772 canon_data->len = b->bodylength - b->signed_body_bytes;
774 if (canon_data->len > 0)
776 exim_sha_update(&b->body_hash_ctx, CUS canon_data->data, canon_data->len);
777 b->signed_body_bytes += canon_data->len;
778 DEBUG(D_acl) pdkim_quoteprint(canon_data->data, canon_data->len);
785 /* -------------------------------------------------------------------------- */
788 pdkim_finish_bodyhash(pdkim_ctx * ctx)
791 pdkim_signature * sig;
793 for (b = ctx->bodyhash; b; b = b->next) /* Finish hashes */
795 DEBUG(D_acl) debug_printf("PDKIM: finish bodyhash %d/%d/%ld len %ld\n",
796 b->hashtype, b->canon_method, b->bodylength, b->signed_body_bytes);
797 exim_sha_finish(&b->body_hash_ctx, &b->bh);
800 /* Traverse all signatures */
801 for (sig = ctx->sig; sig; sig = sig->next)
803 b = sig->calc_body_hash;
807 debug_printf("PDKIM [%s] Body bytes (%s) hashed: %lu\n"
808 "PDKIM [%s] Body %s computed: ",
809 sig->domain, pdkim_canons[b->canon_method], b->signed_body_bytes,
810 sig->domain, pdkim_hashes[b->hashtype].dkim_hashname);
811 pdkim_hexprint(CUS b->bh.data, b->bh.len);
814 /* SIGNING -------------------------------------------------------------- */
815 if (ctx->flags & PDKIM_MODE_SIGN)
817 /* If bodylength limit is set, and we have received less bytes
818 than the requested amount, effectively remove the limit tag. */
819 if (b->signed_body_bytes < sig->bodylength)
820 sig->bodylength = -1;
824 /* VERIFICATION --------------------------------------------------------- */
825 /* Be careful that the header sig included a bodyash */
827 if ( sig->bodyhash.data
828 && memcmp(b->bh.data, sig->bodyhash.data, b->bh.len) == 0)
830 DEBUG(D_acl) debug_printf("PDKIM [%s] Body hash compared OK\n", sig->domain);
836 debug_printf("PDKIM [%s] Body hash signature from headers: ", sig->domain);
837 pdkim_hexprint(sig->bodyhash.data, sig->bodyhash.len);
838 debug_printf("PDKIM [%s] Body hash did NOT verify\n", sig->domain);
840 sig->verify_status = PDKIM_VERIFY_FAIL;
841 sig->verify_ext_status = PDKIM_VERIFY_FAIL_BODY;
849 pdkim_body_complete(pdkim_ctx * ctx)
853 /* In simple body mode, if any empty lines were buffered,
854 replace with one. rfc 4871 3.4.3 */
855 /*XXX checking the signed-body-bytes is a gross hack; I think
856 it indicates that all linebreaks should be buffered, including
857 the one terminating a text line */
859 for (b = ctx->bodyhash; b; b = b->next)
860 if ( b->canon_method == PDKIM_CANON_SIMPLE
861 && b->signed_body_bytes == 0
862 && b->num_buffered_blanklines > 0
864 (void) pdkim_update_ctx_bodyhash(b, &lineending, NULL);
866 ctx->flags |= PDKIM_SEEN_EOD;
867 ctx->linebuf_offset = 0;
872 /* -------------------------------------------------------------------------- */
873 /* Call from pdkim_feed below for processing complete body lines */
874 /* NOTE: the line is not NUL-terminated; but we have a count */
877 pdkim_bodyline_complete(pdkim_ctx * ctx)
879 blob line = {.data = ctx->linebuf, .len = ctx->linebuf_offset};
884 /* Ignore extra data if we've seen the end-of-data marker */
885 if (ctx->flags & PDKIM_SEEN_EOD) goto all_skip;
887 /* We've always got one extra byte to stuff a zero ... */
888 ctx->linebuf[line.len] = '\0';
890 /* Terminate on EOD marker */
891 if (ctx->flags & PDKIM_DOT_TERM)
893 if (memcmp(line.data, ".\r\n", 3) == 0)
894 { pdkim_body_complete(ctx); return; }
897 if (memcmp(line.data, "..", 2) == 0)
898 { line.data++; line.len--; }
901 /* Empty lines need to be buffered until we find a non-empty line */
902 if (memcmp(line.data, "\r\n", 2) == 0)
904 for (b = ctx->bodyhash; b; b = b->next) b->num_buffered_blanklines++;
908 /* Process line for each bodyhash separately */
909 for (b = ctx->bodyhash; b; b = b->next)
911 if (b->canon_method == PDKIM_CANON_RELAXED)
913 /* Lines with just spaces need to be buffered too */
914 uschar * cp = line.data;
919 if (c == '\r' && cp[1] == '\n') break;
920 if (c != ' ' && c != '\t') goto hash_process;
924 b->num_buffered_blanklines++;
929 /* At this point, we have a non-empty line, so release the buffered ones. */
931 while (b->num_buffered_blanklines)
933 rnl = pdkim_update_ctx_bodyhash(b, &lineending, rnl);
934 b->num_buffered_blanklines--;
937 rline = pdkim_update_ctx_bodyhash(b, &line, rline);
941 if (rnl) store_free(rnl);
942 if (rline) store_free(rline);
946 ctx->linebuf_offset = 0;
951 /* -------------------------------------------------------------------------- */
952 /* Callback from pdkim_feed below for processing complete headers */
953 #define DKIM_SIGNATURE_HEADERNAME "DKIM-Signature:"
956 pdkim_header_complete(pdkim_ctx * ctx)
958 pdkim_signature * sig, * last_sig;
960 /* Special case: The last header can have an extra \r appended */
961 if ( (ctx->cur_header->ptr > 1) &&
962 (ctx->cur_header->s[ctx->cur_header->ptr-1] == '\r') )
963 --ctx->cur_header->ptr;
964 (void) string_from_gstring(ctx->cur_header);
966 #ifdef EXPERIMENTAL_ARC
967 /* Feed the header line to ARC processing */
968 (void) arc_header_feed(ctx->cur_header, !(ctx->flags & PDKIM_MODE_SIGN));
971 if (++ctx->num_headers > PDKIM_MAX_HEADERS) goto BAIL;
973 /* SIGNING -------------------------------------------------------------- */
974 if (ctx->flags & PDKIM_MODE_SIGN)
975 for (sig = ctx->sig; sig; sig = sig->next) /* Traverse all signatures */
977 /* Add header to the signed headers list (in reverse order) */
978 sig->headers = pdkim_prepend_stringlist(sig->headers, ctx->cur_header->s);
980 /* VERIFICATION ----------------------------------------------------------- */
981 /* DKIM-Signature: headers are added to the verification list */
987 debug_printf("PDKIM >> raw hdr: ");
988 pdkim_quoteprint(CUS ctx->cur_header->s, ctx->cur_header->ptr);
991 if (strncasecmp(CCS ctx->cur_header->s,
992 DKIM_SIGNATURE_HEADERNAME,
993 Ustrlen(DKIM_SIGNATURE_HEADERNAME)) == 0)
995 /* Create and chain new signature block. We could error-check for all
996 required tags here, but prefer to create the internal sig and expicitly
997 fail verification of it later. */
999 DEBUG(D_acl) debug_printf(
1000 "PDKIM >> Found sig, trying to parse >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1002 sig = pdkim_parse_sig_header(ctx, ctx->cur_header->s);
1004 if (!(last_sig = ctx->sig))
1008 while (last_sig->next) last_sig = last_sig->next;
1009 last_sig->next = sig;
1013 /* all headers are stored for signature verification */
1014 ctx->headers = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->s);
1018 ctx->cur_header->s[ctx->cur_header->ptr = 0] = '\0'; /* leave buffer for reuse */
1024 /* -------------------------------------------------------------------------- */
1025 #define HEADER_BUFFER_FRAG_SIZE 256
1028 pdkim_feed(pdkim_ctx * ctx, uschar * data, int len)
1032 /* Alternate EOD signal, used in non-dotstuffing mode */
1034 pdkim_body_complete(ctx);
1036 else for (p = 0; p<len; p++)
1040 if (ctx->flags & PDKIM_PAST_HDRS)
1042 if (c == '\n' && !(ctx->flags & PDKIM_SEEN_CR)) /* emulate the CR */
1044 ctx->linebuf[ctx->linebuf_offset++] = '\r';
1045 if (ctx->linebuf_offset == PDKIM_MAX_BODY_LINE_LEN-1)
1046 return PDKIM_ERR_LONG_LINE;
1049 /* Processing body byte */
1050 ctx->linebuf[ctx->linebuf_offset++] = c;
1052 ctx->flags |= PDKIM_SEEN_CR;
1055 ctx->flags &= ~PDKIM_SEEN_CR;
1056 pdkim_bodyline_complete(ctx);
1059 if (ctx->linebuf_offset == PDKIM_MAX_BODY_LINE_LEN-1)
1060 return PDKIM_ERR_LONG_LINE;
1064 /* Processing header byte */
1066 ctx->flags |= PDKIM_SEEN_CR;
1069 if (!(ctx->flags & PDKIM_SEEN_CR)) /* emulate the CR */
1070 ctx->cur_header = string_catn(ctx->cur_header, CUS "\r", 1);
1072 if (ctx->flags & PDKIM_SEEN_LF) /* Seen last header line */
1074 if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1077 ctx->flags = (ctx->flags & ~(PDKIM_SEEN_LF|PDKIM_SEEN_CR)) | PDKIM_PAST_HDRS;
1078 DEBUG(D_acl) debug_printf(
1079 "PDKIM >> Body data for hash, canonicalized >>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1083 ctx->flags = (ctx->flags & ~PDKIM_SEEN_CR) | PDKIM_SEEN_LF;
1085 else if (ctx->flags & PDKIM_SEEN_LF)
1087 if (!(c == '\t' || c == ' ')) /* End of header */
1088 if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1090 ctx->flags &= ~PDKIM_SEEN_LF;
1093 if (!ctx->cur_header || ctx->cur_header->ptr < PDKIM_MAX_HEADER_LEN)
1094 ctx->cur_header = string_catn(ctx->cur_header, CUS &data[p], 1);
1102 /* Extend a growing header with a continuation-linebreak */
1104 pdkim_hdr_cont(gstring * str, int * col)
1107 return string_catn(str, US"\r\n\t", 3);
1113 * RFC 5322 specifies that header line length SHOULD be no more than 78
1117 * returns uschar * (not nul-terminated)
1119 * col: this int holds and receives column number (octets since last '\n')
1120 * str: partial string to append to
1121 * pad: padding, split line or space after before or after eg: ";"
1122 * intro: - must join to payload eg "h=", usually the tag name
1123 * payload: eg base64 data - long data can be split arbitrarily.
1125 * this code doesn't fold the header in some of the places that RFC4871
1126 * allows: As per RFC5322(2.2.3) it only folds before or after tag-value
1127 * pairs and inside long values. it also always spaces or breaks after the
1130 * no guarantees are made for output given out-of range input. like tag
1131 * names longer than 78, or bogus col. Input is assumed to be free of line breaks.
1135 pdkim_headcat(int * col, gstring * str,
1136 const uschar * pad, const uschar * intro, const uschar * payload)
1144 str = pdkim_hdr_cont(str, col);
1145 str = string_catn(str, pad, l);
1149 l = (pad?1:0) + (intro?Ustrlen(intro):0);
1152 { /*can't fit intro - start a new line to make room.*/
1153 str = pdkim_hdr_cont(str, col);
1154 l = intro?Ustrlen(intro):0;
1157 l += payload ? Ustrlen(payload):0 ;
1160 { /* this fragment will not fit on a single line */
1163 str = string_catn(str, US" ", 1);
1165 pad = NULL; /* only want this once */
1171 size_t sl = Ustrlen(intro);
1173 str = string_catn(str, intro, sl);
1176 intro = NULL; /* only want this once */
1181 size_t sl = Ustrlen(payload);
1182 size_t chomp = *col+sl < 77 ? sl : 78-*col;
1184 str = string_catn(str, payload, chomp);
1190 /* the while precondition tells us it didn't fit. */
1191 str = pdkim_hdr_cont(str, col);
1196 str = pdkim_hdr_cont(str, col);
1202 str = string_catn(str, US" ", 1);
1209 size_t sl = Ustrlen(intro);
1211 str = string_catn(str, intro, sl);
1219 size_t sl = Ustrlen(payload);
1221 str = string_catn(str, payload, sl);
1229 /* -------------------------------------------------------------------------- */
1231 /* Signing: create signature header
1234 pdkim_create_header(pdkim_signature * sig, BOOL final)
1240 gstring * canon_all;
1242 canon_all = string_cat (NULL, pdkim_canons[sig->canon_headers]);
1243 canon_all = string_catn(canon_all, US"/", 1);
1244 canon_all = string_cat (canon_all, pdkim_canons[sig->canon_body]);
1245 (void) string_from_gstring(canon_all);
1247 hdr = string_cat(NULL, US"DKIM-Signature: v="PDKIM_SIGNATURE_VERSION);
1250 /* Required and static bits */
1251 hdr = pdkim_headcat(&col, hdr, US";", US"a=", dkim_sig_to_a_tag(sig));
1252 hdr = pdkim_headcat(&col, hdr, US";", US"q=", pdkim_querymethods[sig->querymethod]);
1253 hdr = pdkim_headcat(&col, hdr, US";", US"c=", canon_all->s);
1254 hdr = pdkim_headcat(&col, hdr, US";", US"d=", sig->domain);
1255 hdr = pdkim_headcat(&col, hdr, US";", US"s=", sig->selector);
1257 /* list of header names can be split between items. */
1259 uschar * n = string_copy(sig->headernames);
1260 uschar * i = US"h=";
1265 uschar * c = Ustrchr(n, ':');
1270 hdr = pdkim_headcat(&col, hdr, NULL, NULL, US":");
1272 hdr = pdkim_headcat(&col, hdr, s, i, n);
1283 base64_bh = pdkim_encode_base64(&sig->calc_body_hash->bh);
1284 hdr = pdkim_headcat(&col, hdr, US";", US"bh=", base64_bh);
1288 hdr = pdkim_headcat(&col, hdr, US";", US"i=", sig->identity);
1290 if (sig->created > 0)
1294 snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->created);
1295 hdr = pdkim_headcat(&col, hdr, US";", US"t=", minibuf);
1298 if (sig->expires > 0)
1302 snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->expires);
1303 hdr = pdkim_headcat(&col, hdr, US";", US"x=", minibuf);
1306 if (sig->bodylength >= 0)
1310 snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->bodylength);
1311 hdr = pdkim_headcat(&col, hdr, US";", US"l=", minibuf);
1314 /* Preliminary or final version? */
1317 base64_b = pdkim_encode_base64(&sig->sighash);
1318 hdr = pdkim_headcat(&col, hdr, US";", US"b=", base64_b);
1320 /* add trailing semicolon: I'm not sure if this is actually needed */
1321 hdr = pdkim_headcat(&col, hdr, NULL, US";", US"");
1325 /* To satisfy the rule "all surrounding whitespace [...] deleted"
1326 ( RFC 6376 section 3.7 ) we ensure there is no whitespace here. Otherwise
1327 the headcat routine could insert a linebreak which the relaxer would reduce
1328 to a single space preceding the terminating semicolon, resulting in an
1329 incorrect header-hash. */
1330 hdr = pdkim_headcat(&col, hdr, US";", US"b=;", US"");
1333 return string_from_gstring(hdr);
1337 /* -------------------------------------------------------------------------- */
1339 static pdkim_pubkey *
1340 pdkim_key_from_dns(pdkim_ctx * ctx, pdkim_signature * sig, ev_ctx * vctx,
1341 const uschar ** errstr)
1343 uschar * dns_txt_name, * dns_txt_reply;
1346 /* Fetch public key for signing domain, from DNS */
1348 dns_txt_name = string_sprintf("%s._domainkey.%s.", sig->selector, sig->domain);
1350 if ( !(dns_txt_reply = ctx->dns_txt_callback(dns_txt_name))
1351 || dns_txt_reply[0] == '\0'
1354 sig->verify_status = PDKIM_VERIFY_INVALID;
1355 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE;
1362 "PDKIM >> Parsing public key record >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"
1366 pdkim_quoteprint(CUS dns_txt_reply, Ustrlen(dns_txt_reply));
1369 if ( !(p = pdkim_parse_pubkey_record(CUS dns_txt_reply))
1370 || (Ustrcmp(p->srvtype, "*") != 0 && Ustrcmp(p->srvtype, "email") != 0)
1373 sig->verify_status = PDKIM_VERIFY_INVALID;
1374 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD;
1379 debug_printf(" Invalid public key service type '%s'\n", p->srvtype);
1381 debug_printf(" Error while parsing public key record\n");
1383 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1388 DEBUG(D_acl) debug_printf(
1389 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1391 /* Import public key */
1393 /* Normally we use the signature a= tag to tell us the pubkey format.
1394 When signing under debug we do a test-import of the pubkey, and at that
1395 time we do not have a signature so we must interpret the pubkey k= tag
1396 instead. Assume writing on the sig is ok in that case. */
1398 if (sig->keytype < 0)
1401 for(i = 0; i < nelem(pdkim_keytypes); i++)
1402 if (Ustrcmp(p->keytype, pdkim_keytypes[i]) == 0)
1403 { sig->keytype = i; goto k_ok; }
1404 DEBUG(D_acl) debug_printf("verify_init: unhandled keytype %s\n", p->keytype);
1405 sig->verify_status = PDKIM_VERIFY_INVALID;
1406 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
1411 if ((*errstr = exim_dkim_verify_init(&p->key,
1412 sig->keytype == KEYTYPE_ED25519 ? KEYFMT_ED25519_BARE : KEYFMT_DER,
1415 DEBUG(D_acl) debug_printf("verify_init: %s\n", *errstr);
1416 sig->verify_status = PDKIM_VERIFY_INVALID;
1417 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
1421 vctx->keytype = sig->keytype;
1426 /* -------------------------------------------------------------------------- */
1429 pdkim_feed_finish(pdkim_ctx * ctx, pdkim_signature ** return_signatures,
1430 const uschar ** err)
1433 pdkim_signature * sig;
1434 BOOL verify_pass = FALSE;
1436 /* Check if we must still flush a (partial) header. If that is the
1437 case, the message has no body, and we must compute a body hash
1438 out of '<CR><LF>' */
1439 if (ctx->cur_header && ctx->cur_header->ptr > 0)
1444 if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1447 for (b = ctx->bodyhash; b; b = b->next)
1448 rnl = pdkim_update_ctx_bodyhash(b, &lineending, rnl);
1449 if (rnl) store_free(rnl);
1452 DEBUG(D_acl) debug_printf(
1453 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1455 /* Build (and/or evaluate) body hash. Do this even if no DKIM sigs, in case we
1456 have a hash to do for ARC. */
1458 pdkim_finish_bodyhash(ctx);
1462 DEBUG(D_acl) debug_printf("PDKIM: no signatures\n");
1463 *return_signatures = NULL;
1467 for (sig = ctx->sig; sig; sig = sig->next)
1470 uschar * sig_hdr = US"";
1472 gstring * hdata = NULL;
1475 if ( !(ctx->flags & PDKIM_MODE_SIGN)
1476 && sig->verify_status == PDKIM_VERIFY_FAIL)
1479 debug_printf("PDKIM: [%s] abandoning this signature\n", sig->domain);
1483 /*XXX The hash of the headers is needed for GCrypt (for which we can do RSA
1484 suging only, as it happens) and for either GnuTLS and OpenSSL when we are
1485 signing with EC (specifically, Ed25519). The former is because the GCrypt
1486 signing operation is pure (does not do its own hash) so we must hash. The
1487 latter is because we (stupidly, but this is what the IETF draft is saying)
1488 must hash with the declared hash method, then pass the result to the library
1489 hash-and-sign routine (because that's all the libraries are providing. And
1490 we're stuck with whatever that hidden hash method is, too). We may as well
1491 do this hash incrementally.
1492 We don't need the hash we're calculating here for the GnuTLS and OpenSSL
1493 cases of RSA signing, since those library routines can do hash-and-sign.
1495 Some time in the future we could easily avoid doing the hash here for those
1496 cases (which will be common for a long while. We could also change from
1497 the current copy-all-the-headers-into-one-block, then call the hash-and-sign
1498 implementation - to a proper incremental one. Unfortunately, GnuTLS just
1499 cannot do incremental - either signing or verification. Unsure about GCrypt.
1502 /*XXX The header hash is also used (so far) by the verify operation */
1504 if (!exim_sha_init(&hhash_ctx, pdkim_hashes[sig->hashtype].exim_hashmethod))
1506 log_write(0, LOG_MAIN|LOG_PANIC,
1507 "PDKIM: hash setup error, possibly nonhandled hashtype");
1511 if (ctx->flags & PDKIM_MODE_SIGN)
1512 DEBUG(D_acl) debug_printf(
1513 "PDKIM >> Headers to be signed: >>>>>>>>>>>>\n"
1517 DEBUG(D_acl) debug_printf(
1518 "PDKIM >> Header data for hash, canonicalized (%-7s), in sequence >>\n",
1519 pdkim_canons[sig->canon_headers]);
1522 /* SIGNING ---------------------------------------------------------------- */
1523 /* When signing, walk through our header list and add them to the hash. As we
1524 go, construct a list of the header's names to use for the h= parameter.
1525 Then append to that list any remaining header names for which there was no
1528 if (ctx->flags & PDKIM_MODE_SIGN)
1531 pdkim_stringlist *p;
1536 /* Import private key, including the keytype which we need for building
1537 the signature header */
1539 /*XXX extend for non-RSA algos */
1540 if ((*err = exim_dkim_signing_init(CUS sig->privkey, &sctx)))
1542 log_write(0, LOG_MAIN|LOG_PANIC, "signing_init: %s", *err);
1543 return PDKIM_ERR_RSA_PRIVKEY;
1545 sig->keytype = sctx.keytype;
1547 for (sig->headernames = NULL, /* Collected signed header names */
1548 p = sig->headers; p; p = p->next)
1550 uschar * rh = p->value;
1552 if (header_name_match(rh, sig->sign_headers) == PDKIM_OK)
1554 /* Collect header names (Note: colon presence is guaranteed here) */
1555 g = string_append_listele_n(g, ':', rh, Ustrchr(rh, ':') - rh);
1557 if (sig->canon_headers == PDKIM_CANON_RELAXED)
1558 rh = pdkim_relax_header(rh, TRUE); /* cook header for relaxed canon */
1560 /* Feed header to the hash algorithm */
1561 exim_sha_update(&hhash_ctx, CUS rh, Ustrlen(rh));
1563 /* Remember headers block for signing (when the library cannot do incremental) */
1564 /*XXX we could avoid doing this for all but the GnuTLS/RSA case */
1565 hdata = exim_dkim_data_append(hdata, rh);
1567 DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1571 /* Any headers we wanted to sign but were not present must also be listed.
1572 Ignore elements that have been ticked-off or are marked as never-oversign. */
1574 l = sig->sign_headers;
1575 while((s = string_nextinlist(&l, &sep, NULL, 0)))
1577 if (*s == '+') /* skip oversigning marker */
1579 if (*s != '_' && *s != '=')
1580 g = string_append_listele(g, ':', s);
1582 sig->headernames = string_from_gstring(g);
1584 /* Create signature header with b= omitted */
1585 sig_hdr = pdkim_create_header(sig, FALSE);
1588 /* VERIFICATION ----------------------------------------------------------- */
1589 /* When verifying, walk through the header name list in the h= parameter and
1590 add the headers to the hash in that order. */
1593 uschar * p = sig->headernames;
1595 pdkim_stringlist * hdrs;
1600 for (hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1606 if ((q = Ustrchr(p, ':')))
1609 /*XXX walk the list of headers in same order as received. */
1610 for (hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1612 && strncasecmp(CCS hdrs->value, CCS p, Ustrlen(p)) == 0
1613 && (hdrs->value)[Ustrlen(p)] == ':'
1616 /* cook header for relaxed canon, or just copy it for simple */
1618 uschar * rh = sig->canon_headers == PDKIM_CANON_RELAXED
1619 ? pdkim_relax_header(hdrs->value, TRUE)
1620 : string_copy(CUS hdrs->value);
1622 /* Feed header to the hash algorithm */
1623 exim_sha_update(&hhash_ctx, CUS rh, Ustrlen(rh));
1625 DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1634 sig_hdr = string_copy(sig->rawsig_no_b_val);
1638 DEBUG(D_acl) debug_printf(
1639 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1644 "PDKIM >> Signed DKIM-Signature header, pre-canonicalized >>>>>>>>>>>>>\n");
1645 pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr));
1647 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1650 /* Relax header if necessary */
1651 if (sig->canon_headers == PDKIM_CANON_RELAXED)
1652 sig_hdr = pdkim_relax_header(sig_hdr, FALSE);
1656 debug_printf("PDKIM >> Signed DKIM-Signature header, canonicalized (%-7s) >>>>>>>\n",
1657 pdkim_canons[sig->canon_headers]);
1658 pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr));
1660 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1663 /* Finalize header hash */
1664 exim_sha_update(&hhash_ctx, CUS sig_hdr, Ustrlen(sig_hdr));
1665 exim_sha_finish(&hhash_ctx, &hhash);
1669 debug_printf("PDKIM [%s] Header %s computed: ",
1670 sig->domain, pdkim_hashes[sig->hashtype].dkim_hashname);
1671 pdkim_hexprint(hhash.data, hhash.len);
1674 /* Remember headers block for signing (when the signing library cannot do
1676 if (ctx->flags & PDKIM_MODE_SIGN)
1677 hdata = exim_dkim_data_append(hdata, US sig_hdr);
1679 /* SIGNING ---------------------------------------------------------------- */
1680 if (ctx->flags & PDKIM_MODE_SIGN)
1682 hashmethod hm = sig->keytype == KEYTYPE_ED25519
1683 #if defined(SIGN_OPENSSL)
1688 : pdkim_hashes[sig->hashtype].exim_hashmethod;
1690 #ifdef SIGN_HAVE_ED25519
1691 /* For GCrypt, and for EC, we pass the hash-of-headers to the signing
1692 routine. For anything else we just pass the headers. */
1694 if (sig->keytype != KEYTYPE_ED25519)
1697 hhash.data = hdata->s;
1698 hhash.len = hdata->ptr;
1701 if ((*err = exim_dkim_sign(&sctx, hm, &hhash, &sig->sighash)))
1703 log_write(0, LOG_MAIN|LOG_PANIC, "signing: %s", *err);
1704 return PDKIM_ERR_RSA_SIGNING;
1709 debug_printf( "PDKIM [%s] b computed: ", sig->domain);
1710 pdkim_hexprint(sig->sighash.data, sig->sighash.len);
1713 sig->signature_header = pdkim_create_header(sig, TRUE);
1716 /* VERIFICATION ----------------------------------------------------------- */
1722 /* Make sure we have all required signature tags */
1723 if (!( sig->domain && *sig->domain
1724 && sig->selector && *sig->selector
1725 && sig->headernames && *sig->headernames
1726 && sig->bodyhash.data
1727 && sig->sighash.data
1728 && sig->keytype >= 0
1729 && sig->hashtype >= 0
1733 sig->verify_status = PDKIM_VERIFY_INVALID;
1734 sig->verify_ext_status = PDKIM_VERIFY_INVALID_SIGNATURE_ERROR;
1736 DEBUG(D_acl) debug_printf(
1737 " Error in DKIM-Signature header: tags missing or invalid (%s)\n"
1738 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
1739 !(sig->domain && *sig->domain) ? "d="
1740 : !(sig->selector && *sig->selector) ? "s="
1741 : !(sig->headernames && *sig->headernames) ? "h="
1742 : !sig->bodyhash.data ? "bh="
1743 : !sig->sighash.data ? "b="
1744 : sig->keytype < 0 || sig->hashtype < 0 ? "a="
1750 /* Make sure sig uses supported DKIM version (only v1) */
1751 if (sig->version != 1)
1753 sig->verify_status = PDKIM_VERIFY_INVALID;
1754 sig->verify_ext_status = PDKIM_VERIFY_INVALID_DKIM_VERSION;
1756 DEBUG(D_acl) debug_printf(
1757 " Error in DKIM-Signature header: unsupported DKIM version\n"
1758 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1764 debug_printf( "PDKIM [%s] b from mail: ", sig->domain);
1765 pdkim_hexprint(sig->sighash.data, sig->sighash.len);
1768 if (!(sig->pubkey = pdkim_key_from_dns(ctx, sig, &vctx, err)))
1770 log_write(0, LOG_MAIN, "PDKIM: %s%s %s%s [failed key import]",
1771 sig->domain ? "d=" : "", sig->domain ? sig->domain : US"",
1772 sig->selector ? "s=" : "", sig->selector ? sig->selector : US"");
1776 /* If the pubkey limits to a list of specific hashes, ignore sigs that
1777 do not have the hash part of the sig algorithm matching */
1779 if (sig->pubkey->hashes)
1781 const uschar * list = sig->pubkey->hashes, * ele;
1783 while ((ele = string_nextinlist(&list, &sep, NULL, 0)))
1784 if (Ustrcmp(ele, pdkim_hashes[sig->hashtype].dkim_hashname) == 0) break;
1787 DEBUG(D_acl) debug_printf("pubkey h=%s vs. sig a=%s_%s\n",
1788 sig->pubkey->hashes,
1789 pdkim_keytypes[sig->keytype],
1790 pdkim_hashes[sig->hashtype].dkim_hashname);
1791 sig->verify_status = PDKIM_VERIFY_FAIL;
1792 sig->verify_ext_status = PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH;
1797 hm = sig->keytype == KEYTYPE_ED25519
1798 #if defined(SIGN_OPENSSL)
1803 : pdkim_hashes[sig->hashtype].exim_hashmethod;
1805 /* Check the signature */
1807 if ((*err = exim_dkim_verify(&vctx, hm, &hhash, &sig->sighash)))
1809 DEBUG(D_acl) debug_printf("headers verify: %s\n", *err);
1810 sig->verify_status = PDKIM_VERIFY_FAIL;
1811 sig->verify_ext_status = PDKIM_VERIFY_FAIL_MESSAGE;
1816 /* We have a winner! (if bodyhash was correct earlier) */
1817 if (sig->verify_status == PDKIM_VERIFY_NONE)
1819 sig->verify_status = PDKIM_VERIFY_PASS;
1827 debug_printf("PDKIM [%s] %s signature status: %s",
1828 sig->domain, dkim_sig_to_a_tag(sig),
1829 pdkim_verify_status_str(sig->verify_status));
1830 if (sig->verify_ext_status > 0)
1831 debug_printf(" (%s)\n",
1832 pdkim_verify_ext_status_str(sig->verify_ext_status));
1839 /* If requested, set return pointer to signature(s) */
1840 if (return_signatures)
1841 *return_signatures = ctx->sig;
1843 return ctx->flags & PDKIM_MODE_SIGN || verify_pass
1844 ? PDKIM_OK : PDKIM_FAIL;
1848 /* -------------------------------------------------------------------------- */
1850 DLLEXPORT pdkim_ctx *
1851 pdkim_init_verify(uschar * (*dns_txt_callback)(uschar *), BOOL dot_stuffing)
1855 ctx = store_get(sizeof(pdkim_ctx));
1856 memset(ctx, 0, sizeof(pdkim_ctx));
1858 if (dot_stuffing) ctx->flags = PDKIM_DOT_TERM;
1859 ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN);
1860 ctx->dns_txt_callback = dns_txt_callback;
1866 /* -------------------------------------------------------------------------- */
1868 DLLEXPORT pdkim_signature *
1869 pdkim_init_sign(pdkim_ctx * ctx,
1870 uschar * domain, uschar * selector, uschar * privkey,
1871 uschar * hashname, const uschar ** errstr)
1874 pdkim_signature * sig;
1876 if (!domain || !selector || !privkey)
1879 /* Allocate & init one signature struct */
1881 sig = store_get(sizeof(pdkim_signature));
1882 memset(sig, 0, sizeof(pdkim_signature));
1884 sig->bodylength = -1;
1886 sig->domain = string_copy(US domain);
1887 sig->selector = string_copy(US selector);
1888 sig->privkey = string_copy(US privkey);
1891 for (hashtype = 0; hashtype < nelem(pdkim_hashes); hashtype++)
1892 if (Ustrcmp(hashname, pdkim_hashes[hashtype].dkim_hashname) == 0)
1893 { sig->hashtype = hashtype; break; }
1894 if (hashtype >= nelem(pdkim_hashes))
1896 log_write(0, LOG_MAIN|LOG_PANIC,
1897 "PDKIM: unrecognised hashname '%s'", hashname);
1903 pdkim_signature s = *sig;
1906 debug_printf("PDKIM (checking verify key)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1907 if (!pdkim_key_from_dns(ctx, &s, &vctx, errstr))
1908 debug_printf("WARNING: bad dkim key in dns\n");
1909 debug_printf("PDKIM (finished checking verify key)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1915 /* -------------------------------------------------------------------------- */
1918 pdkim_set_optional(pdkim_signature * sig,
1919 char * sign_headers,
1924 unsigned long created,
1925 unsigned long expires)
1928 sig->identity = string_copy(US identity);
1930 sig->sign_headers = string_copy(sign_headers
1931 ? US sign_headers : US PDKIM_DEFAULT_SIGN_HEADERS);
1933 sig->canon_headers = canon_headers;
1934 sig->canon_body = canon_body;
1935 sig->bodylength = bodylength;
1936 sig->created = created;
1937 sig->expires = expires;
1944 /* Set up a blob for calculating the bodyhash according to the
1945 given needs. Use an existing one if possible, or create a new one.
1947 Return: hashblob pointer, or NULL on error
1950 pdkim_set_bodyhash(pdkim_ctx * ctx, int hashtype, int canon_method,
1955 for (b = ctx->bodyhash; b; b = b->next)
1956 if ( hashtype == b->hashtype
1957 && canon_method == b->canon_method
1958 && bodylength == b->bodylength)
1960 DEBUG(D_receive) debug_printf("PDKIM: using existing bodyhash %d/%d/%ld\n",
1961 hashtype, canon_method, bodylength);
1965 DEBUG(D_receive) debug_printf("PDKIM: new bodyhash %d/%d/%ld\n",
1966 hashtype, canon_method, bodylength);
1967 b = store_get(sizeof(pdkim_bodyhash));
1968 b->next = ctx->bodyhash;
1969 b->hashtype = hashtype;
1970 b->canon_method = canon_method;
1971 b->bodylength = bodylength;
1972 if (!exim_sha_init(&b->body_hash_ctx, /*XXX hash method: extend for sha512 */
1973 pdkim_hashes[hashtype].exim_hashmethod))
1976 debug_printf("PDKIM: hash init error, possibly nonhandled hashtype\n");
1979 b->signed_body_bytes = 0;
1980 b->num_buffered_blanklines = 0;
1986 /* Set up a blob for calculating the bodyhash according to the
1987 needs of this signature. Use an existing one if possible, or
1990 Return: hashblob pointer, or NULL on error (only used as a boolean).
1993 pdkim_set_sig_bodyhash(pdkim_ctx * ctx, pdkim_signature * sig)
1995 pdkim_bodyhash * b = pdkim_set_bodyhash(ctx,
1996 sig->hashtype, sig->canon_body, sig->bodylength);
1997 sig->calc_body_hash = b;
2002 /* -------------------------------------------------------------------------- */
2006 pdkim_init_context(pdkim_ctx * ctx, BOOL dot_stuffed,
2007 uschar * (*dns_txt_callback)(uschar *))
2009 memset(ctx, 0, sizeof(pdkim_ctx));
2010 ctx->flags = dot_stuffed ? PDKIM_MODE_SIGN | PDKIM_DOT_TERM : PDKIM_MODE_SIGN;
2011 ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN);
2012 DEBUG(D_acl) ctx->dns_txt_callback = dns_txt_callback;
2024 #endif /*DISABLE_DKIM*/