Merge branch '4.next'
[exim.git] / src / src / pdkim / pdkim.c
1 /*
2 * PDKIM - a RFC4871 (DKIM) implementation
3 *
4 * Copyright (C) 2009 - 2016 Tom Kistner <tom@duncanthrax.net>
5 * Copyright (C) 2016 - 2018 Jeremy Harris <jgh@exim.org>
6 *
7 * http://duncanthrax.net/pdkim/
8 *
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.
13 *
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.
18 *
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.
22 */
23
24 #include "../exim.h"
25
26
27 #ifndef DISABLE_DKIM /* entire file */
28
29 #ifdef DISABLE_TLS
30 # error Must not DISABLE_TLS, for DKIM
31 #endif
32
33 #include "crypt_ver.h"
34
35 #ifdef SIGN_OPENSSL
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>
42 #endif
43
44 #include "pdkim.h"
45 #include "signing.h"
46
47 #define PDKIM_SIGNATURE_VERSION "1"
48 #define PDKIM_PUB_RECORD_VERSION US "DKIM1"
49
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
54
55 /* -------------------------------------------------------------------------- */
56 struct pdkim_stringlist {
57 uschar * value;
58 int tag;
59 void * next;
60 };
61
62 /* -------------------------------------------------------------------------- */
63 /* A bunch of list constants */
64 const uschar * pdkim_querymethods[] = {
65 US"dns/txt",
66 NULL
67 };
68 const uschar * pdkim_canons[] = {
69 US"simple",
70 US"relaxed",
71 NULL
72 };
73
74 const pdkim_hashtype pdkim_hashes[] = {
75 { US"sha1", HASH_SHA1 },
76 { US"sha256", HASH_SHA2_256 },
77 { US"sha512", HASH_SHA2_512 }
78 };
79
80 const uschar * pdkim_keytypes[] = {
81 [KEYTYPE_RSA] = US"rsa",
82 #ifdef SIGN_HAVE_ED25519
83 [KEYTYPE_ED25519] = US"ed25519", /* Works for 3.6.0 GnuTLS, OpenSSL 1.1.1 */
84 #endif
85
86 #ifdef notyet_EC_dkim_extensions /* https://tools.ietf.org/html/draft-srose-dkim-ecc-00 */
87 US"eccp256",
88 US"eccp348",
89 US"ed448",
90 #endif
91 };
92
93 typedef struct pdkim_combined_canon_entry {
94 const uschar * str;
95 int canon_headers;
96 int canon_body;
97 } pdkim_combined_canon_entry;
98
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 },
106 { NULL, 0, 0 }
107 };
108
109
110 static blob lineending = {.data = US"\r\n", .len = 2};
111
112 /* -------------------------------------------------------------------------- */
113 uschar *
114 dkim_sig_to_a_tag(const pdkim_signature * sig)
115 {
116 if ( sig->keytype < 0 || sig->keytype > nelem(pdkim_keytypes)
117 || sig->hashtype < 0 || sig->hashtype > nelem(pdkim_hashes))
118 return US"err";
119 return string_sprintf("%s-%s",
120 pdkim_keytypes[sig->keytype], pdkim_hashes[sig->hashtype].dkim_hashname);
121 }
122
123
124 static int
125 pdkim_keyname_to_keytype(const uschar * s)
126 {
127 for (int i = 0; i < nelem(pdkim_keytypes); i++)
128 if (Ustrcmp(s, pdkim_keytypes[i]) == 0) return i;
129 return -1;
130 }
131
132 int
133 pdkim_hashname_to_hashtype(const uschar * s, unsigned len)
134 {
135 if (!len) len = Ustrlen(s);
136 for (int i = 0; i < nelem(pdkim_hashes); i++)
137 if (Ustrncmp(s, pdkim_hashes[i].dkim_hashname, len) == 0)
138 return i;
139 return -1;
140 }
141
142 void
143 pdkim_cstring_to_canons(const uschar * s, unsigned len,
144 int * canon_head, int * canon_body)
145 {
146 if (!len) len = Ustrlen(s);
147 for (int i = 0; pdkim_combined_canons[i].str; i++)
148 if ( Ustrncmp(s, pdkim_combined_canons[i].str, len) == 0
149 && len == Ustrlen(pdkim_combined_canons[i].str))
150 {
151 *canon_head = pdkim_combined_canons[i].canon_headers;
152 *canon_body = pdkim_combined_canons[i].canon_body;
153 break;
154 }
155 }
156
157
158
159 const char *
160 pdkim_verify_status_str(int status)
161 {
162 switch(status)
163 {
164 case PDKIM_VERIFY_NONE: return "PDKIM_VERIFY_NONE";
165 case PDKIM_VERIFY_INVALID: return "PDKIM_VERIFY_INVALID";
166 case PDKIM_VERIFY_FAIL: return "PDKIM_VERIFY_FAIL";
167 case PDKIM_VERIFY_PASS: return "PDKIM_VERIFY_PASS";
168 default: return "PDKIM_VERIFY_UNKNOWN";
169 }
170 }
171
172 const char *
173 pdkim_verify_ext_status_str(int ext_status)
174 {
175 switch(ext_status)
176 {
177 case PDKIM_VERIFY_FAIL_BODY: return "PDKIM_VERIFY_FAIL_BODY";
178 case PDKIM_VERIFY_FAIL_MESSAGE: return "PDKIM_VERIFY_FAIL_MESSAGE";
179 case PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH: return "PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH";
180 case PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE: return "PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE";
181 case PDKIM_VERIFY_INVALID_BUFFER_SIZE: return "PDKIM_VERIFY_INVALID_BUFFER_SIZE";
182 case PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD: return "PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD";
183 case PDKIM_VERIFY_INVALID_PUBKEY_IMPORT: return "PDKIM_VERIFY_INVALID_PUBKEY_IMPORT";
184 case PDKIM_VERIFY_INVALID_SIGNATURE_ERROR: return "PDKIM_VERIFY_INVALID_SIGNATURE_ERROR";
185 case PDKIM_VERIFY_INVALID_DKIM_VERSION: return "PDKIM_VERIFY_INVALID_DKIM_VERSION";
186 default: return "PDKIM_VERIFY_UNKNOWN";
187 }
188 }
189
190 const uschar *
191 pdkim_errstr(int status)
192 {
193 switch(status)
194 {
195 case PDKIM_OK: return US"OK";
196 case PDKIM_FAIL: return US"FAIL";
197 case PDKIM_ERR_RSA_PRIVKEY: return US"PRIVKEY";
198 case PDKIM_ERR_RSA_SIGNING: return US"SIGNING";
199 case PDKIM_ERR_LONG_LINE: return US"LONG_LINE";
200 case PDKIM_ERR_BUFFER_TOO_SMALL: return US"BUFFER_TOO_SMALL";
201 case PDKIM_ERR_EXCESS_SIGS: return US"EXCESS_SIGS";
202 case PDKIM_SIGN_PRIVKEY_WRAP: return US"PRIVKEY_WRAP";
203 case PDKIM_SIGN_PRIVKEY_B64D: return US"PRIVKEY_B64D";
204 default: return US"(unknown)";
205 }
206 }
207
208
209 /* -------------------------------------------------------------------------- */
210 /* Print debugging functions */
211 void
212 pdkim_quoteprint(const uschar *data, int len)
213 {
214 for (int i = 0; i < len; i++)
215 {
216 const int c = data[i];
217 switch (c)
218 {
219 case ' ' : debug_printf("{SP}"); break;
220 case '\t': debug_printf("{TB}"); break;
221 case '\r': debug_printf("{CR}"); break;
222 case '\n': debug_printf("{LF}"); break;
223 case '{' : debug_printf("{BO}"); break;
224 case '}' : debug_printf("{BC}"); break;
225 default:
226 if ( (c < 32) || (c > 127) )
227 debug_printf("{%02x}", c);
228 else
229 debug_printf("%c", c);
230 break;
231 }
232 }
233 debug_printf("\n");
234 }
235
236 void
237 pdkim_hexprint(const uschar *data, int len)
238 {
239 if (data) for (int i = 0 ; i < len; i++) debug_printf("%02x", data[i]);
240 else debug_printf("<NULL>");
241 debug_printf("\n");
242 }
243
244
245
246 static pdkim_stringlist *
247 pdkim_prepend_stringlist(pdkim_stringlist * base, const uschar * str)
248 {
249 pdkim_stringlist * new_entry = store_get(sizeof(pdkim_stringlist), FALSE);
250
251 memset(new_entry, 0, sizeof(pdkim_stringlist));
252 new_entry->value = string_copy(str);
253 if (base) new_entry->next = base;
254 return new_entry;
255 }
256
257
258
259 /* Trim whitespace fore & aft */
260
261 static void
262 pdkim_strtrim(gstring * str)
263 {
264 uschar * p = str->s;
265 uschar * q;
266
267 while (*p == '\t' || *p == ' ') /* dump the leading whitespace */
268 { str->size--; str->ptr--; str->s++; }
269
270 while ( str->ptr > 0
271 && ((q = str->s + str->ptr - 1), (*q == '\t' || *q == ' '))
272 )
273 str->ptr--; /* dump trailing whitespace */
274
275 (void) string_from_gstring(str);
276 }
277
278
279
280 /* -------------------------------------------------------------------------- */
281
282 DLLEXPORT void
283 pdkim_free_ctx(pdkim_ctx *ctx)
284 {
285 }
286
287
288 /* -------------------------------------------------------------------------- */
289 /* Matches the name of the passed raw "header" against
290 the passed colon-separated "tick", and invalidates
291 the entry in tick. Entries can be prefixed for multi- or over-signing,
292 in which case do not invalidate.
293
294 Returns OK for a match, or fail-code
295 */
296
297 static int
298 header_name_match(const uschar * header, uschar * tick)
299 {
300 const uschar * ticklist = tick;
301 int sep = ':';
302 BOOL multisign;
303 uschar * hname, * p, * ele;
304 uschar * hcolon = Ustrchr(header, ':'); /* Get header name */
305
306 if (!hcolon)
307 return PDKIM_FAIL; /* This isn't a header */
308
309 /* if we had strncmpic() we wouldn't need this copy */
310 hname = string_copyn(header, hcolon-header);
311
312 while (p = US ticklist, ele = string_nextinlist(&ticklist, &sep, NULL, 0))
313 {
314 switch (*ele)
315 {
316 case '=': case '+': multisign = TRUE; ele++; break;
317 default: multisign = FALSE; break;
318 }
319
320 if (strcmpic(ele, hname) == 0)
321 {
322 if (!multisign)
323 *p = '_'; /* Invalidate this header name instance in tick-off list */
324 return PDKIM_OK;
325 }
326 }
327 return PDKIM_FAIL;
328 }
329
330
331 /* -------------------------------------------------------------------------- */
332 /* Performs "relaxed" canonicalization of a header. */
333
334 uschar *
335 pdkim_relax_header_n(const uschar * header, int len, BOOL append_crlf)
336 {
337 BOOL past_field_name = FALSE;
338 BOOL seen_wsp = FALSE;
339 uschar * relaxed = store_get(len+3, TRUE); /* tainted */
340 uschar * q = relaxed;
341
342 for (const uschar * p = header; p - header < len; p++)
343 {
344 uschar c = *p;
345
346 if (c == '\r' || c == '\n') /* Ignore CR & LF */
347 continue;
348 if (c == '\t' || c == ' ')
349 {
350 if (seen_wsp)
351 continue;
352 c = ' '; /* Turns WSP into SP */
353 seen_wsp = TRUE;
354 }
355 else
356 if (!past_field_name && c == ':')
357 {
358 if (seen_wsp) q--; /* This removes WSP immediately before the colon */
359 seen_wsp = TRUE; /* This removes WSP immediately after the colon */
360 past_field_name = TRUE;
361 }
362 else
363 seen_wsp = FALSE;
364
365 /* Lowercase header name */
366 if (!past_field_name) c = tolower(c);
367 *q++ = c;
368 }
369
370 if (q > relaxed && q[-1] == ' ') q--; /* Squash eventual trailing SP */
371
372 if (append_crlf) { *q++ = '\r'; *q++ = '\n'; }
373 *q = '\0';
374 return relaxed;
375 }
376
377
378 uschar *
379 pdkim_relax_header(const uschar * header, BOOL append_crlf)
380 {
381 return pdkim_relax_header_n(header, Ustrlen(header), append_crlf);
382 }
383
384
385 /* -------------------------------------------------------------------------- */
386 #define PDKIM_QP_ERROR_DECODE -1
387
388 static const uschar *
389 pdkim_decode_qp_char(const uschar *qp_p, int *c)
390 {
391 const uschar *initial_pos = qp_p;
392
393 /* Advance one char */
394 qp_p++;
395
396 /* Check for two hex digits and decode them */
397 if (isxdigit(*qp_p) && isxdigit(qp_p[1]))
398 {
399 /* Do hex conversion */
400 *c = (isdigit(*qp_p) ? *qp_p - '0' : toupper(*qp_p) - 'A' + 10) << 4;
401 *c |= isdigit(qp_p[1]) ? qp_p[1] - '0' : toupper(qp_p[1]) - 'A' + 10;
402 return qp_p + 2;
403 }
404
405 /* Illegal char here */
406 *c = PDKIM_QP_ERROR_DECODE;
407 return initial_pos;
408 }
409
410
411 /* -------------------------------------------------------------------------- */
412
413 static uschar *
414 pdkim_decode_qp(const uschar * str)
415 {
416 int nchar = 0;
417 uschar * q;
418 const uschar * p = str;
419 uschar * n = store_get(Ustrlen(str)+1, TRUE);
420
421 *n = '\0';
422 q = n;
423 while (*p)
424 {
425 if (*p == '=')
426 {
427 p = pdkim_decode_qp_char(p, &nchar);
428 if (nchar >= 0)
429 {
430 *q++ = nchar;
431 continue;
432 }
433 }
434 else
435 *q++ = *p;
436 p++;
437 }
438 *q = '\0';
439 return n;
440 }
441
442
443 /* -------------------------------------------------------------------------- */
444
445 void
446 pdkim_decode_base64(const uschar * str, blob * b)
447 {
448 int dlen = b64decode(str, &b->data);
449 if (dlen < 0) b->data = NULL;
450 b->len = dlen;
451 }
452
453 uschar *
454 pdkim_encode_base64(blob * b)
455 {
456 return b64encode(CUS b->data, b->len);
457 }
458
459
460 /* -------------------------------------------------------------------------- */
461 #define PDKIM_HDR_LIMBO 0
462 #define PDKIM_HDR_TAG 1
463 #define PDKIM_HDR_VALUE 2
464
465 static pdkim_signature *
466 pdkim_parse_sig_header(pdkim_ctx * ctx, uschar * raw_hdr)
467 {
468 pdkim_signature * sig;
469 uschar *q;
470 gstring * cur_tag = NULL;
471 gstring * cur_val = NULL;
472 BOOL past_hname = FALSE;
473 BOOL in_b_val = FALSE;
474 int where = PDKIM_HDR_LIMBO;
475
476 sig = store_get(sizeof(pdkim_signature), FALSE);
477 memset(sig, 0, sizeof(pdkim_signature));
478 sig->bodylength = -1;
479
480 /* Set so invalid/missing data error display is accurate */
481 sig->version = 0;
482 sig->keytype = -1;
483 sig->hashtype = -1;
484
485 q = sig->rawsig_no_b_val = store_get(Ustrlen(raw_hdr)+1, TRUE); /* tainted */
486
487 for (uschar * p = raw_hdr; ; p++)
488 {
489 char c = *p;
490
491 /* Ignore FWS */
492 if (c == '\r' || c == '\n')
493 goto NEXT_CHAR;
494
495 /* Fast-forward through header name */
496 if (!past_hname)
497 {
498 if (c == ':') past_hname = TRUE;
499 goto NEXT_CHAR;
500 }
501
502 if (where == PDKIM_HDR_LIMBO)
503 {
504 /* In limbo, just wait for a tag-char to appear */
505 if (!(c >= 'a' && c <= 'z'))
506 goto NEXT_CHAR;
507
508 where = PDKIM_HDR_TAG;
509 }
510
511 if (where == PDKIM_HDR_TAG)
512 {
513 if (c >= 'a' && c <= 'z')
514 cur_tag = string_catn(cur_tag, p, 1);
515
516 if (c == '=')
517 {
518 if (Ustrcmp(string_from_gstring(cur_tag), "b") == 0)
519 {
520 *q++ = '=';
521 in_b_val = TRUE;
522 }
523 where = PDKIM_HDR_VALUE;
524 goto NEXT_CHAR;
525 }
526 }
527
528 if (where == PDKIM_HDR_VALUE)
529 {
530 if (c == '\r' || c == '\n' || c == ' ' || c == '\t')
531 goto NEXT_CHAR;
532
533 if (c == ';' || c == '\0')
534 {
535 /* We must have both tag and value, and tags must be one char except
536 for the possibility of "bh". */
537
538 if ( cur_tag && cur_val
539 && (cur_tag->ptr == 1 || *cur_tag->s == 'b')
540 )
541 {
542 (void) string_from_gstring(cur_val);
543 pdkim_strtrim(cur_val);
544
545 DEBUG(D_acl) debug_printf(" %s=%s\n", cur_tag->s, cur_val->s);
546
547 switch (*cur_tag->s)
548 {
549 case 'b': /* sig-data or body-hash */
550 switch (cur_tag->s[1])
551 {
552 case '\0': pdkim_decode_base64(cur_val->s, &sig->sighash); break;
553 case 'h': if (cur_tag->ptr == 2)
554 pdkim_decode_base64(cur_val->s, &sig->bodyhash);
555 break;
556 default: break;
557 }
558 break;
559 case 'v': /* version */
560 /* We only support version 1, and that is currently the
561 only version there is. */
562 sig->version =
563 Ustrcmp(cur_val->s, PDKIM_SIGNATURE_VERSION) == 0 ? 1 : -1;
564 break;
565 case 'a': /* algorithm */
566 {
567 const uschar * list = cur_val->s;
568 int sep = '-';
569 uschar * elem;
570
571 if ((elem = string_nextinlist(&list, &sep, NULL, 0)))
572 sig->keytype = pdkim_keyname_to_keytype(elem);
573 if ((elem = string_nextinlist(&list, &sep, NULL, 0)))
574 for (int i = 0; i < nelem(pdkim_hashes); i++)
575 if (Ustrcmp(elem, pdkim_hashes[i].dkim_hashname) == 0)
576 { sig->hashtype = i; break; }
577 }
578
579 case 'c': /* canonicalization */
580 pdkim_cstring_to_canons(cur_val->s, 0,
581 &sig->canon_headers, &sig->canon_body);
582 break;
583 case 'q': /* Query method (for pubkey)*/
584 for (int i = 0; pdkim_querymethods[i]; i++)
585 if (Ustrcmp(cur_val->s, pdkim_querymethods[i]) == 0)
586 {
587 sig->querymethod = i; /* we never actually use this */
588 break;
589 }
590 break;
591 case 's': /* Selector */
592 sig->selector = string_copyn(cur_val->s, cur_val->ptr); break;
593 case 'd': /* SDID */
594 sig->domain = string_copyn(cur_val->s, cur_val->ptr); break;
595 case 'i': /* AUID */
596 sig->identity = pdkim_decode_qp(cur_val->s); break;
597 case 't': /* Timestamp */
598 sig->created = strtoul(CS cur_val->s, NULL, 10); break;
599 case 'x': /* Expiration */
600 sig->expires = strtoul(CS cur_val->s, NULL, 10); break;
601 case 'l': /* Body length count */
602 sig->bodylength = strtol(CS cur_val->s, NULL, 10); break;
603 case 'h': /* signed header fields */
604 sig->headernames = string_copyn(cur_val->s, cur_val->ptr); break;
605 case 'z': /* Copied headfields */
606 sig->copiedheaders = pdkim_decode_qp(cur_val->s); break;
607 /*XXX draft-ietf-dcrup-dkim-crypto-05 would need 'p' tag support
608 for rsafp signatures. But later discussion is dropping those. */
609 default:
610 DEBUG(D_acl) debug_printf(" Unknown tag encountered\n");
611 break;
612 }
613 }
614 cur_tag = cur_val = NULL;
615 in_b_val = FALSE;
616 where = PDKIM_HDR_LIMBO;
617 }
618 else
619 cur_val = string_catn(cur_val, p, 1);
620 }
621
622 NEXT_CHAR:
623 if (c == '\0')
624 break;
625
626 if (!in_b_val)
627 *q++ = c;
628 }
629
630 if (sig->keytype < 0 || sig->hashtype < 0) /* Cannot verify this signature */
631 return NULL;
632
633 *q = '\0';
634 /* Chomp raw header. The final newline must not be added to the signature. */
635 while (--q > sig->rawsig_no_b_val && (*q == '\r' || *q == '\n'))
636 *q = '\0';
637
638 DEBUG(D_acl)
639 {
640 debug_printf(
641 "DKIM >> Raw signature w/o b= tag value >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
642 pdkim_quoteprint(US sig->rawsig_no_b_val, Ustrlen(sig->rawsig_no_b_val));
643 debug_printf(
644 "DKIM >> Sig size: %4u bits\n", (unsigned) sig->sighash.len*8);
645 debug_printf(
646 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
647 }
648
649 if (!pdkim_set_sig_bodyhash(ctx, sig))
650 return NULL;
651
652 return sig;
653 }
654
655
656 /* -------------------------------------------------------------------------- */
657
658 pdkim_pubkey *
659 pdkim_parse_pubkey_record(const uschar *raw_record)
660 {
661 const uschar * ele;
662 int sep = ';';
663 pdkim_pubkey * pub;
664
665 pub = store_get(sizeof(pdkim_pubkey), TRUE); /* tainted */
666 memset(pub, 0, sizeof(pdkim_pubkey));
667
668 while ((ele = string_nextinlist(&raw_record, &sep, NULL, 0)))
669 {
670 const uschar * val;
671
672 if ((val = Ustrchr(ele, '=')))
673 {
674 int taglen = val++ - ele;
675
676 DEBUG(D_acl) debug_printf(" %.*s=%s\n", taglen, ele, val);
677 switch (ele[0])
678 {
679 case 'v': pub->version = val; break;
680 case 'h': pub->hashes = val; break;
681 case 'k': pub->keytype = val; break;
682 case 'g': pub->granularity = val; break;
683 case 'n': pub->notes = pdkim_decode_qp(val); break;
684 case 'p': pdkim_decode_base64(val, &pub->key); break;
685 case 's': pub->srvtype = val; break;
686 case 't': if (Ustrchr(val, 'y')) pub->testing = 1;
687 if (Ustrchr(val, 's')) pub->no_subdomaining = 1;
688 break;
689 default: DEBUG(D_acl) debug_printf(" Unknown tag encountered\n"); break;
690 }
691 }
692 }
693
694 /* Set fallback defaults */
695 if (!pub->version)
696 pub->version = string_copy(PDKIM_PUB_RECORD_VERSION);
697 else if (Ustrcmp(pub->version, PDKIM_PUB_RECORD_VERSION) != 0)
698 {
699 DEBUG(D_acl) debug_printf(" Bad v= field\n");
700 return NULL;
701 }
702
703 if (!pub->granularity) pub->granularity = US"*";
704 if (!pub->keytype ) pub->keytype = US"rsa";
705 if (!pub->srvtype ) pub->srvtype = US"*";
706
707 /* p= is required */
708 if (pub->key.data)
709 return pub;
710
711 DEBUG(D_acl) debug_printf(" Missing p= field\n");
712 return NULL;
713 }
714
715
716 /* -------------------------------------------------------------------------- */
717
718 /* Update one bodyhash with some additional data.
719 If we have to relax the data for this sig, return our copy of it. */
720
721 static blob *
722 pdkim_update_ctx_bodyhash(pdkim_bodyhash * b, blob * orig_data, blob * relaxed_data)
723 {
724 blob * canon_data = orig_data;
725 /* Defaults to simple canon (no further treatment necessary) */
726
727 if (b->canon_method == PDKIM_CANON_RELAXED)
728 {
729 /* Relax the line if not done already */
730 if (!relaxed_data)
731 {
732 BOOL seen_wsp = FALSE;
733 int q = 0;
734
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(). */
739
740 relaxed_data = store_malloc(sizeof(blob) + orig_data->len+1);
741 relaxed_data->data = US (relaxed_data+1);
742
743 for (const uschar * p = orig_data->data, * r = p + orig_data->len; p < r; p++)
744 {
745 char c = *p;
746 if (c == '\r')
747 {
748 if (q > 0 && relaxed_data->data[q-1] == ' ')
749 q--;
750 }
751 else if (c == '\t' || c == ' ')
752 {
753 c = ' '; /* Turns WSP into SP */
754 if (seen_wsp)
755 continue;
756 seen_wsp = TRUE;
757 }
758 else
759 seen_wsp = FALSE;
760 relaxed_data->data[q++] = c;
761 }
762 relaxed_data->data[q] = '\0';
763 relaxed_data->len = q;
764 }
765 canon_data = relaxed_data;
766 }
767
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
771 )
772 canon_data->len = b->bodylength - b->signed_body_bytes;
773
774 if (canon_data->len > 0)
775 {
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);
779 }
780
781 return relaxed_data;
782 }
783
784
785 /* -------------------------------------------------------------------------- */
786
787 static void
788 pdkim_finish_bodyhash(pdkim_ctx * ctx)
789 {
790 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next) /* Finish hashes */
791 {
792 DEBUG(D_acl) debug_printf("DKIM: finish bodyhash %d/%d/%ld len %ld\n",
793 b->hashtype, b->canon_method, b->bodylength, b->signed_body_bytes);
794 exim_sha_finish(&b->body_hash_ctx, &b->bh);
795 }
796
797 /* Traverse all signatures */
798 for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next)
799 {
800 pdkim_bodyhash * b = sig->calc_body_hash;
801
802 DEBUG(D_acl)
803 {
804 debug_printf("DKIM [%s] Body bytes (%s) hashed: %lu\n"
805 "DKIM [%s] Body %s computed: ",
806 sig->domain, pdkim_canons[b->canon_method], b->signed_body_bytes,
807 sig->domain, pdkim_hashes[b->hashtype].dkim_hashname);
808 pdkim_hexprint(CUS b->bh.data, b->bh.len);
809 }
810
811 /* SIGNING -------------------------------------------------------------- */
812 if (ctx->flags & PDKIM_MODE_SIGN)
813 {
814 /* If bodylength limit is set, and we have received less bytes
815 than the requested amount, effectively remove the limit tag. */
816 if (b->signed_body_bytes < sig->bodylength)
817 sig->bodylength = -1;
818 }
819
820 else
821 /* VERIFICATION --------------------------------------------------------- */
822 /* Be careful that the header sig included a bodyash */
823
824 if ( sig->bodyhash.data
825 && memcmp(b->bh.data, sig->bodyhash.data, b->bh.len) == 0)
826 {
827 DEBUG(D_acl) debug_printf("DKIM [%s] Body hash compared OK\n", sig->domain);
828 }
829 else
830 {
831 DEBUG(D_acl)
832 {
833 debug_printf("DKIM [%s] Body hash signature from headers: ", sig->domain);
834 pdkim_hexprint(sig->bodyhash.data, sig->bodyhash.len);
835 debug_printf("DKIM [%s] Body hash did NOT verify\n", sig->domain);
836 }
837 sig->verify_status = PDKIM_VERIFY_FAIL;
838 sig->verify_ext_status = PDKIM_VERIFY_FAIL_BODY;
839 }
840 }
841 }
842
843
844
845 static void
846 pdkim_body_complete(pdkim_ctx * ctx)
847 {
848 /* In simple body mode, if any empty lines were buffered,
849 replace with one. rfc 4871 3.4.3 */
850 /*XXX checking the signed-body-bytes is a gross hack; I think
851 it indicates that all linebreaks should be buffered, including
852 the one terminating a text line */
853
854 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
855 if ( b->canon_method == PDKIM_CANON_SIMPLE
856 && b->signed_body_bytes == 0
857 && b->num_buffered_blanklines > 0
858 )
859 (void) pdkim_update_ctx_bodyhash(b, &lineending, NULL);
860
861 ctx->flags |= PDKIM_SEEN_EOD;
862 ctx->linebuf_offset = 0;
863 }
864
865
866
867 /* -------------------------------------------------------------------------- */
868 /* Call from pdkim_feed below for processing complete body lines */
869 /* NOTE: the line is not NUL-terminated; but we have a count */
870
871 static void
872 pdkim_bodyline_complete(pdkim_ctx * ctx)
873 {
874 blob line = {.data = ctx->linebuf, .len = ctx->linebuf_offset};
875 blob * rnl = NULL;
876 blob * rline = NULL;
877
878 /* Ignore extra data if we've seen the end-of-data marker */
879 if (ctx->flags & PDKIM_SEEN_EOD) goto all_skip;
880
881 /* We've always got one extra byte to stuff a zero ... */
882 ctx->linebuf[line.len] = '\0';
883
884 /* Terminate on EOD marker */
885 if (ctx->flags & PDKIM_DOT_TERM)
886 {
887 if (memcmp(line.data, ".\r\n", 3) == 0)
888 { pdkim_body_complete(ctx); return; }
889
890 /* Unstuff dots */
891 if (memcmp(line.data, "..", 2) == 0)
892 { line.data++; line.len--; }
893 }
894
895 /* Empty lines need to be buffered until we find a non-empty line */
896 if (memcmp(line.data, "\r\n", 2) == 0)
897 {
898 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
899 b->num_buffered_blanklines++;
900 goto all_skip;
901 }
902
903 /* Process line for each bodyhash separately */
904 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
905 {
906 if (b->canon_method == PDKIM_CANON_RELAXED)
907 {
908 /* Lines with just spaces need to be buffered too */
909 uschar * cp = line.data;
910 char c;
911
912 while ((c = *cp))
913 {
914 if (c == '\r' && cp[1] == '\n') break;
915 if (c != ' ' && c != '\t') goto hash_process;
916 cp++;
917 }
918
919 b->num_buffered_blanklines++;
920 goto hash_skip;
921 }
922
923 hash_process:
924 /* At this point, we have a non-empty line, so release the buffered ones. */
925
926 while (b->num_buffered_blanklines)
927 {
928 rnl = pdkim_update_ctx_bodyhash(b, &lineending, rnl);
929 b->num_buffered_blanklines--;
930 }
931
932 rline = pdkim_update_ctx_bodyhash(b, &line, rline);
933 hash_skip: ;
934 }
935
936 if (rnl) store_free(rnl);
937 if (rline) store_free(rline);
938
939 all_skip:
940
941 ctx->linebuf_offset = 0;
942 return;
943 }
944
945
946 /* -------------------------------------------------------------------------- */
947 /* Callback from pdkim_feed below for processing complete headers */
948 #define DKIM_SIGNATURE_HEADERNAME "DKIM-Signature:"
949
950 static int
951 pdkim_header_complete(pdkim_ctx * ctx)
952 {
953 if ( (ctx->cur_header->ptr > 1) &&
954 (ctx->cur_header->s[ctx->cur_header->ptr-1] == '\r') )
955 --ctx->cur_header->ptr;
956 (void) string_from_gstring(ctx->cur_header);
957
958 #ifdef EXPERIMENTAL_ARC
959 /* Feed the header line to ARC processing */
960 (void) arc_header_feed(ctx->cur_header, !(ctx->flags & PDKIM_MODE_SIGN));
961 #endif
962
963 if (++ctx->num_headers > PDKIM_MAX_HEADERS) goto BAIL;
964
965 /* SIGNING -------------------------------------------------------------- */
966 if (ctx->flags & PDKIM_MODE_SIGN)
967 for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) /* Traverse all signatures */
968
969 /* Add header to the signed headers list (in reverse order) */
970 sig->headers = pdkim_prepend_stringlist(sig->headers, ctx->cur_header->s);
971
972 /* VERIFICATION ----------------------------------------------------------- */
973 /* DKIM-Signature: headers are added to the verification list */
974 else
975 {
976 #ifdef notdef
977 DEBUG(D_acl)
978 {
979 debug_printf("DKIM >> raw hdr: ");
980 pdkim_quoteprint(CUS ctx->cur_header->s, ctx->cur_header->ptr);
981 }
982 #endif
983 if (strncasecmp(CCS ctx->cur_header->s,
984 DKIM_SIGNATURE_HEADERNAME,
985 Ustrlen(DKIM_SIGNATURE_HEADERNAME)) == 0)
986 {
987 pdkim_signature * sig, * last_sig;
988 /* Create and chain new signature block. We could error-check for all
989 required tags here, but prefer to create the internal sig and expicitly
990 fail verification of it later. */
991
992 DEBUG(D_acl) debug_printf(
993 "DKIM >> Found sig, trying to parse >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
994
995 sig = pdkim_parse_sig_header(ctx, ctx->cur_header->s);
996
997 if (!(last_sig = ctx->sig))
998 ctx->sig = sig;
999 else
1000 {
1001 while (last_sig->next) last_sig = last_sig->next;
1002 last_sig->next = sig;
1003 }
1004
1005 if (--dkim_collect_input == 0)
1006 {
1007 ctx->headers = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->s);
1008 ctx->cur_header->s[ctx->cur_header->ptr = 0] = '\0';
1009 return PDKIM_ERR_EXCESS_SIGS;
1010 }
1011 }
1012
1013 /* all headers are stored for signature verification */
1014 ctx->headers = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->s);
1015 }
1016
1017 BAIL:
1018 ctx->cur_header->s[ctx->cur_header->ptr = 0] = '\0'; /* leave buffer for reuse */
1019 return PDKIM_OK;
1020 }
1021
1022
1023
1024 /* -------------------------------------------------------------------------- */
1025 #define HEADER_BUFFER_FRAG_SIZE 256
1026
1027 DLLEXPORT int
1028 pdkim_feed(pdkim_ctx * ctx, uschar * data, int len)
1029 {
1030 /* Alternate EOD signal, used in non-dotstuffing mode */
1031 if (!data)
1032 pdkim_body_complete(ctx);
1033
1034 else for (int p = 0; p < len; p++)
1035 {
1036 uschar c = data[p];
1037 int rc;
1038
1039 if (ctx->flags & PDKIM_PAST_HDRS)
1040 {
1041 if (c == '\n' && !(ctx->flags & PDKIM_SEEN_CR)) /* emulate the CR */
1042 {
1043 ctx->linebuf[ctx->linebuf_offset++] = '\r';
1044 if (ctx->linebuf_offset == PDKIM_MAX_BODY_LINE_LEN-1)
1045 return PDKIM_ERR_LONG_LINE;
1046 }
1047
1048 /* Processing body byte */
1049 ctx->linebuf[ctx->linebuf_offset++] = c;
1050 if (c == '\r')
1051 ctx->flags |= PDKIM_SEEN_CR;
1052 else if (c == '\n')
1053 {
1054 ctx->flags &= ~PDKIM_SEEN_CR;
1055 pdkim_bodyline_complete(ctx);
1056 }
1057
1058 if (ctx->linebuf_offset == PDKIM_MAX_BODY_LINE_LEN-1)
1059 return PDKIM_ERR_LONG_LINE;
1060 }
1061 else
1062 {
1063 /* Processing header byte */
1064 if (c == '\r')
1065 ctx->flags |= PDKIM_SEEN_CR;
1066 else if (c == '\n')
1067 {
1068 if (!(ctx->flags & PDKIM_SEEN_CR)) /* emulate the CR */
1069 ctx->cur_header = string_catn(ctx->cur_header, CUS "\r", 1);
1070
1071 if (ctx->flags & PDKIM_SEEN_LF) /* Seen last header line */
1072 {
1073 if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1074 return rc;
1075
1076 ctx->flags = (ctx->flags & ~(PDKIM_SEEN_LF|PDKIM_SEEN_CR)) | PDKIM_PAST_HDRS;
1077 DEBUG(D_acl) debug_printf(
1078 "DKIM >> Body data for hash, canonicalized >>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1079 continue;
1080 }
1081 else
1082 ctx->flags = (ctx->flags & ~PDKIM_SEEN_CR) | PDKIM_SEEN_LF;
1083 }
1084 else if (ctx->flags & PDKIM_SEEN_LF)
1085 {
1086 if (!(c == '\t' || c == ' ')) /* End of header */
1087 if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1088 return rc;
1089 ctx->flags &= ~PDKIM_SEEN_LF;
1090 }
1091
1092 if (!ctx->cur_header || ctx->cur_header->ptr < PDKIM_MAX_HEADER_LEN)
1093 ctx->cur_header = string_catn(ctx->cur_header, CUS &data[p], 1);
1094 }
1095 }
1096 return PDKIM_OK;
1097 }
1098
1099
1100
1101 /* Extend a growing header with a continuation-linebreak */
1102 static gstring *
1103 pdkim_hdr_cont(gstring * str, int * col)
1104 {
1105 *col = 1;
1106 return string_catn(str, US"\r\n\t", 3);
1107 }
1108
1109
1110
1111 /*
1112 * RFC 5322 specifies that header line length SHOULD be no more than 78
1113 * lets make it so!
1114 * pdkim_headcat
1115 *
1116 * returns uschar * (not nul-terminated)
1117 *
1118 * col: this int holds and receives column number (octets since last '\n')
1119 * str: partial string to append to
1120 * pad: padding, split line or space after before or after eg: ";"
1121 * intro: - must join to payload eg "h=", usually the tag name
1122 * payload: eg base64 data - long data can be split arbitrarily.
1123 *
1124 * this code doesn't fold the header in some of the places that RFC4871
1125 * allows: As per RFC5322(2.2.3) it only folds before or after tag-value
1126 * pairs and inside long values. it also always spaces or breaks after the
1127 * "pad"
1128 *
1129 * no guarantees are made for output given out-of range input. like tag
1130 * names longer than 78, or bogus col. Input is assumed to be free of line breaks.
1131 */
1132
1133 static gstring *
1134 pdkim_headcat(int * col, gstring * str,
1135 const uschar * pad, const uschar * intro, const uschar * payload)
1136 {
1137 size_t l;
1138
1139 if (pad)
1140 {
1141 l = Ustrlen(pad);
1142 if (*col + l > 78)
1143 str = pdkim_hdr_cont(str, col);
1144 str = string_catn(str, pad, l);
1145 *col += l;
1146 }
1147
1148 l = (pad?1:0) + (intro?Ustrlen(intro):0);
1149
1150 if (*col + l > 78)
1151 { /*can't fit intro - start a new line to make room.*/
1152 str = pdkim_hdr_cont(str, col);
1153 l = intro?Ustrlen(intro):0;
1154 }
1155
1156 l += payload ? Ustrlen(payload):0 ;
1157
1158 while (l>77)
1159 { /* this fragment will not fit on a single line */
1160 if (pad)
1161 {
1162 str = string_catn(str, US" ", 1);
1163 *col += 1;
1164 pad = NULL; /* only want this once */
1165 l--;
1166 }
1167
1168 if (intro)
1169 {
1170 size_t sl = Ustrlen(intro);
1171
1172 str = string_catn(str, intro, sl);
1173 *col += sl;
1174 l -= sl;
1175 intro = NULL; /* only want this once */
1176 }
1177
1178 if (payload)
1179 {
1180 size_t sl = Ustrlen(payload);
1181 size_t chomp = *col+sl < 77 ? sl : 78-*col;
1182
1183 str = string_catn(str, payload, chomp);
1184 *col += chomp;
1185 payload += chomp;
1186 l -= chomp-1;
1187 }
1188
1189 /* the while precondition tells us it didn't fit. */
1190 str = pdkim_hdr_cont(str, col);
1191 }
1192
1193 if (*col + l > 78)
1194 {
1195 str = pdkim_hdr_cont(str, col);
1196 pad = NULL;
1197 }
1198
1199 if (pad)
1200 {
1201 str = string_catn(str, US" ", 1);
1202 *col += 1;
1203 pad = NULL;
1204 }
1205
1206 if (intro)
1207 {
1208 size_t sl = Ustrlen(intro);
1209
1210 str = string_catn(str, intro, sl);
1211 *col += sl;
1212 l -= sl;
1213 intro = NULL;
1214 }
1215
1216 if (payload)
1217 {
1218 size_t sl = Ustrlen(payload);
1219
1220 str = string_catn(str, payload, sl);
1221 *col += sl;
1222 }
1223
1224 return str;
1225 }
1226
1227
1228 /* -------------------------------------------------------------------------- */
1229
1230 /* Signing: create signature header
1231 */
1232 static uschar *
1233 pdkim_create_header(pdkim_signature * sig, BOOL final)
1234 {
1235 uschar * base64_bh;
1236 uschar * base64_b;
1237 int col = 0;
1238 gstring * hdr;
1239 gstring * canon_all;
1240
1241 canon_all = string_cat (NULL, pdkim_canons[sig->canon_headers]);
1242 canon_all = string_catn(canon_all, US"/", 1);
1243 canon_all = string_cat (canon_all, pdkim_canons[sig->canon_body]);
1244 (void) string_from_gstring(canon_all);
1245
1246 hdr = string_cat(NULL, US"DKIM-Signature: v="PDKIM_SIGNATURE_VERSION);
1247 col = hdr->ptr;
1248
1249 /* Required and static bits */
1250 hdr = pdkim_headcat(&col, hdr, US";", US"a=", dkim_sig_to_a_tag(sig));
1251 hdr = pdkim_headcat(&col, hdr, US";", US"q=", pdkim_querymethods[sig->querymethod]);
1252 hdr = pdkim_headcat(&col, hdr, US";", US"c=", canon_all->s);
1253 hdr = pdkim_headcat(&col, hdr, US";", US"d=", sig->domain);
1254 hdr = pdkim_headcat(&col, hdr, US";", US"s=", sig->selector);
1255
1256 /* list of header names can be split between items. */
1257 {
1258 uschar * n = string_copy(sig->headernames);
1259 uschar * i = US"h=";
1260 uschar * s = US";";
1261
1262 while (*n)
1263 {
1264 uschar * c = Ustrchr(n, ':');
1265
1266 if (c) *c ='\0';
1267
1268 if (!i)
1269 hdr = pdkim_headcat(&col, hdr, NULL, NULL, US":");
1270
1271 hdr = pdkim_headcat(&col, hdr, s, i, n);
1272
1273 if (!c)
1274 break;
1275
1276 n = c+1;
1277 s = NULL;
1278 i = NULL;
1279 }
1280 }
1281
1282 base64_bh = pdkim_encode_base64(&sig->calc_body_hash->bh);
1283 hdr = pdkim_headcat(&col, hdr, US";", US"bh=", base64_bh);
1284
1285 /* Optional bits */
1286 if (sig->identity)
1287 hdr = pdkim_headcat(&col, hdr, US";", US"i=", sig->identity);
1288
1289 if (sig->created > 0)
1290 {
1291 uschar minibuf[20];
1292
1293 snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->created);
1294 hdr = pdkim_headcat(&col, hdr, US";", US"t=", minibuf);
1295 }
1296
1297 if (sig->expires > 0)
1298 {
1299 uschar minibuf[20];
1300
1301 snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->expires);
1302 hdr = pdkim_headcat(&col, hdr, US";", US"x=", minibuf);
1303 }
1304
1305 if (sig->bodylength >= 0)
1306 {
1307 uschar minibuf[20];
1308
1309 snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->bodylength);
1310 hdr = pdkim_headcat(&col, hdr, US";", US"l=", minibuf);
1311 }
1312
1313 /* Preliminary or final version? */
1314 if (final)
1315 {
1316 base64_b = pdkim_encode_base64(&sig->sighash);
1317 hdr = pdkim_headcat(&col, hdr, US";", US"b=", base64_b);
1318
1319 /* add trailing semicolon: I'm not sure if this is actually needed */
1320 hdr = pdkim_headcat(&col, hdr, NULL, US";", US"");
1321 }
1322 else
1323 {
1324 /* To satisfy the rule "all surrounding whitespace [...] deleted"
1325 ( RFC 6376 section 3.7 ) we ensure there is no whitespace here. Otherwise
1326 the headcat routine could insert a linebreak which the relaxer would reduce
1327 to a single space preceding the terminating semicolon, resulting in an
1328 incorrect header-hash. */
1329 hdr = pdkim_headcat(&col, hdr, US";", US"b=;", US"");
1330 }
1331
1332 return string_from_gstring(hdr);
1333 }
1334
1335
1336 /* -------------------------------------------------------------------------- */
1337
1338 /* According to draft-ietf-dcrup-dkim-crypto-07 "keys are 256 bits" (referring
1339 to DNS, hence the pubkey). Check for more than 32 bytes; if so assume the
1340 alternate possible representation (still) being discussed: a
1341 SubjectPublickeyInfo wrapped key - and drop all but the trailing 32-bytes (it
1342 should be a DER, with exactly 12 leading bytes - but we could accept a BER also,
1343 which could be any size). We still rely on the crypto library for checking for
1344 undersize.
1345
1346 When the RFC is published this should be re-addressed. */
1347
1348 static void
1349 check_bare_ed25519_pubkey(pdkim_pubkey * p)
1350 {
1351 int excess = p->key.len - 32;
1352 if (excess > 0)
1353 {
1354 DEBUG(D_acl) debug_printf("DKIM: unexpected pubkey len %lu\n", p->key.len);
1355 p->key.data += excess; p->key.len = 32;
1356 }
1357 }
1358
1359
1360 static pdkim_pubkey *
1361 pdkim_key_from_dns(pdkim_ctx * ctx, pdkim_signature * sig, ev_ctx * vctx,
1362 const uschar ** errstr)
1363 {
1364 uschar * dns_txt_name, * dns_txt_reply;
1365 pdkim_pubkey * p;
1366
1367 /* Fetch public key for signing domain, from DNS */
1368
1369 dns_txt_name = string_sprintf("%s._domainkey.%s.", sig->selector, sig->domain);
1370
1371 if ( !(dns_txt_reply = ctx->dns_txt_callback(dns_txt_name))
1372 || dns_txt_reply[0] == '\0'
1373 )
1374 {
1375 sig->verify_status = PDKIM_VERIFY_INVALID;
1376 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE;
1377 return NULL;
1378 }
1379
1380 DEBUG(D_acl)
1381 {
1382 debug_printf(
1383 "DKIM >> Parsing public key record >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"
1384 " %s\n"
1385 " Raw record: ",
1386 dns_txt_name);
1387 pdkim_quoteprint(CUS dns_txt_reply, Ustrlen(dns_txt_reply));
1388 }
1389
1390 if ( !(p = pdkim_parse_pubkey_record(CUS dns_txt_reply))
1391 || (Ustrcmp(p->srvtype, "*") != 0 && Ustrcmp(p->srvtype, "email") != 0)
1392 )
1393 {
1394 sig->verify_status = PDKIM_VERIFY_INVALID;
1395 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD;
1396
1397 DEBUG(D_acl)
1398 {
1399 if (p)
1400 debug_printf(" Invalid public key service type '%s'\n", p->srvtype);
1401 else
1402 debug_printf(" Error while parsing public key record\n");
1403 debug_printf(
1404 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1405 }
1406 return NULL;
1407 }
1408
1409 DEBUG(D_acl) debug_printf(
1410 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1411
1412 /* Import public key */
1413
1414 /* Normally we use the signature a= tag to tell us the pubkey format.
1415 When signing under debug we do a test-import of the pubkey, and at that
1416 time we do not have a signature so we must interpret the pubkey k= tag
1417 instead. Assume writing on the sig is ok in that case. */
1418
1419 if (sig->keytype < 0)
1420 if ((sig->keytype = pdkim_keyname_to_keytype(p->keytype)) < 0)
1421 {
1422 DEBUG(D_acl) debug_printf("verify_init: unhandled keytype %s\n", p->keytype);
1423 sig->verify_status = PDKIM_VERIFY_INVALID;
1424 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
1425 return NULL;
1426 }
1427
1428 if (sig->keytype == KEYTYPE_ED25519)
1429 check_bare_ed25519_pubkey(p);
1430
1431 if ((*errstr = exim_dkim_verify_init(&p->key,
1432 sig->keytype == KEYTYPE_ED25519 ? KEYFMT_ED25519_BARE : KEYFMT_DER,
1433 vctx)))
1434 {
1435 DEBUG(D_acl) debug_printf("verify_init: %s\n", *errstr);
1436 sig->verify_status = PDKIM_VERIFY_INVALID;
1437 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
1438 return NULL;
1439 }
1440
1441 vctx->keytype = sig->keytype;
1442 return p;
1443 }
1444
1445
1446 /* -------------------------------------------------------------------------- */
1447 /* Sort and filter the sigs developed from the message */
1448
1449 static pdkim_signature *
1450 sort_sig_methods(pdkim_signature * siglist)
1451 {
1452 pdkim_signature * yield, ** ss;
1453 const uschar * prefs;
1454 uschar * ele;
1455 int sep;
1456
1457 if (!siglist) return NULL;
1458
1459 /* first select in order of hashtypes */
1460 DEBUG(D_acl) debug_printf("DKIM: dkim_verify_hashes '%s'\n", dkim_verify_hashes);
1461 for (prefs = dkim_verify_hashes, sep = 0, yield = NULL, ss = &yield;
1462 ele = string_nextinlist(&prefs, &sep, NULL, 0); )
1463 {
1464 int i = pdkim_hashname_to_hashtype(CUS ele, 0);
1465 for (pdkim_signature * s = siglist, * next, ** prev = &siglist; s;
1466 s = next)
1467 {
1468 next = s->next;
1469 if (s->hashtype == i)
1470 { *prev = next; s->next = NULL; *ss = s; ss = &s->next; }
1471 else
1472 prev = &s->next;
1473 }
1474 }
1475
1476 /* then in order of keytypes */
1477 siglist = yield;
1478 DEBUG(D_acl) debug_printf("DKIM: dkim_verify_keytypes '%s'\n", dkim_verify_keytypes);
1479 for (prefs = dkim_verify_keytypes, sep = 0, yield = NULL, ss = &yield;
1480 ele = string_nextinlist(&prefs, &sep, NULL, 0); )
1481 {
1482 int i = pdkim_keyname_to_keytype(CUS ele);
1483 for (pdkim_signature * s = siglist, * next, ** prev = &siglist; s;
1484 s = next)
1485 {
1486 next = s->next;
1487 if (s->keytype == i)
1488 { *prev = next; s->next = NULL; *ss = s; ss = &s->next; }
1489 else
1490 prev = &s->next;
1491 }
1492 }
1493
1494 DEBUG(D_acl) for (pdkim_signature * s = yield; s; s = s->next)
1495 debug_printf(" retain d=%s s=%s a=%s\n",
1496 s->domain, s->selector, dkim_sig_to_a_tag(s));
1497 return yield;
1498 }
1499
1500
1501 /* -------------------------------------------------------------------------- */
1502
1503 DLLEXPORT int
1504 pdkim_feed_finish(pdkim_ctx * ctx, pdkim_signature ** return_signatures,
1505 const uschar ** err)
1506 {
1507 BOOL verify_pass = FALSE;
1508
1509 /* Check if we must still flush a (partial) header. If that is the
1510 case, the message has no body, and we must compute a body hash
1511 out of '<CR><LF>' */
1512 if (ctx->cur_header && ctx->cur_header->ptr > 0)
1513 {
1514 blob * rnl = NULL;
1515 int rc;
1516
1517 if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1518 return rc;
1519
1520 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
1521 rnl = pdkim_update_ctx_bodyhash(b, &lineending, rnl);
1522 if (rnl) store_free(rnl);
1523 }
1524 else
1525 DEBUG(D_acl) debug_printf(
1526 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1527
1528 /* Build (and/or evaluate) body hash. Do this even if no DKIM sigs, in case we
1529 have a hash to do for ARC. */
1530
1531 pdkim_finish_bodyhash(ctx);
1532
1533 /* Sort and filter the recived signatures */
1534
1535 if (!(ctx->flags & PDKIM_MODE_SIGN))
1536 ctx->sig = sort_sig_methods(ctx->sig);
1537
1538 if (!ctx->sig)
1539 {
1540 DEBUG(D_acl) debug_printf("DKIM: no signatures\n");
1541 *return_signatures = NULL;
1542 return PDKIM_OK;
1543 }
1544
1545 for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next)
1546 {
1547 hctx hhash_ctx;
1548 uschar * sig_hdr = US"";
1549 blob hhash;
1550 gstring * hdata = NULL;
1551 es_ctx sctx;
1552
1553 if ( !(ctx->flags & PDKIM_MODE_SIGN)
1554 && sig->verify_status == PDKIM_VERIFY_FAIL)
1555 {
1556 DEBUG(D_acl)
1557 debug_printf("DKIM: [%s] abandoning this signature\n", sig->domain);
1558 continue;
1559 }
1560
1561 /*XXX The hash of the headers is needed for GCrypt (for which we can do RSA
1562 signing only, as it happens) and for either GnuTLS and OpenSSL when we are
1563 signing with EC (specifically, Ed25519). The former is because the GCrypt
1564 signing operation is pure (does not do its own hash) so we must hash. The
1565 latter is because we (stupidly, but this is what the IETF draft is saying)
1566 must hash with the declared hash method, then pass the result to the library
1567 hash-and-sign routine (because that's all the libraries are providing. And
1568 we're stuck with whatever that hidden hash method is, too). We may as well
1569 do this hash incrementally.
1570 We don't need the hash we're calculating here for the GnuTLS and OpenSSL
1571 cases of RSA signing, since those library routines can do hash-and-sign.
1572
1573 Some time in the future we could easily avoid doing the hash here for those
1574 cases (which will be common for a long while. We could also change from
1575 the current copy-all-the-headers-into-one-block, then call the hash-and-sign
1576 implementation - to a proper incremental one. Unfortunately, GnuTLS just
1577 cannot do incremental - either signing or verification. Unsure about GCrypt.
1578 */
1579
1580 /*XXX The header hash is also used (so far) by the verify operation */
1581
1582 if (!exim_sha_init(&hhash_ctx, pdkim_hashes[sig->hashtype].exim_hashmethod))
1583 {
1584 log_write(0, LOG_MAIN|LOG_PANIC,
1585 "DKIM: hash setup error, possibly nonhandled hashtype");
1586 break;
1587 }
1588
1589 if (ctx->flags & PDKIM_MODE_SIGN)
1590 DEBUG(D_acl) debug_printf(
1591 "DKIM >> Headers to be signed: >>>>>>>>>>>>\n"
1592 " %s\n",
1593 sig->sign_headers);
1594
1595 DEBUG(D_acl) debug_printf(
1596 "DKIM >> Header data for hash, canonicalized (%-7s), in sequence >>\n",
1597 pdkim_canons[sig->canon_headers]);
1598
1599
1600 /* SIGNING ---------------------------------------------------------------- */
1601 /* When signing, walk through our header list and add them to the hash. As we
1602 go, construct a list of the header's names to use for the h= parameter.
1603 Then append to that list any remaining header names for which there was no
1604 header to sign. */
1605
1606 if (ctx->flags & PDKIM_MODE_SIGN)
1607 {
1608 gstring * g = NULL;
1609 const uschar * l;
1610 uschar * s;
1611 int sep = 0;
1612
1613 /* Import private key, including the keytype which we need for building
1614 the signature header */
1615
1616 if ((*err = exim_dkim_signing_init(CUS sig->privkey, &sctx)))
1617 {
1618 log_write(0, LOG_MAIN|LOG_PANIC, "signing_init: %s", *err);
1619 return PDKIM_ERR_RSA_PRIVKEY;
1620 }
1621 sig->keytype = sctx.keytype;
1622
1623 sig->headernames = NULL; /* Collected signed header names */
1624 for (pdkim_stringlist * p = sig->headers; p; p = p->next)
1625 {
1626 uschar * rh = p->value;
1627
1628 if (header_name_match(rh, sig->sign_headers) == PDKIM_OK)
1629 {
1630 /* Collect header names (Note: colon presence is guaranteed here) */
1631 g = string_append_listele_n(g, ':', rh, Ustrchr(rh, ':') - rh);
1632
1633 if (sig->canon_headers == PDKIM_CANON_RELAXED)
1634 rh = pdkim_relax_header(rh, TRUE); /* cook header for relaxed canon */
1635
1636 /* Feed header to the hash algorithm */
1637 exim_sha_update(&hhash_ctx, CUS rh, Ustrlen(rh));
1638
1639 /* Remember headers block for signing (when the library cannot do incremental) */
1640 /*XXX we could avoid doing this for all but the GnuTLS/RSA case */
1641 hdata = exim_dkim_data_append(hdata, rh);
1642
1643 DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1644 }
1645 }
1646
1647 /* Any headers we wanted to sign but were not present must also be listed.
1648 Ignore elements that have been ticked-off or are marked as never-oversign. */
1649
1650 l = sig->sign_headers;
1651 while((s = string_nextinlist(&l, &sep, NULL, 0)))
1652 {
1653 if (*s == '+') /* skip oversigning marker */
1654 s++;
1655 if (*s != '_' && *s != '=')
1656 g = string_append_listele(g, ':', s);
1657 }
1658 sig->headernames = string_from_gstring(g);
1659
1660 /* Create signature header with b= omitted */
1661 sig_hdr = pdkim_create_header(sig, FALSE);
1662 }
1663
1664 /* VERIFICATION ----------------------------------------------------------- */
1665 /* When verifying, walk through the header name list in the h= parameter and
1666 add the headers to the hash in that order. */
1667 else
1668 {
1669 uschar * p = sig->headernames;
1670 uschar * q;
1671
1672 if (p)
1673 {
1674 /* clear tags */
1675 for (pdkim_stringlist * hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1676 hdrs->tag = 0;
1677
1678 p = string_copy(p);
1679 while(1)
1680 {
1681 if ((q = Ustrchr(p, ':')))
1682 *q = '\0';
1683
1684 /*XXX walk the list of headers in same order as received. */
1685 for (pdkim_stringlist * hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1686 if ( hdrs->tag == 0
1687 && strncasecmp(CCS hdrs->value, CCS p, Ustrlen(p)) == 0
1688 && (hdrs->value)[Ustrlen(p)] == ':'
1689 )
1690 {
1691 /* cook header for relaxed canon, or just copy it for simple */
1692
1693 uschar * rh = sig->canon_headers == PDKIM_CANON_RELAXED
1694 ? pdkim_relax_header(hdrs->value, TRUE)
1695 : string_copy(CUS hdrs->value);
1696
1697 /* Feed header to the hash algorithm */
1698 exim_sha_update(&hhash_ctx, CUS rh, Ustrlen(rh));
1699
1700 DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1701 hdrs->tag = 1;
1702 break;
1703 }
1704
1705 if (!q) break;
1706 p = q+1;
1707 }
1708
1709 sig_hdr = string_copy(sig->rawsig_no_b_val);
1710 }
1711 }
1712
1713 DEBUG(D_acl) debug_printf(
1714 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1715
1716 DEBUG(D_acl)
1717 {
1718 debug_printf(
1719 "DKIM >> Signed DKIM-Signature header, pre-canonicalized >>>>>>>>>>>>>\n");
1720 pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr));
1721 debug_printf(
1722 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1723 }
1724
1725 /* Relax header if necessary */
1726 if (sig->canon_headers == PDKIM_CANON_RELAXED)
1727 sig_hdr = pdkim_relax_header(sig_hdr, FALSE);
1728
1729 DEBUG(D_acl)
1730 {
1731 debug_printf("DKIM >> Signed DKIM-Signature header, canonicalized (%-7s) >>>>>>>\n",
1732 pdkim_canons[sig->canon_headers]);
1733 pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr));
1734 debug_printf(
1735 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1736 }
1737
1738 /* Finalize header hash */
1739 exim_sha_update(&hhash_ctx, CUS sig_hdr, Ustrlen(sig_hdr));
1740 exim_sha_finish(&hhash_ctx, &hhash);
1741
1742 DEBUG(D_acl)
1743 {
1744 debug_printf("DKIM [%s] Header %s computed: ",
1745 sig->domain, pdkim_hashes[sig->hashtype].dkim_hashname);
1746 pdkim_hexprint(hhash.data, hhash.len);
1747 }
1748
1749 /* Remember headers block for signing (when the signing library cannot do
1750 incremental) */
1751 if (ctx->flags & PDKIM_MODE_SIGN)
1752 hdata = exim_dkim_data_append(hdata, US sig_hdr);
1753
1754 /* SIGNING ---------------------------------------------------------------- */
1755 if (ctx->flags & PDKIM_MODE_SIGN)
1756 {
1757 hashmethod hm = sig->keytype == KEYTYPE_ED25519
1758 #if defined(SIGN_OPENSSL)
1759 ? HASH_NULL
1760 #else
1761 ? HASH_SHA2_512
1762 #endif
1763 : pdkim_hashes[sig->hashtype].exim_hashmethod;
1764
1765 #ifdef SIGN_HAVE_ED25519
1766 /* For GCrypt, and for EC, we pass the hash-of-headers to the signing
1767 routine. For anything else we just pass the headers. */
1768
1769 if (sig->keytype != KEYTYPE_ED25519)
1770 #endif
1771 {
1772 hhash.data = hdata->s;
1773 hhash.len = hdata->ptr;
1774 }
1775
1776 if ((*err = exim_dkim_sign(&sctx, hm, &hhash, &sig->sighash)))
1777 {
1778 log_write(0, LOG_MAIN|LOG_PANIC, "signing: %s", *err);
1779 return PDKIM_ERR_RSA_SIGNING;
1780 }
1781
1782 DEBUG(D_acl)
1783 {
1784 debug_printf( "DKIM [%s] b computed: ", sig->domain);
1785 pdkim_hexprint(sig->sighash.data, sig->sighash.len);
1786 }
1787
1788 sig->signature_header = pdkim_create_header(sig, TRUE);
1789 }
1790
1791 /* VERIFICATION ----------------------------------------------------------- */
1792 else
1793 {
1794 ev_ctx vctx;
1795 hashmethod hm;
1796
1797 /* Make sure we have all required signature tags */
1798 if (!( sig->domain && *sig->domain
1799 && sig->selector && *sig->selector
1800 && sig->headernames && *sig->headernames
1801 && sig->bodyhash.data
1802 && sig->sighash.data
1803 && sig->keytype >= 0
1804 && sig->hashtype >= 0
1805 && sig->version
1806 ) )
1807 {
1808 sig->verify_status = PDKIM_VERIFY_INVALID;
1809 sig->verify_ext_status = PDKIM_VERIFY_INVALID_SIGNATURE_ERROR;
1810
1811 DEBUG(D_acl) debug_printf(
1812 " Error in DKIM-Signature header: tags missing or invalid (%s)\n"
1813 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
1814 !(sig->domain && *sig->domain) ? "d="
1815 : !(sig->selector && *sig->selector) ? "s="
1816 : !(sig->headernames && *sig->headernames) ? "h="
1817 : !sig->bodyhash.data ? "bh="
1818 : !sig->sighash.data ? "b="
1819 : sig->keytype < 0 || sig->hashtype < 0 ? "a="
1820 : "v="
1821 );
1822 goto NEXT_VERIFY;
1823 }
1824
1825 /* Make sure sig uses supported DKIM version (only v1) */
1826 if (sig->version != 1)
1827 {
1828 sig->verify_status = PDKIM_VERIFY_INVALID;
1829 sig->verify_ext_status = PDKIM_VERIFY_INVALID_DKIM_VERSION;
1830
1831 DEBUG(D_acl) debug_printf(
1832 " Error in DKIM-Signature header: unsupported DKIM version\n"
1833 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1834 goto NEXT_VERIFY;
1835 }
1836
1837 DEBUG(D_acl)
1838 {
1839 debug_printf( "DKIM [%s] b from mail: ", sig->domain);
1840 pdkim_hexprint(sig->sighash.data, sig->sighash.len);
1841 }
1842
1843 if (!(sig->pubkey = pdkim_key_from_dns(ctx, sig, &vctx, err)))
1844 {
1845 log_write(0, LOG_MAIN, "DKIM: %s%s %s%s [failed key import]",
1846 sig->domain ? "d=" : "", sig->domain ? sig->domain : US"",
1847 sig->selector ? "s=" : "", sig->selector ? sig->selector : US"");
1848 goto NEXT_VERIFY;
1849 }
1850
1851 /* If the pubkey limits to a list of specific hashes, ignore sigs that
1852 do not have the hash part of the sig algorithm matching */
1853
1854 if (sig->pubkey->hashes)
1855 {
1856 const uschar * list = sig->pubkey->hashes, * ele;
1857 int sep = ':';
1858 while ((ele = string_nextinlist(&list, &sep, NULL, 0)))
1859 if (Ustrcmp(ele, pdkim_hashes[sig->hashtype].dkim_hashname) == 0) break;
1860 if (!ele)
1861 {
1862 DEBUG(D_acl) debug_printf("pubkey h=%s vs. sig a=%s_%s\n",
1863 sig->pubkey->hashes,
1864 pdkim_keytypes[sig->keytype],
1865 pdkim_hashes[sig->hashtype].dkim_hashname);
1866 sig->verify_status = PDKIM_VERIFY_FAIL;
1867 sig->verify_ext_status = PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH;
1868 goto NEXT_VERIFY;
1869 }
1870 }
1871
1872 hm = sig->keytype == KEYTYPE_ED25519
1873 #if defined(SIGN_OPENSSL)
1874 ? HASH_NULL
1875 #else
1876 ? HASH_SHA2_512
1877 #endif
1878 : pdkim_hashes[sig->hashtype].exim_hashmethod;
1879
1880 /* Check the signature */
1881
1882 if ((*err = exim_dkim_verify(&vctx, hm, &hhash, &sig->sighash)))
1883 {
1884 DEBUG(D_acl) debug_printf("headers verify: %s\n", *err);
1885 sig->verify_status = PDKIM_VERIFY_FAIL;
1886 sig->verify_ext_status = PDKIM_VERIFY_FAIL_MESSAGE;
1887 goto NEXT_VERIFY;
1888 }
1889
1890
1891 /* We have a winner! (if bodyhash was correct earlier) */
1892 if (sig->verify_status == PDKIM_VERIFY_NONE)
1893 {
1894 sig->verify_status = PDKIM_VERIFY_PASS;
1895 verify_pass = TRUE;
1896 if (dkim_verify_minimal) break;
1897 }
1898
1899 NEXT_VERIFY:
1900
1901 DEBUG(D_acl)
1902 {
1903 debug_printf("DKIM [%s] %s signature status: %s",
1904 sig->domain, dkim_sig_to_a_tag(sig),
1905 pdkim_verify_status_str(sig->verify_status));
1906 if (sig->verify_ext_status > 0)
1907 debug_printf(" (%s)\n",
1908 pdkim_verify_ext_status_str(sig->verify_ext_status));
1909 else
1910 debug_printf("\n");
1911 }
1912 }
1913 }
1914
1915 /* If requested, set return pointer to signature(s) */
1916 if (return_signatures)
1917 *return_signatures = ctx->sig;
1918
1919 return ctx->flags & PDKIM_MODE_SIGN || verify_pass
1920 ? PDKIM_OK : PDKIM_FAIL;
1921 }
1922
1923
1924 /* -------------------------------------------------------------------------- */
1925
1926 DLLEXPORT pdkim_ctx *
1927 pdkim_init_verify(uschar * (*dns_txt_callback)(const uschar *), BOOL dot_stuffing)
1928 {
1929 pdkim_ctx * ctx;
1930
1931 ctx = store_get(sizeof(pdkim_ctx), FALSE);
1932 memset(ctx, 0, sizeof(pdkim_ctx));
1933
1934 if (dot_stuffing) ctx->flags = PDKIM_DOT_TERM;
1935 /* The line-buffer is for message data, hence tainted */
1936 ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN, TRUE);
1937 ctx->dns_txt_callback = dns_txt_callback;
1938
1939 return ctx;
1940 }
1941
1942
1943 /* -------------------------------------------------------------------------- */
1944
1945 DLLEXPORT pdkim_signature *
1946 pdkim_init_sign(pdkim_ctx * ctx,
1947 uschar * domain, uschar * selector, uschar * privkey,
1948 uschar * hashname, const uschar ** errstr)
1949 {
1950 int hashtype;
1951 pdkim_signature * sig;
1952
1953 if (!domain || !selector || !privkey)
1954 return NULL;
1955
1956 /* Allocate & init one signature struct */
1957
1958 sig = store_get(sizeof(pdkim_signature), FALSE);
1959 memset(sig, 0, sizeof(pdkim_signature));
1960
1961 sig->bodylength = -1;
1962
1963 sig->domain = string_copy(US domain);
1964 sig->selector = string_copy(US selector);
1965 sig->privkey = string_copy(US privkey);
1966 sig->keytype = -1;
1967
1968 for (hashtype = 0; hashtype < nelem(pdkim_hashes); hashtype++)
1969 if (Ustrcmp(hashname, pdkim_hashes[hashtype].dkim_hashname) == 0)
1970 { sig->hashtype = hashtype; break; }
1971 if (hashtype >= nelem(pdkim_hashes))
1972 {
1973 log_write(0, LOG_MAIN|LOG_PANIC,
1974 "DKIM: unrecognised hashname '%s'", hashname);
1975 return NULL;
1976 }
1977
1978 DEBUG(D_acl)
1979 {
1980 pdkim_signature s = *sig;
1981 ev_ctx vctx;
1982
1983 debug_printf("DKIM (checking verify key)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1984 if (!pdkim_key_from_dns(ctx, &s, &vctx, errstr))
1985 debug_printf("WARNING: bad dkim key in dns\n");
1986 debug_printf("DKIM (finished checking verify key)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1987 }
1988 return sig;
1989 }
1990
1991
1992 /* -------------------------------------------------------------------------- */
1993
1994 DLLEXPORT void
1995 pdkim_set_optional(pdkim_signature * sig,
1996 char * sign_headers,
1997 char * identity,
1998 int canon_headers,
1999 int canon_body,
2000 long bodylength,
2001 unsigned long created,
2002 unsigned long expires)
2003 {
2004 if (identity)
2005 sig->identity = string_copy(US identity);
2006
2007 sig->sign_headers = string_copy(sign_headers
2008 ? US sign_headers : US PDKIM_DEFAULT_SIGN_HEADERS);
2009
2010 sig->canon_headers = canon_headers;
2011 sig->canon_body = canon_body;
2012 sig->bodylength = bodylength;
2013 sig->created = created;
2014 sig->expires = expires;
2015
2016 return;
2017 }
2018
2019
2020
2021 /* Set up a blob for calculating the bodyhash according to the
2022 given needs. Use an existing one if possible, or create a new one.
2023
2024 Return: hashblob pointer, or NULL on error
2025 */
2026 pdkim_bodyhash *
2027 pdkim_set_bodyhash(pdkim_ctx * ctx, int hashtype, int canon_method,
2028 long bodylength)
2029 {
2030 pdkim_bodyhash * b;
2031
2032 if (hashtype == -1 || canon_method == -1) return NULL;
2033
2034 for (b = ctx->bodyhash; b; b = b->next)
2035 if ( hashtype == b->hashtype
2036 && canon_method == b->canon_method
2037 && bodylength == b->bodylength)
2038 {
2039 DEBUG(D_receive) debug_printf("DKIM: using existing bodyhash %d/%d/%ld\n",
2040 hashtype, canon_method, bodylength);
2041 return b;
2042 }
2043
2044 DEBUG(D_receive) debug_printf("DKIM: new bodyhash %d/%d/%ld\n",
2045 hashtype, canon_method, bodylength);
2046 b = store_get(sizeof(pdkim_bodyhash), FALSE);
2047 b->next = ctx->bodyhash;
2048 b->hashtype = hashtype;
2049 b->canon_method = canon_method;
2050 b->bodylength = bodylength;
2051 if (!exim_sha_init(&b->body_hash_ctx, /*XXX hash method: extend for sha512 */
2052 pdkim_hashes[hashtype].exim_hashmethod))
2053 {
2054 DEBUG(D_acl)
2055 debug_printf("DKIM: hash init error, possibly nonhandled hashtype\n");
2056 return NULL;
2057 }
2058 b->signed_body_bytes = 0;
2059 b->num_buffered_blanklines = 0;
2060 ctx->bodyhash = b;
2061 return b;
2062 }
2063
2064
2065 /* Set up a blob for calculating the bodyhash according to the
2066 needs of this signature. Use an existing one if possible, or
2067 create a new one.
2068
2069 Return: hashblob pointer, or NULL on error (only used as a boolean).
2070 */
2071 pdkim_bodyhash *
2072 pdkim_set_sig_bodyhash(pdkim_ctx * ctx, pdkim_signature * sig)
2073 {
2074 pdkim_bodyhash * b = pdkim_set_bodyhash(ctx,
2075 sig->hashtype, sig->canon_body, sig->bodylength);
2076 sig->calc_body_hash = b;
2077 return b;
2078 }
2079
2080
2081 /* -------------------------------------------------------------------------- */
2082
2083
2084 void
2085 pdkim_init_context(pdkim_ctx * ctx, BOOL dot_stuffed,
2086 uschar * (*dns_txt_callback)(const uschar *))
2087 {
2088 memset(ctx, 0, sizeof(pdkim_ctx));
2089 ctx->flags = dot_stuffed ? PDKIM_MODE_SIGN | PDKIM_DOT_TERM : PDKIM_MODE_SIGN;
2090 /* The line buffer is for message data, hence tainted */
2091 ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN, TRUE);
2092 DEBUG(D_acl) ctx->dns_txt_callback = dns_txt_callback;
2093 }
2094
2095
2096 void
2097 pdkim_init(void)
2098 {
2099 exim_dkim_init();
2100 }
2101
2102
2103
2104 #endif /*DISABLE_DKIM*/