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[] = {
75 const uschar * dkim_hashname;
76 hashmethod exim_hashmethod;
78 static const pdkim_hashtype pdkim_hashes[] = {
79 { US"sha1", HASH_SHA1 },
80 { US"sha256", HASH_SHA2_256 },
81 { US"sha512", HASH_SHA2_512 }
84 const uschar * pdkim_keytypes[] = {
85 [KEYTYPE_RSA] = US"rsa",
86 #ifdef SIGN_HAVE_ED25519
87 [KEYTYPE_ED25519] = US"ed25519", /* Works for 3.6.0 GnuTLS */
90 #ifdef notyet_EC_dkim_extensions /* https://tools.ietf.org/html/draft-srose-dkim-ecc-00 */
97 typedef struct pdkim_combined_canon_entry {
101 } pdkim_combined_canon_entry;
103 pdkim_combined_canon_entry pdkim_combined_canons[] = {
104 { US"simple/simple", PDKIM_CANON_SIMPLE, PDKIM_CANON_SIMPLE },
105 { US"simple/relaxed", PDKIM_CANON_SIMPLE, PDKIM_CANON_RELAXED },
106 { US"relaxed/simple", PDKIM_CANON_RELAXED, PDKIM_CANON_SIMPLE },
107 { US"relaxed/relaxed", PDKIM_CANON_RELAXED, PDKIM_CANON_RELAXED },
108 { US"simple", PDKIM_CANON_SIMPLE, PDKIM_CANON_SIMPLE },
109 { US"relaxed", PDKIM_CANON_RELAXED, PDKIM_CANON_SIMPLE },
114 static blob lineending = {.data = US"\r\n", .len = 2};
116 /* -------------------------------------------------------------------------- */
118 dkim_sig_to_a_tag(const pdkim_signature * sig)
120 if ( sig->keytype < 0 || sig->keytype > nelem(pdkim_keytypes)
121 || sig->hashtype < 0 || sig->hashtype > nelem(pdkim_hashes))
123 return string_sprintf("%s-%s",
124 pdkim_keytypes[sig->keytype], pdkim_hashes[sig->hashtype].dkim_hashname);
130 pdkim_verify_status_str(int status)
134 case PDKIM_VERIFY_NONE: return "PDKIM_VERIFY_NONE";
135 case PDKIM_VERIFY_INVALID: return "PDKIM_VERIFY_INVALID";
136 case PDKIM_VERIFY_FAIL: return "PDKIM_VERIFY_FAIL";
137 case PDKIM_VERIFY_PASS: return "PDKIM_VERIFY_PASS";
138 default: return "PDKIM_VERIFY_UNKNOWN";
143 pdkim_verify_ext_status_str(int ext_status)
147 case PDKIM_VERIFY_FAIL_BODY: return "PDKIM_VERIFY_FAIL_BODY";
148 case PDKIM_VERIFY_FAIL_MESSAGE: return "PDKIM_VERIFY_FAIL_MESSAGE";
149 case PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH: return "PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH";
150 case PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE: return "PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE";
151 case PDKIM_VERIFY_INVALID_BUFFER_SIZE: return "PDKIM_VERIFY_INVALID_BUFFER_SIZE";
152 case PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD: return "PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD";
153 case PDKIM_VERIFY_INVALID_PUBKEY_IMPORT: return "PDKIM_VERIFY_INVALID_PUBKEY_IMPORT";
154 case PDKIM_VERIFY_INVALID_SIGNATURE_ERROR: return "PDKIM_VERIFY_INVALID_SIGNATURE_ERROR";
155 case PDKIM_VERIFY_INVALID_DKIM_VERSION: return "PDKIM_VERIFY_INVALID_DKIM_VERSION";
156 default: return "PDKIM_VERIFY_UNKNOWN";
161 pdkim_errstr(int status)
165 case PDKIM_OK: return US"OK";
166 case PDKIM_FAIL: return US"FAIL";
167 case PDKIM_ERR_RSA_PRIVKEY: return US"PRIVKEY";
168 case PDKIM_ERR_RSA_SIGNING: return US"SIGNING";
169 case PDKIM_ERR_LONG_LINE: return US"LONG_LINE";
170 case PDKIM_ERR_BUFFER_TOO_SMALL: return US"BUFFER_TOO_SMALL";
171 case PDKIM_SIGN_PRIVKEY_WRAP: return US"PRIVKEY_WRAP";
172 case PDKIM_SIGN_PRIVKEY_B64D: return US"PRIVKEY_B64D";
173 default: return US"(unknown)";
178 /* -------------------------------------------------------------------------- */
179 /* Print debugging functions */
181 pdkim_quoteprint(const uschar *data, int len)
184 for (i = 0; i < len; i++)
186 const int c = data[i];
189 case ' ' : debug_printf("{SP}"); break;
190 case '\t': debug_printf("{TB}"); break;
191 case '\r': debug_printf("{CR}"); break;
192 case '\n': debug_printf("{LF}"); break;
193 case '{' : debug_printf("{BO}"); break;
194 case '}' : debug_printf("{BC}"); break;
196 if ( (c < 32) || (c > 127) )
197 debug_printf("{%02x}", c);
199 debug_printf("%c", c);
207 pdkim_hexprint(const uschar *data, int len)
210 if (data) for (i = 0 ; i < len; i++) debug_printf("%02x", data[i]);
211 else debug_printf("<NULL>");
217 static pdkim_stringlist *
218 pdkim_prepend_stringlist(pdkim_stringlist * base, const uschar * str)
220 pdkim_stringlist * new_entry = store_get(sizeof(pdkim_stringlist));
222 memset(new_entry, 0, sizeof(pdkim_stringlist));
223 new_entry->value = string_copy(str);
224 if (base) new_entry->next = base;
230 /* Trim whitespace fore & aft */
233 pdkim_strtrim(gstring * str)
238 while (*p == '\t' || *p == ' ') /* dump the leading whitespace */
239 { str->size--; str->ptr--; str->s++; }
242 && ((q = str->s + str->ptr - 1), (*q == '\t' || *q == ' '))
244 str->ptr--; /* dump trailing whitespace */
246 (void) string_from_gstring(str);
251 /* -------------------------------------------------------------------------- */
254 pdkim_free_ctx(pdkim_ctx *ctx)
259 /* -------------------------------------------------------------------------- */
260 /* Matches the name of the passed raw "header" against
261 the passed colon-separated "tick", and invalidates
262 the entry in tick. Entries can be prefixed for multi- or over-signing,
263 in which case do not invalidate.
265 Returns OK for a match, or fail-code
269 header_name_match(const uschar * header, uschar * tick)
271 const uschar * ticklist = tick;
274 uschar * hname, * p, * ele;
275 uschar * hcolon = Ustrchr(header, ':'); /* Get header name */
278 return PDKIM_FAIL; /* This isn't a header */
280 /* if we had strncmpic() we wouldn't need this copy */
281 hname = string_copyn(header, hcolon-header);
283 while (p = US ticklist, ele = string_nextinlist(&ticklist, &sep, NULL, 0))
287 case '=': case '+': multisign = TRUE; ele++; break;
288 default: multisign = FALSE; break;
291 if (strcmpic(ele, hname) == 0)
294 *p = '_'; /* Invalidate this header name instance in tick-off list */
302 /* -------------------------------------------------------------------------- */
303 /* Performs "relaxed" canonicalization of a header. */
306 pdkim_relax_header(const uschar * header, BOOL append_crlf)
308 BOOL past_field_name = FALSE;
309 BOOL seen_wsp = FALSE;
311 uschar * relaxed = store_get(Ustrlen(header)+3);
312 uschar * q = relaxed;
314 for (p = header; *p; p++)
318 if (c == '\r' || c == '\n') /* Ignore CR & LF */
320 if (c == '\t' || c == ' ')
324 c = ' '; /* Turns WSP into SP */
328 if (!past_field_name && c == ':')
330 if (seen_wsp) q--; /* This removes WSP immediately before the colon */
331 seen_wsp = TRUE; /* This removes WSP immediately after the colon */
332 past_field_name = TRUE;
337 /* Lowercase header name */
338 if (!past_field_name) c = tolower(c);
342 if (q > relaxed && q[-1] == ' ') q--; /* Squash eventual trailing SP */
344 if (append_crlf) { *q++ = '\r'; *q++ = '\n'; }
350 /* -------------------------------------------------------------------------- */
351 #define PDKIM_QP_ERROR_DECODE -1
353 static const uschar *
354 pdkim_decode_qp_char(const uschar *qp_p, int *c)
356 const uschar *initial_pos = qp_p;
358 /* Advance one char */
361 /* Check for two hex digits and decode them */
362 if (isxdigit(*qp_p) && isxdigit(qp_p[1]))
364 /* Do hex conversion */
365 *c = (isdigit(*qp_p) ? *qp_p - '0' : toupper(*qp_p) - 'A' + 10) << 4;
366 *c |= isdigit(qp_p[1]) ? qp_p[1] - '0' : toupper(qp_p[1]) - 'A' + 10;
370 /* Illegal char here */
371 *c = PDKIM_QP_ERROR_DECODE;
376 /* -------------------------------------------------------------------------- */
379 pdkim_decode_qp(const uschar * str)
383 const uschar * p = str;
384 uschar * n = store_get(Ustrlen(str)+1);
392 p = pdkim_decode_qp_char(p, &nchar);
408 /* -------------------------------------------------------------------------- */
411 pdkim_decode_base64(const uschar * str, blob * b)
414 dlen = b64decode(str, &b->data);
415 if (dlen < 0) b->data = NULL;
420 pdkim_encode_base64(blob * b)
422 return b64encode(b->data, b->len);
426 /* -------------------------------------------------------------------------- */
427 #define PDKIM_HDR_LIMBO 0
428 #define PDKIM_HDR_TAG 1
429 #define PDKIM_HDR_VALUE 2
431 static pdkim_signature *
432 pdkim_parse_sig_header(pdkim_ctx * ctx, uschar * raw_hdr)
434 pdkim_signature * sig;
436 gstring * cur_tag = NULL;
437 gstring * cur_val = NULL;
438 BOOL past_hname = FALSE;
439 BOOL in_b_val = FALSE;
440 int where = PDKIM_HDR_LIMBO;
443 sig = store_get(sizeof(pdkim_signature));
444 memset(sig, 0, sizeof(pdkim_signature));
445 sig->bodylength = -1;
447 /* Set so invalid/missing data error display is accurate */
452 q = sig->rawsig_no_b_val = store_get(Ustrlen(raw_hdr)+1);
454 for (p = raw_hdr; ; p++)
459 if (c == '\r' || c == '\n')
462 /* Fast-forward through header name */
465 if (c == ':') past_hname = TRUE;
469 if (where == PDKIM_HDR_LIMBO)
471 /* In limbo, just wait for a tag-char to appear */
472 if (!(c >= 'a' && c <= 'z'))
475 where = PDKIM_HDR_TAG;
478 if (where == PDKIM_HDR_TAG)
480 if (c >= 'a' && c <= 'z')
481 cur_tag = string_catn(cur_tag, p, 1);
485 if (Ustrcmp(string_from_gstring(cur_tag), "b") == 0)
490 where = PDKIM_HDR_VALUE;
495 if (where == PDKIM_HDR_VALUE)
497 if (c == '\r' || c == '\n' || c == ' ' || c == '\t')
500 if (c == ';' || c == '\0')
502 /* We must have both tag and value, and tags must be one char except
503 for the possibility of "bh". */
505 if ( cur_tag && cur_val
506 && (cur_tag->ptr == 1 || *cur_tag->s == 'b')
509 (void) string_from_gstring(cur_val);
510 pdkim_strtrim(cur_val);
512 DEBUG(D_acl) debug_printf(" %s=%s\n", cur_tag->s, cur_val->s);
516 case 'b': /* sig-data or body-hash */
517 switch (cur_tag->s[1])
519 case '\0': pdkim_decode_base64(cur_val->s, &sig->sighash); break;
520 case 'h': if (cur_tag->ptr == 2)
521 pdkim_decode_base64(cur_val->s, &sig->bodyhash);
526 case 'v': /* version */
527 /* We only support version 1, and that is currently the
528 only version there is. */
530 Ustrcmp(cur_val->s, PDKIM_SIGNATURE_VERSION) == 0 ? 1 : -1;
532 case 'a': /* algorithm */
534 uschar * s = Ustrchr(cur_val->s, '-');
536 for(i = 0; i < nelem(pdkim_keytypes); i++)
537 if (Ustrncmp(cur_val->s, pdkim_keytypes[i], s - cur_val->s) == 0)
538 { sig->keytype = i; break; }
539 if (sig->keytype < 0)
540 log_write(0, LOG_MAIN,
541 "DKIM: ignoring signature due to nonhandled keytype in a=%s",
544 for (++s, i = 0; i < nelem(pdkim_hashes); i++)
545 if (Ustrcmp(s, pdkim_hashes[i].dkim_hashname) == 0)
546 { sig->hashtype = i; break; }
547 if (sig->hashtype < 0)
548 log_write(0, LOG_MAIN,
549 "DKIM: ignoring signature due to nonhandled hashtype in a=%s",
554 case 'c': /* canonicalization */
555 for (i = 0; pdkim_combined_canons[i].str; i++)
556 if (Ustrcmp(cur_val->s, pdkim_combined_canons[i].str) == 0)
558 sig->canon_headers = pdkim_combined_canons[i].canon_headers;
559 sig->canon_body = pdkim_combined_canons[i].canon_body;
563 case 'q': /* Query method (for pubkey)*/
564 for (i = 0; pdkim_querymethods[i]; i++)
565 if (Ustrcmp(cur_val->s, pdkim_querymethods[i]) == 0)
567 sig->querymethod = i; /* we never actually use this */
571 case 's': /* Selector */
572 sig->selector = string_copyn(cur_val->s, cur_val->ptr); break;
574 sig->domain = string_copyn(cur_val->s, cur_val->ptr); break;
576 sig->identity = pdkim_decode_qp(cur_val->s); break;
577 case 't': /* Timestamp */
578 sig->created = strtoul(CS cur_val->s, NULL, 10); break;
579 case 'x': /* Expiration */
580 sig->expires = strtoul(CS cur_val->s, NULL, 10); break;
581 case 'l': /* Body length count */
582 sig->bodylength = strtol(CS cur_val->s, NULL, 10); break;
583 case 'h': /* signed header fields */
584 sig->headernames = string_copyn(cur_val->s, cur_val->ptr); break;
585 case 'z': /* Copied headfields */
586 sig->copiedheaders = pdkim_decode_qp(cur_val->s); break;
587 /*XXX draft-ietf-dcrup-dkim-crypto-05 would need 'p' tag support
588 for rsafp signatures. But later discussion is dropping those. */
590 DEBUG(D_acl) debug_printf(" Unknown tag encountered\n");
594 cur_tag = cur_val = NULL;
596 where = PDKIM_HDR_LIMBO;
599 cur_val = string_catn(cur_val, p, 1);
610 if (sig->keytype < 0 || sig->hashtype < 0) /* Cannot verify this signature */
614 /* Chomp raw header. The final newline must not be added to the signature. */
615 while (--q > sig->rawsig_no_b_val && (*q == '\r' || *q == '\n'))
621 "PDKIM >> Raw signature w/o b= tag value >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
622 pdkim_quoteprint(US sig->rawsig_no_b_val, Ustrlen(sig->rawsig_no_b_val));
624 "PDKIM >> Sig size: %4u bits\n", (unsigned) sig->sighash.len*8);
626 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
629 if (!pdkim_set_bodyhash(ctx, sig))
636 /* -------------------------------------------------------------------------- */
638 static pdkim_pubkey *
639 pdkim_parse_pubkey_record(pdkim_ctx *ctx, const uschar *raw_record)
645 pub = store_get(sizeof(pdkim_pubkey));
646 memset(pub, 0, sizeof(pdkim_pubkey));
648 while ((ele = string_nextinlist(&raw_record, &sep, NULL, 0)))
652 if ((val = Ustrchr(ele, '=')))
654 int taglen = val++ - ele;
656 DEBUG(D_acl) debug_printf(" %.*s=%s\n", taglen, ele, val);
659 case 'v': pub->version = val; break;
660 case 'h': pub->hashes = val; break;
661 case 'k': pub->keytype = val; break;
662 case 'g': pub->granularity = val; break;
663 case 'n': pub->notes = pdkim_decode_qp(val); break;
664 case 'p': pdkim_decode_base64(val, &pub->key); break;
665 case 's': pub->srvtype = val; break;
666 case 't': if (Ustrchr(val, 'y')) pub->testing = 1;
667 if (Ustrchr(val, 's')) pub->no_subdomaining = 1;
669 default: DEBUG(D_acl) debug_printf(" Unknown tag encountered\n"); break;
674 /* Set fallback defaults */
676 pub->version = string_copy(PDKIM_PUB_RECORD_VERSION);
677 else if (Ustrcmp(pub->version, PDKIM_PUB_RECORD_VERSION) != 0)
679 DEBUG(D_acl) debug_printf(" Bad v= field\n");
683 if (!pub->granularity) pub->granularity = US"*";
684 if (!pub->keytype ) pub->keytype = US"rsa";
685 if (!pub->srvtype ) pub->srvtype = US"*";
691 DEBUG(D_acl) debug_printf(" Missing p= field\n");
696 /* -------------------------------------------------------------------------- */
698 /* Update one bodyhash with some additional data.
699 If we have to relax the data for this sig, return our copy of it. */
702 pdkim_update_ctx_bodyhash(pdkim_bodyhash * b, blob * orig_data, blob * relaxed_data)
704 blob * canon_data = orig_data;
705 /* Defaults to simple canon (no further treatment necessary) */
707 if (b->canon_method == PDKIM_CANON_RELAXED)
709 /* Relax the line if not done already */
712 BOOL seen_wsp = FALSE;
713 const uschar * p, * r;
716 /* We want to be able to free this else we allocate
717 for the entire message which could be many MB. Since
718 we don't know what allocations the SHA routines might
719 do, not safe to use store_get()/store_reset(). */
721 relaxed_data = store_malloc(sizeof(blob) + orig_data->len+1);
722 relaxed_data->data = US (relaxed_data+1);
724 for (p = orig_data->data, r = p + orig_data->len; p < r; p++)
729 if (q > 0 && relaxed_data->data[q-1] == ' ')
732 else if (c == '\t' || c == ' ')
734 c = ' '; /* Turns WSP into SP */
741 relaxed_data->data[q++] = c;
743 relaxed_data->data[q] = '\0';
744 relaxed_data->len = q;
746 canon_data = relaxed_data;
749 /* Make sure we don't exceed the to-be-signed body length */
750 if ( b->bodylength >= 0
751 && b->signed_body_bytes + (unsigned long)canon_data->len > b->bodylength
753 canon_data->len = b->bodylength - b->signed_body_bytes;
755 if (canon_data->len > 0)
757 exim_sha_update(&b->body_hash_ctx, CUS canon_data->data, canon_data->len);
758 b->signed_body_bytes += canon_data->len;
759 DEBUG(D_acl) pdkim_quoteprint(canon_data->data, canon_data->len);
766 /* -------------------------------------------------------------------------- */
769 pdkim_finish_bodyhash(pdkim_ctx * ctx)
772 pdkim_signature * sig;
774 for (b = ctx->bodyhash; b; b = b->next) /* Finish hashes */
775 exim_sha_finish(&b->body_hash_ctx, &b->bh);
777 /* Traverse all signatures */
778 for (sig = ctx->sig; sig; sig = sig->next)
780 b = sig->calc_body_hash;
784 debug_printf("PDKIM [%s] Body bytes (%s) hashed: %lu\n"
785 "PDKIM [%s] Body %s computed: ",
786 sig->domain, pdkim_canons[b->canon_method], b->signed_body_bytes,
787 sig->domain, pdkim_hashes[b->hashtype].dkim_hashname);
788 pdkim_hexprint(CUS b->bh.data, b->bh.len);
791 /* SIGNING -------------------------------------------------------------- */
792 if (ctx->flags & PDKIM_MODE_SIGN)
794 /* If bodylength limit is set, and we have received less bytes
795 than the requested amount, effectively remove the limit tag. */
796 if (b->signed_body_bytes < sig->bodylength)
797 sig->bodylength = -1;
801 /* VERIFICATION --------------------------------------------------------- */
802 /* Be careful that the header sig included a bodyash */
804 if ( sig->bodyhash.data
805 && memcmp(b->bh.data, sig->bodyhash.data, b->bh.len) == 0)
807 DEBUG(D_acl) debug_printf("PDKIM [%s] Body hash compared OK\n", sig->domain);
813 debug_printf("PDKIM [%s] Body hash signature from headers: ", sig->domain);
814 pdkim_hexprint(sig->bodyhash.data, sig->bodyhash.len);
815 debug_printf("PDKIM [%s] Body hash did NOT verify\n", sig->domain);
817 sig->verify_status = PDKIM_VERIFY_FAIL;
818 sig->verify_ext_status = PDKIM_VERIFY_FAIL_BODY;
826 pdkim_body_complete(pdkim_ctx * ctx)
830 /* In simple body mode, if any empty lines were buffered,
831 replace with one. rfc 4871 3.4.3 */
832 /*XXX checking the signed-body-bytes is a gross hack; I think
833 it indicates that all linebreaks should be buffered, including
834 the one terminating a text line */
836 for (b = ctx->bodyhash; b; b = b->next)
837 if ( b->canon_method == PDKIM_CANON_SIMPLE
838 && b->signed_body_bytes == 0
839 && b->num_buffered_blanklines > 0
841 (void) pdkim_update_ctx_bodyhash(b, &lineending, NULL);
843 ctx->flags |= PDKIM_SEEN_EOD;
844 ctx->linebuf_offset = 0;
849 /* -------------------------------------------------------------------------- */
850 /* Call from pdkim_feed below for processing complete body lines */
851 /* NOTE: the line is not NUL-terminated; but we have a count */
854 pdkim_bodyline_complete(pdkim_ctx * ctx)
856 blob line = {.data = ctx->linebuf, .len = ctx->linebuf_offset};
861 /* Ignore extra data if we've seen the end-of-data marker */
862 if (ctx->flags & PDKIM_SEEN_EOD) goto all_skip;
864 /* We've always got one extra byte to stuff a zero ... */
865 ctx->linebuf[line.len] = '\0';
867 /* Terminate on EOD marker */
868 if (ctx->flags & PDKIM_DOT_TERM)
870 if (memcmp(line.data, ".\r\n", 3) == 0)
871 { pdkim_body_complete(ctx); return; }
874 if (memcmp(line.data, "..", 2) == 0)
875 { line.data++; line.len--; }
878 /* Empty lines need to be buffered until we find a non-empty line */
879 if (memcmp(line.data, "\r\n", 2) == 0)
881 for (b = ctx->bodyhash; b; b = b->next) b->num_buffered_blanklines++;
885 /* Process line for each bodyhash separately */
886 for (b = ctx->bodyhash; b; b = b->next)
888 if (b->canon_method == PDKIM_CANON_RELAXED)
890 /* Lines with just spaces need to be buffered too */
891 uschar * cp = line.data;
896 if (c == '\r' && cp[1] == '\n') break;
897 if (c != ' ' && c != '\t') goto hash_process;
901 b->num_buffered_blanklines++;
906 /* At this point, we have a non-empty line, so release the buffered ones. */
908 while (b->num_buffered_blanklines)
910 rnl = pdkim_update_ctx_bodyhash(b, &lineending, rnl);
911 b->num_buffered_blanklines--;
914 rline = pdkim_update_ctx_bodyhash(b, &line, rline);
918 if (rnl) store_free(rnl);
919 if (rline) store_free(rline);
923 ctx->linebuf_offset = 0;
928 /* -------------------------------------------------------------------------- */
929 /* Callback from pdkim_feed below for processing complete headers */
930 #define DKIM_SIGNATURE_HEADERNAME "DKIM-Signature:"
933 pdkim_header_complete(pdkim_ctx * ctx)
935 pdkim_signature * sig, * last_sig;
937 /* Special case: The last header can have an extra \r appended */
938 if ( (ctx->cur_header->ptr > 1) &&
939 (ctx->cur_header->s[ctx->cur_header->ptr-1] == '\r') )
940 --ctx->cur_header->ptr;
941 (void) string_from_gstring(ctx->cur_header);
943 if (++ctx->num_headers > PDKIM_MAX_HEADERS) goto BAIL;
945 /* SIGNING -------------------------------------------------------------- */
946 if (ctx->flags & PDKIM_MODE_SIGN)
947 for (sig = ctx->sig; sig; sig = sig->next) /* Traverse all signatures */
949 /* Add header to the signed headers list (in reverse order) */
950 sig->headers = pdkim_prepend_stringlist(sig->headers, ctx->cur_header->s);
952 /* VERIFICATION ----------------------------------------------------------- */
953 /* DKIM-Signature: headers are added to the verification list */
959 debug_printf("PDKIM >> raw hdr: ");
960 pdkim_quoteprint(CUS ctx->cur_header->s, ctx->cur_header->ptr);
963 if (strncasecmp(CCS ctx->cur_header->s,
964 DKIM_SIGNATURE_HEADERNAME,
965 Ustrlen(DKIM_SIGNATURE_HEADERNAME)) == 0)
967 /* Create and chain new signature block. We could error-check for all
968 required tags here, but prefer to create the internal sig and expicitly
969 fail verification of it later. */
971 DEBUG(D_acl) debug_printf(
972 "PDKIM >> Found sig, trying to parse >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
974 sig = pdkim_parse_sig_header(ctx, ctx->cur_header->s);
976 if (!(last_sig = ctx->sig))
980 while (last_sig->next) last_sig = last_sig->next;
981 last_sig->next = sig;
985 /* all headers are stored for signature verification */
986 ctx->headers = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->s);
990 ctx->cur_header->s[ctx->cur_header->ptr = 0] = '\0'; /* leave buffer for reuse */
996 /* -------------------------------------------------------------------------- */
997 #define HEADER_BUFFER_FRAG_SIZE 256
1000 pdkim_feed(pdkim_ctx * ctx, uschar * data, int len)
1004 /* Alternate EOD signal, used in non-dotstuffing mode */
1006 pdkim_body_complete(ctx);
1008 else for (p = 0; p<len; p++)
1012 if (ctx->flags & PDKIM_PAST_HDRS)
1014 if (c == '\n' && !(ctx->flags & PDKIM_SEEN_CR)) /* emulate the CR */
1016 ctx->linebuf[ctx->linebuf_offset++] = '\r';
1017 if (ctx->linebuf_offset == PDKIM_MAX_BODY_LINE_LEN-1)
1018 return PDKIM_ERR_LONG_LINE;
1021 /* Processing body byte */
1022 ctx->linebuf[ctx->linebuf_offset++] = c;
1024 ctx->flags |= PDKIM_SEEN_CR;
1027 ctx->flags &= ~PDKIM_SEEN_CR;
1028 pdkim_bodyline_complete(ctx);
1031 if (ctx->linebuf_offset == PDKIM_MAX_BODY_LINE_LEN-1)
1032 return PDKIM_ERR_LONG_LINE;
1036 /* Processing header byte */
1038 ctx->flags |= PDKIM_SEEN_CR;
1041 if (!(ctx->flags & PDKIM_SEEN_CR)) /* emulate the CR */
1042 ctx->cur_header = string_catn(ctx->cur_header, CUS "\r", 1);
1044 if (ctx->flags & PDKIM_SEEN_LF) /* Seen last header line */
1046 if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1049 ctx->flags = (ctx->flags & ~(PDKIM_SEEN_LF|PDKIM_SEEN_CR)) | PDKIM_PAST_HDRS;
1050 DEBUG(D_acl) debug_printf(
1051 "PDKIM >> Body data for hash, canonicalized >>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1055 ctx->flags = (ctx->flags & ~PDKIM_SEEN_CR) | PDKIM_SEEN_LF;
1057 else if (ctx->flags & PDKIM_SEEN_LF)
1059 if (!(c == '\t' || c == ' ')) /* End of header */
1060 if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1062 ctx->flags &= ~PDKIM_SEEN_LF;
1065 if (!ctx->cur_header || ctx->cur_header->ptr < PDKIM_MAX_HEADER_LEN)
1066 ctx->cur_header = string_catn(ctx->cur_header, CUS &data[p], 1);
1074 /* Extend a growing header with a continuation-linebreak */
1076 pdkim_hdr_cont(gstring * str, int * col)
1079 return string_catn(str, US"\r\n\t", 3);
1085 * RFC 5322 specifies that header line length SHOULD be no more than 78
1089 * returns uschar * (not nul-terminated)
1091 * col: this int holds and receives column number (octets since last '\n')
1092 * str: partial string to append to
1093 * pad: padding, split line or space after before or after eg: ";"
1094 * intro: - must join to payload eg "h=", usually the tag name
1095 * payload: eg base64 data - long data can be split arbitrarily.
1097 * this code doesn't fold the header in some of the places that RFC4871
1098 * allows: As per RFC5322(2.2.3) it only folds before or after tag-value
1099 * pairs and inside long values. it also always spaces or breaks after the
1102 * no guarantees are made for output given out-of range input. like tag
1103 * names longer than 78, or bogus col. Input is assumed to be free of line breaks.
1107 pdkim_headcat(int * col, gstring * str,
1108 const uschar * pad, const uschar * intro, const uschar * payload)
1116 str = pdkim_hdr_cont(str, col);
1117 str = string_catn(str, pad, l);
1121 l = (pad?1:0) + (intro?Ustrlen(intro):0);
1124 { /*can't fit intro - start a new line to make room.*/
1125 str = pdkim_hdr_cont(str, col);
1126 l = intro?Ustrlen(intro):0;
1129 l += payload ? Ustrlen(payload):0 ;
1132 { /* this fragment will not fit on a single line */
1135 str = string_catn(str, US" ", 1);
1137 pad = NULL; /* only want this once */
1143 size_t sl = Ustrlen(intro);
1145 str = string_catn(str, intro, sl);
1148 intro = NULL; /* only want this once */
1153 size_t sl = Ustrlen(payload);
1154 size_t chomp = *col+sl < 77 ? sl : 78-*col;
1156 str = string_catn(str, payload, chomp);
1162 /* the while precondition tells us it didn't fit. */
1163 str = pdkim_hdr_cont(str, col);
1168 str = pdkim_hdr_cont(str, col);
1174 str = string_catn(str, US" ", 1);
1181 size_t sl = Ustrlen(intro);
1183 str = string_catn(str, intro, sl);
1191 size_t sl = Ustrlen(payload);
1193 str = string_catn(str, payload, sl);
1201 /* -------------------------------------------------------------------------- */
1203 /* Signing: create signature header
1206 pdkim_create_header(pdkim_signature * sig, BOOL final)
1212 gstring * canon_all;
1214 canon_all = string_cat (NULL, pdkim_canons[sig->canon_headers]);
1215 canon_all = string_catn(canon_all, US"/", 1);
1216 canon_all = string_cat (canon_all, pdkim_canons[sig->canon_body]);
1217 (void) string_from_gstring(canon_all);
1219 hdr = string_cat(NULL, US"DKIM-Signature: v="PDKIM_SIGNATURE_VERSION);
1222 /* Required and static bits */
1223 hdr = pdkim_headcat(&col, hdr, US";", US"a=", dkim_sig_to_a_tag(sig));
1224 hdr = pdkim_headcat(&col, hdr, US";", US"q=", pdkim_querymethods[sig->querymethod]);
1225 hdr = pdkim_headcat(&col, hdr, US";", US"c=", canon_all->s);
1226 hdr = pdkim_headcat(&col, hdr, US";", US"d=", sig->domain);
1227 hdr = pdkim_headcat(&col, hdr, US";", US"s=", sig->selector);
1229 /* list of header names can be split between items. */
1231 uschar * n = string_copy(sig->headernames);
1232 uschar * i = US"h=";
1237 uschar * c = Ustrchr(n, ':');
1242 hdr = pdkim_headcat(&col, hdr, NULL, NULL, US":");
1244 hdr = pdkim_headcat(&col, hdr, s, i, n);
1255 base64_bh = pdkim_encode_base64(&sig->calc_body_hash->bh);
1256 hdr = pdkim_headcat(&col, hdr, US";", US"bh=", base64_bh);
1260 hdr = pdkim_headcat(&col, hdr, US";", US"i=", sig->identity);
1262 if (sig->created > 0)
1266 snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->created);
1267 hdr = pdkim_headcat(&col, hdr, US";", US"t=", minibuf);
1270 if (sig->expires > 0)
1274 snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->expires);
1275 hdr = pdkim_headcat(&col, hdr, US";", US"x=", minibuf);
1278 if (sig->bodylength >= 0)
1282 snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->bodylength);
1283 hdr = pdkim_headcat(&col, hdr, US";", US"l=", minibuf);
1286 /* Preliminary or final version? */
1289 base64_b = pdkim_encode_base64(&sig->sighash);
1290 hdr = pdkim_headcat(&col, hdr, US";", US"b=", base64_b);
1292 /* add trailing semicolon: I'm not sure if this is actually needed */
1293 hdr = pdkim_headcat(&col, hdr, NULL, US";", US"");
1297 /* To satisfy the rule "all surrounding whitespace [...] deleted"
1298 ( RFC 6376 section 3.7 ) we ensure there is no whitespace here. Otherwise
1299 the headcat routine could insert a linebreak which the relaxer would reduce
1300 to a single space preceding the terminating semicolon, resulting in an
1301 incorrect header-hash. */
1302 hdr = pdkim_headcat(&col, hdr, US";", US"b=;", US"");
1305 return string_from_gstring(hdr);
1309 /* -------------------------------------------------------------------------- */
1311 static pdkim_pubkey *
1312 pdkim_key_from_dns(pdkim_ctx * ctx, pdkim_signature * sig, ev_ctx * vctx,
1313 const uschar ** errstr)
1315 uschar * dns_txt_name, * dns_txt_reply;
1318 /* Fetch public key for signing domain, from DNS */
1320 dns_txt_name = string_sprintf("%s._domainkey.%s.", sig->selector, sig->domain);
1322 if ( !(dns_txt_reply = ctx->dns_txt_callback(CS dns_txt_name))
1323 || dns_txt_reply[0] == '\0'
1326 sig->verify_status = PDKIM_VERIFY_INVALID;
1327 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE;
1334 "PDKIM >> Parsing public key record >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"
1338 pdkim_quoteprint(CUS dns_txt_reply, Ustrlen(dns_txt_reply));
1341 if ( !(p = pdkim_parse_pubkey_record(ctx, CUS dns_txt_reply))
1342 || (Ustrcmp(p->srvtype, "*") != 0 && Ustrcmp(p->srvtype, "email") != 0)
1345 sig->verify_status = PDKIM_VERIFY_INVALID;
1346 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD;
1351 debug_printf(" Invalid public key service type '%s'\n", p->srvtype);
1353 debug_printf(" Error while parsing public key record\n");
1355 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1360 DEBUG(D_acl) debug_printf(
1361 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1363 /* Import public key */
1365 if ((*errstr = exim_dkim_verify_init(&p->key,
1366 sig->keytype == KEYTYPE_ED25519 ? KEYFMT_ED25519_BARE : KEYFMT_DER,
1369 DEBUG(D_acl) debug_printf("verify_init: %s\n", *errstr);
1370 sig->verify_status = PDKIM_VERIFY_INVALID;
1371 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
1375 vctx->keytype = sig->keytype;
1380 /* -------------------------------------------------------------------------- */
1383 pdkim_feed_finish(pdkim_ctx * ctx, pdkim_signature ** return_signatures,
1384 const uschar ** err)
1387 pdkim_signature * sig;
1388 BOOL verify_pass = FALSE;
1390 /* Check if we must still flush a (partial) header. If that is the
1391 case, the message has no body, and we must compute a body hash
1392 out of '<CR><LF>' */
1393 if (ctx->cur_header && ctx->cur_header->ptr > 0)
1398 if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1401 for (b = ctx->bodyhash; b; b = b->next)
1402 rnl = pdkim_update_ctx_bodyhash(b, &lineending, rnl);
1403 if (rnl) store_free(rnl);
1406 DEBUG(D_acl) debug_printf(
1407 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1411 DEBUG(D_acl) debug_printf("PDKIM: no signatures\n");
1415 /* Build (and/or evaluate) body hash */
1416 pdkim_finish_bodyhash(ctx);
1418 for (sig = ctx->sig; sig; sig = sig->next)
1421 uschar * sig_hdr = US"";
1423 gstring * hdata = NULL;
1426 /*XXX The hash of the headers is needed for GCrypt (for which we can do RSA
1427 suging only, as it happens) and for either GnuTLS and OpenSSL when we are
1428 signing with EC (specifically, Ed25519). The former is because the GCrypt
1429 signing operation is pure (does not do its own hash) so we must hash. The
1430 latter is because we (stupidly, but this is what the IETF draft is saying)
1431 must hash with the declared hash method, then pass the result to the library
1432 hash-and-sign routine (because that's all the libraries are providing. And
1433 we're stuck with whatever that hidden hash method is, too). We may as well
1434 do this hash incrementally.
1435 We don't need the hash we're calculating here for the GnuTLS and OpenSSL
1436 cases of RSA signing, since those library routines can do hash-and-sign.
1438 Some time in the future we could easily avoid doing the hash here for those
1439 cases (which will be common for a long while. We could also change from
1440 the current copy-all-the-headers-into-one-block, then call the hash-and-sign
1441 implementation - to a proper incremental one. Unfortunately, GnuTLS just
1442 cannot do incremental - either signing or verification. Unsure about GCrypt.
1445 /*XXX The header hash is also used (so far) by the verify operation */
1447 if (!exim_sha_init(&hhash_ctx, pdkim_hashes[sig->hashtype].exim_hashmethod))
1449 log_write(0, LOG_MAIN|LOG_PANIC,
1450 "PDKIM: hash setup error, possibly nonhandled hashtype");
1454 if (ctx->flags & PDKIM_MODE_SIGN)
1455 DEBUG(D_acl) debug_printf(
1456 "PDKIM >> Headers to be signed: >>>>>>>>>>>>\n"
1460 DEBUG(D_acl) debug_printf(
1461 "PDKIM >> Header data for hash, canonicalized (%-7s), in sequence >>\n",
1462 pdkim_canons[sig->canon_headers]);
1465 /* SIGNING ---------------------------------------------------------------- */
1466 /* When signing, walk through our header list and add them to the hash. As we
1467 go, construct a list of the header's names to use for the h= parameter.
1468 Then append to that list any remaining header names for which there was no
1471 if (ctx->flags & PDKIM_MODE_SIGN)
1474 pdkim_stringlist *p;
1479 /* Import private key, including the keytype which we need for building
1480 the signature header */
1482 /*XXX extend for non-RSA algos */
1483 if ((*err = exim_dkim_signing_init(US sig->privkey, &sctx)))
1485 log_write(0, LOG_MAIN|LOG_PANIC, "signing_init: %s", *err);
1486 return PDKIM_ERR_RSA_PRIVKEY;
1488 sig->keytype = sctx.keytype;
1490 for (sig->headernames = NULL, /* Collected signed header names */
1491 p = sig->headers; p; p = p->next)
1493 uschar * rh = p->value;
1495 if (header_name_match(rh, sig->sign_headers) == PDKIM_OK)
1497 /* Collect header names (Note: colon presence is guaranteed here) */
1498 g = string_append_listele_n(g, ':', rh, Ustrchr(rh, ':') - rh);
1500 if (sig->canon_headers == PDKIM_CANON_RELAXED)
1501 rh = pdkim_relax_header(rh, TRUE); /* cook header for relaxed canon */
1503 /* Feed header to the hash algorithm */
1504 exim_sha_update(&hhash_ctx, CUS rh, Ustrlen(rh));
1506 /* Remember headers block for signing (when the library cannot do incremental) */
1507 /*XXX we could avoid doing this for all but the GnuTLS/RSA case */
1508 hdata = exim_dkim_data_append(hdata, rh);
1510 DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1514 /* Any headers we wanted to sign but were not present must also be listed.
1515 Ignore elements that have been ticked-off or are marked as never-oversign. */
1517 l = sig->sign_headers;
1518 while((s = string_nextinlist(&l, &sep, NULL, 0)))
1520 if (*s == '+') /* skip oversigning marker */
1522 if (*s != '_' && *s != '=')
1523 g = string_append_listele(g, ':', s);
1525 sig->headernames = string_from_gstring(g);
1527 /* Create signature header with b= omitted */
1528 sig_hdr = pdkim_create_header(sig, FALSE);
1531 /* VERIFICATION ----------------------------------------------------------- */
1532 /* When verifying, walk through the header name list in the h= parameter and
1533 add the headers to the hash in that order. */
1536 uschar * p = sig->headernames;
1538 pdkim_stringlist * hdrs;
1543 for (hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1549 if ((q = Ustrchr(p, ':')))
1552 /*XXX walk the list of headers in same order as received. */
1553 for (hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1555 && strncasecmp(CCS hdrs->value, CCS p, Ustrlen(p)) == 0
1556 && (hdrs->value)[Ustrlen(p)] == ':'
1559 /* cook header for relaxed canon, or just copy it for simple */
1561 uschar * rh = sig->canon_headers == PDKIM_CANON_RELAXED
1562 ? pdkim_relax_header(hdrs->value, TRUE)
1563 : string_copy(CUS hdrs->value);
1565 /* Feed header to the hash algorithm */
1566 exim_sha_update(&hhash_ctx, CUS rh, Ustrlen(rh));
1568 DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1577 sig_hdr = string_copy(sig->rawsig_no_b_val);
1581 DEBUG(D_acl) debug_printf(
1582 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1587 "PDKIM >> Signed DKIM-Signature header, pre-canonicalized >>>>>>>>>>>>>\n");
1588 pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr));
1590 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1593 /* Relax header if necessary */
1594 if (sig->canon_headers == PDKIM_CANON_RELAXED)
1595 sig_hdr = pdkim_relax_header(sig_hdr, FALSE);
1599 debug_printf("PDKIM >> Signed DKIM-Signature header, canonicalized (%-7s) >>>>>>>\n",
1600 pdkim_canons[sig->canon_headers]);
1601 pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr));
1603 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1606 /* Finalize header hash */
1607 exim_sha_update(&hhash_ctx, CUS sig_hdr, Ustrlen(sig_hdr));
1608 exim_sha_finish(&hhash_ctx, &hhash);
1612 debug_printf("PDKIM [%s] Header %s computed: ",
1613 sig->domain, pdkim_hashes[sig->hashtype].dkim_hashname);
1614 pdkim_hexprint(hhash.data, hhash.len);
1617 /* Remember headers block for signing (when the signing library cannot do
1619 if (ctx->flags & PDKIM_MODE_SIGN)
1620 hdata = exim_dkim_data_append(hdata, US sig_hdr);
1622 /* SIGNING ---------------------------------------------------------------- */
1623 if (ctx->flags & PDKIM_MODE_SIGN)
1625 hashmethod hm = sig->keytype == KEYTYPE_ED25519
1626 ? HASH_SHA2_512 : pdkim_hashes[sig->hashtype].exim_hashmethod;
1628 #ifdef SIGN_HAVE_ED25519
1629 /* For GCrypt, and for EC, we pass the hash-of-headers to the signing
1630 routine. For anything else we just pass the headers. */
1632 if (sig->keytype != KEYTYPE_ED25519)
1635 hhash.data = hdata->s;
1636 hhash.len = hdata->ptr;
1639 /*XXX extend for non-RSA algos */
1640 /*- done for GnuTLS */
1641 if ((*err = exim_dkim_sign(&sctx, hm, &hhash, &sig->sighash)))
1643 log_write(0, LOG_MAIN|LOG_PANIC, "signing: %s", *err);
1644 return PDKIM_ERR_RSA_SIGNING;
1649 debug_printf( "PDKIM [%s] b computed: ", sig->domain);
1650 pdkim_hexprint(sig->sighash.data, sig->sighash.len);
1653 sig->signature_header = pdkim_create_header(sig, TRUE);
1656 /* VERIFICATION ----------------------------------------------------------- */
1661 /* Make sure we have all required signature tags */
1662 if (!( sig->domain && *sig->domain
1663 && sig->selector && *sig->selector
1664 && sig->headernames && *sig->headernames
1665 && sig->bodyhash.data
1666 && sig->sighash.data
1667 && sig->keytype >= 0
1668 && sig->hashtype >= 0
1672 sig->verify_status = PDKIM_VERIFY_INVALID;
1673 sig->verify_ext_status = PDKIM_VERIFY_INVALID_SIGNATURE_ERROR;
1675 DEBUG(D_acl) debug_printf(
1676 " Error in DKIM-Signature header: tags missing or invalid\n"
1677 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1681 /* Make sure sig uses supported DKIM version (only v1) */
1682 if (sig->version != 1)
1684 sig->verify_status = PDKIM_VERIFY_INVALID;
1685 sig->verify_ext_status = PDKIM_VERIFY_INVALID_DKIM_VERSION;
1687 DEBUG(D_acl) debug_printf(
1688 " Error in DKIM-Signature header: unsupported DKIM version\n"
1689 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1695 debug_printf( "PDKIM [%s] b from mail: ", sig->domain);
1696 pdkim_hexprint(sig->sighash.data, sig->sighash.len);
1699 if (!(sig->pubkey = pdkim_key_from_dns(ctx, sig, &vctx, err)))
1701 log_write(0, LOG_MAIN, "PDKIM: %s%s %s%s [failed key import]",
1702 sig->domain ? "d=" : "", sig->domain ? sig->domain : US"",
1703 sig->selector ? "s=" : "", sig->selector ? sig->selector : US"");
1707 /* If the pubkey limits to a list of specific hashes, ignore sigs that
1708 do not have the hash part of the sig algorithm matching */
1710 if (sig->pubkey->hashes)
1712 const uschar * list = sig->pubkey->hashes, * ele;
1714 while ((ele = string_nextinlist(&list, &sep, NULL, 0)))
1715 if (Ustrcmp(ele, pdkim_hashes[sig->hashtype].dkim_hashname) == 0) break;
1718 DEBUG(D_acl) debug_printf("pubkey h=%s vs. sig a=%s_%s\n",
1719 sig->pubkey->hashes,
1720 pdkim_keytypes[sig->keytype],
1721 pdkim_hashes[sig->hashtype].dkim_hashname);
1722 sig->verify_status = PDKIM_VERIFY_FAIL;
1723 sig->verify_ext_status = PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH;
1728 /* Check the signature */
1729 /*XXX extend for non-RSA algos */
1730 /*- done for GnuTLS */
1731 if ((*err = exim_dkim_verify(&vctx,
1732 pdkim_hashes[sig->hashtype].exim_hashmethod,
1733 &hhash, &sig->sighash)))
1735 DEBUG(D_acl) debug_printf("headers verify: %s\n", *err);
1736 sig->verify_status = PDKIM_VERIFY_FAIL;
1737 sig->verify_ext_status = PDKIM_VERIFY_FAIL_MESSAGE;
1742 /* We have a winner! (if bodyhash was correct earlier) */
1743 if (sig->verify_status == PDKIM_VERIFY_NONE)
1745 sig->verify_status = PDKIM_VERIFY_PASS;
1753 debug_printf("PDKIM [%s] %s signature status: %s",
1754 sig->domain, dkim_sig_to_a_tag(sig),
1755 pdkim_verify_status_str(sig->verify_status));
1756 if (sig->verify_ext_status > 0)
1757 debug_printf(" (%s)\n",
1758 pdkim_verify_ext_status_str(sig->verify_ext_status));
1765 /* If requested, set return pointer to signature(s) */
1766 if (return_signatures)
1767 *return_signatures = ctx->sig;
1769 return ctx->flags & PDKIM_MODE_SIGN || verify_pass
1770 ? PDKIM_OK : PDKIM_FAIL;
1774 /* -------------------------------------------------------------------------- */
1776 DLLEXPORT pdkim_ctx *
1777 pdkim_init_verify(uschar * (*dns_txt_callback)(char *), BOOL dot_stuffing)
1781 ctx = store_get(sizeof(pdkim_ctx));
1782 memset(ctx, 0, sizeof(pdkim_ctx));
1784 if (dot_stuffing) ctx->flags = PDKIM_DOT_TERM;
1785 ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN);
1786 ctx->dns_txt_callback = dns_txt_callback;
1792 /* -------------------------------------------------------------------------- */
1794 DLLEXPORT pdkim_signature *
1795 pdkim_init_sign(pdkim_ctx * ctx,
1796 uschar * domain, uschar * selector, uschar * privkey,
1797 uschar * hashname, const uschar ** errstr)
1800 pdkim_signature * sig;
1802 if (!domain || !selector || !privkey)
1805 /* Allocate & init one signature struct */
1807 sig = store_get(sizeof(pdkim_signature));
1808 memset(sig, 0, sizeof(pdkim_signature));
1810 sig->bodylength = -1;
1812 sig->domain = string_copy(US domain);
1813 sig->selector = string_copy(US selector);
1814 sig->privkey = string_copy(US privkey);
1817 for (hashtype = 0; hashtype < nelem(pdkim_hashes); hashtype++)
1818 if (Ustrcmp(hashname, pdkim_hashes[hashtype].dkim_hashname) == 0)
1819 { sig->hashtype = hashtype; break; }
1820 if (hashtype >= nelem(pdkim_hashes))
1822 log_write(0, LOG_MAIN|LOG_PANIC,
1823 "PDKIM: unrecognised hashname '%s'", hashname);
1829 pdkim_signature s = *sig;
1832 debug_printf("PDKIM (checking verify key)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1833 if (!pdkim_key_from_dns(ctx, &s, &vctx, errstr))
1834 debug_printf("WARNING: bad dkim key in dns\n");
1835 debug_printf("PDKIM (finished checking verify key)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1841 /* -------------------------------------------------------------------------- */
1844 pdkim_set_optional(pdkim_signature * sig,
1845 char * sign_headers,
1850 unsigned long created,
1851 unsigned long expires)
1854 sig->identity = string_copy(US identity);
1856 sig->sign_headers = string_copy(sign_headers
1857 ? US sign_headers : US PDKIM_DEFAULT_SIGN_HEADERS);
1859 sig->canon_headers = canon_headers;
1860 sig->canon_body = canon_body;
1861 sig->bodylength = bodylength;
1862 sig->created = created;
1863 sig->expires = expires;
1870 /* Set up a blob for calculating the bodyhash according to the
1871 needs of this signature. Use an existing one if possible, or
1874 Return: hashblob pointer, or NULL on error (only used as a boolean).
1877 pdkim_set_bodyhash(pdkim_ctx * ctx, pdkim_signature * sig)
1881 for (b = ctx->bodyhash; b; b = b->next)
1882 if ( sig->hashtype == b->hashtype
1883 && sig->canon_body == b->canon_method
1884 && sig->bodylength == b->bodylength)
1887 b = store_get(sizeof(pdkim_bodyhash));
1888 b->next = ctx->bodyhash;
1889 b->hashtype = sig->hashtype;
1890 b->canon_method = sig->canon_body;
1891 b->bodylength = sig->bodylength;
1892 if (!exim_sha_init(&b->body_hash_ctx, /*XXX hash method: extend for sha512 */
1893 pdkim_hashes[sig->hashtype].exim_hashmethod))
1896 debug_printf("PDKIM: hash init error, possibly nonhandled hashtype\n");
1899 b->signed_body_bytes = 0;
1900 b->num_buffered_blanklines = 0;
1904 sig->calc_body_hash = b;
1909 /* -------------------------------------------------------------------------- */
1913 pdkim_init_context(pdkim_ctx * ctx, BOOL dot_stuffed,
1914 uschar * (*dns_txt_callback)(char *))
1916 memset(ctx, 0, sizeof(pdkim_ctx));
1917 ctx->flags = dot_stuffed ? PDKIM_MODE_SIGN | PDKIM_DOT_TERM : PDKIM_MODE_SIGN;
1918 ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN);
1919 DEBUG(D_acl) ctx->dns_txt_callback = dns_txt_callback;
1931 #endif /*DISABLE_DKIM*/