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