Copyright updates:
[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 - 2020 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_PUBKEY_KEYSIZE: return "PDKIM_VERIFY_INVALID_PUBKEY_KEYSIZE";
185 case PDKIM_VERIFY_INVALID_SIGNATURE_ERROR: return "PDKIM_VERIFY_INVALID_SIGNATURE_ERROR";
186 case PDKIM_VERIFY_INVALID_DKIM_VERSION: return "PDKIM_VERIFY_INVALID_DKIM_VERSION";
187 default: return "PDKIM_VERIFY_UNKNOWN";
188 }
189 }
190
191 const uschar *
192 pdkim_errstr(int status)
193 {
194 switch(status)
195 {
196 case PDKIM_OK: return US"OK";
197 case PDKIM_FAIL: return US"FAIL";
198 case PDKIM_ERR_RSA_PRIVKEY: return US"PRIVKEY";
199 case PDKIM_ERR_RSA_SIGNING: return US"SIGNING";
200 case PDKIM_ERR_LONG_LINE: return US"LONG_LINE";
201 case PDKIM_ERR_BUFFER_TOO_SMALL: return US"BUFFER_TOO_SMALL";
202 case PDKIM_ERR_EXCESS_SIGS: return US"EXCESS_SIGS";
203 case PDKIM_SIGN_PRIVKEY_WRAP: return US"PRIVKEY_WRAP";
204 case PDKIM_SIGN_PRIVKEY_B64D: return US"PRIVKEY_B64D";
205 default: return US"(unknown)";
206 }
207 }
208
209
210 /* -------------------------------------------------------------------------- */
211 /* Print debugging functions */
212 void
213 pdkim_quoteprint(const uschar *data, int len)
214 {
215 for (int i = 0; i < len; i++)
216 {
217 const int c = data[i];
218 switch (c)
219 {
220 case ' ' : debug_printf("{SP}"); break;
221 case '\t': debug_printf("{TB}"); break;
222 case '\r': debug_printf("{CR}"); break;
223 case '\n': debug_printf("{LF}"); break;
224 case '{' : debug_printf("{BO}"); break;
225 case '}' : debug_printf("{BC}"); break;
226 default:
227 if ( (c < 32) || (c > 127) )
228 debug_printf("{%02x}", c);
229 else
230 debug_printf("%c", c);
231 break;
232 }
233 }
234 debug_printf("\n");
235 }
236
237 void
238 pdkim_hexprint(const uschar *data, int len)
239 {
240 if (data) for (int i = 0 ; i < len; i++) debug_printf("%02x", data[i]);
241 else debug_printf("<NULL>");
242 debug_printf("\n");
243 }
244
245
246
247 static pdkim_stringlist *
248 pdkim_prepend_stringlist(pdkim_stringlist * base, const uschar * str)
249 {
250 pdkim_stringlist * new_entry = store_get(sizeof(pdkim_stringlist), FALSE);
251
252 memset(new_entry, 0, sizeof(pdkim_stringlist));
253 new_entry->value = string_copy(str);
254 if (base) new_entry->next = base;
255 return new_entry;
256 }
257
258
259
260 /* Trim whitespace fore & aft */
261
262 static void
263 pdkim_strtrim(gstring * str)
264 {
265 uschar * p = str->s;
266 uschar * q;
267
268 while (*p == '\t' || *p == ' ') /* dump the leading whitespace */
269 { str->size--; str->ptr--; str->s++; }
270
271 while ( str->ptr > 0
272 && ((q = str->s + str->ptr - 1), (*q == '\t' || *q == ' '))
273 )
274 str->ptr--; /* dump trailing whitespace */
275
276 (void) string_from_gstring(str);
277 }
278
279
280
281 /* -------------------------------------------------------------------------- */
282
283 DLLEXPORT void
284 pdkim_free_ctx(pdkim_ctx *ctx)
285 {
286 }
287
288
289 /* -------------------------------------------------------------------------- */
290 /* Matches the name of the passed raw "header" against
291 the passed colon-separated "tick", and invalidates
292 the entry in tick. Entries can be prefixed for multi- or over-signing,
293 in which case do not invalidate.
294
295 Returns OK for a match, or fail-code
296 */
297
298 static int
299 header_name_match(const uschar * header, uschar * tick)
300 {
301 const uschar * ticklist = tick;
302 int sep = ':';
303 BOOL multisign;
304 uschar * hname, * p, * ele;
305 uschar * hcolon = Ustrchr(header, ':'); /* Get header name */
306
307 if (!hcolon)
308 return PDKIM_FAIL; /* This isn't a header */
309
310 /* if we had strncmpic() we wouldn't need this copy */
311 hname = string_copyn(header, hcolon-header);
312
313 while (p = US ticklist, ele = string_nextinlist(&ticklist, &sep, NULL, 0))
314 {
315 switch (*ele)
316 {
317 case '=': case '+': multisign = TRUE; ele++; break;
318 default: multisign = FALSE; break;
319 }
320
321 if (strcmpic(ele, hname) == 0)
322 {
323 if (!multisign)
324 *p = '_'; /* Invalidate this header name instance in tick-off list */
325 return PDKIM_OK;
326 }
327 }
328 return PDKIM_FAIL;
329 }
330
331
332 /* -------------------------------------------------------------------------- */
333 /* Performs "relaxed" canonicalization of a header. */
334
335 uschar *
336 pdkim_relax_header_n(const uschar * header, int len, BOOL append_crlf)
337 {
338 BOOL past_field_name = FALSE;
339 BOOL seen_wsp = FALSE;
340 uschar * relaxed = store_get(len+3, TRUE); /* tainted */
341 uschar * q = relaxed;
342
343 for (const uschar * p = header; p - header < len; p++)
344 {
345 uschar c = *p;
346
347 if (c == '\r' || c == '\n') /* Ignore CR & LF */
348 continue;
349 if (c == '\t' || c == ' ')
350 {
351 if (seen_wsp)
352 continue;
353 c = ' '; /* Turns WSP into SP */
354 seen_wsp = TRUE;
355 }
356 else
357 if (!past_field_name && c == ':')
358 {
359 if (seen_wsp) q--; /* This removes WSP immediately before the colon */
360 seen_wsp = TRUE; /* This removes WSP immediately after the colon */
361 past_field_name = TRUE;
362 }
363 else
364 seen_wsp = FALSE;
365
366 /* Lowercase header name */
367 if (!past_field_name) c = tolower(c);
368 *q++ = c;
369 }
370
371 if (q > relaxed && q[-1] == ' ') q--; /* Squash eventual trailing SP */
372
373 if (append_crlf) { *q++ = '\r'; *q++ = '\n'; }
374 *q = '\0';
375 return relaxed;
376 }
377
378
379 uschar *
380 pdkim_relax_header(const uschar * header, BOOL append_crlf)
381 {
382 return pdkim_relax_header_n(header, Ustrlen(header), append_crlf);
383 }
384
385
386 /* -------------------------------------------------------------------------- */
387 #define PDKIM_QP_ERROR_DECODE -1
388
389 static const uschar *
390 pdkim_decode_qp_char(const uschar *qp_p, int *c)
391 {
392 const uschar *initial_pos = qp_p;
393
394 /* Advance one char */
395 qp_p++;
396
397 /* Check for two hex digits and decode them */
398 if (isxdigit(*qp_p) && isxdigit(qp_p[1]))
399 {
400 /* Do hex conversion */
401 *c = (isdigit(*qp_p) ? *qp_p - '0' : toupper(*qp_p) - 'A' + 10) << 4;
402 *c |= isdigit(qp_p[1]) ? qp_p[1] - '0' : toupper(qp_p[1]) - 'A' + 10;
403 return qp_p + 2;
404 }
405
406 /* Illegal char here */
407 *c = PDKIM_QP_ERROR_DECODE;
408 return initial_pos;
409 }
410
411
412 /* -------------------------------------------------------------------------- */
413
414 static uschar *
415 pdkim_decode_qp(const uschar * str)
416 {
417 int nchar = 0;
418 uschar * q;
419 const uschar * p = str;
420 uschar * n = store_get(Ustrlen(str)+1, TRUE);
421
422 *n = '\0';
423 q = n;
424 while (*p)
425 {
426 if (*p == '=')
427 {
428 p = pdkim_decode_qp_char(p, &nchar);
429 if (nchar >= 0)
430 {
431 *q++ = nchar;
432 continue;
433 }
434 }
435 else
436 *q++ = *p;
437 p++;
438 }
439 *q = '\0';
440 return n;
441 }
442
443
444 /* -------------------------------------------------------------------------- */
445
446 void
447 pdkim_decode_base64(const uschar * str, blob * b)
448 {
449 int dlen = b64decode(str, &b->data);
450 if (dlen < 0) b->data = NULL;
451 b->len = dlen;
452 }
453
454 uschar *
455 pdkim_encode_base64(blob * b)
456 {
457 return b64encode(CUS b->data, b->len);
458 }
459
460
461 /* -------------------------------------------------------------------------- */
462 #define PDKIM_HDR_LIMBO 0
463 #define PDKIM_HDR_TAG 1
464 #define PDKIM_HDR_VALUE 2
465
466 static pdkim_signature *
467 pdkim_parse_sig_header(pdkim_ctx * ctx, uschar * raw_hdr)
468 {
469 pdkim_signature * sig;
470 uschar *q;
471 gstring * cur_tag = NULL;
472 gstring * cur_val = NULL;
473 BOOL past_hname = FALSE;
474 BOOL in_b_val = FALSE;
475 int where = PDKIM_HDR_LIMBO;
476
477 sig = store_get(sizeof(pdkim_signature), FALSE);
478 memset(sig, 0, sizeof(pdkim_signature));
479 sig->bodylength = -1;
480
481 /* Set so invalid/missing data error display is accurate */
482 sig->version = 0;
483 sig->keytype = -1;
484 sig->hashtype = -1;
485
486 q = sig->rawsig_no_b_val = store_get(Ustrlen(raw_hdr)+1, TRUE); /* tainted */
487
488 for (uschar * p = raw_hdr; ; p++)
489 {
490 char c = *p;
491
492 /* Ignore FWS */
493 if (c == '\r' || c == '\n')
494 goto NEXT_CHAR;
495
496 /* Fast-forward through header name */
497 if (!past_hname)
498 {
499 if (c == ':') past_hname = TRUE;
500 goto NEXT_CHAR;
501 }
502
503 if (where == PDKIM_HDR_LIMBO)
504 {
505 /* In limbo, just wait for a tag-char to appear */
506 if (!(c >= 'a' && c <= 'z'))
507 goto NEXT_CHAR;
508
509 where = PDKIM_HDR_TAG;
510 }
511
512 if (where == PDKIM_HDR_TAG)
513 {
514 if (c >= 'a' && c <= 'z')
515 cur_tag = string_catn(cur_tag, p, 1);
516
517 if (c == '=')
518 {
519 if (Ustrcmp(string_from_gstring(cur_tag), "b") == 0)
520 {
521 *q++ = '=';
522 in_b_val = TRUE;
523 }
524 where = PDKIM_HDR_VALUE;
525 goto NEXT_CHAR;
526 }
527 }
528
529 if (where == PDKIM_HDR_VALUE)
530 {
531 if (c == '\r' || c == '\n' || c == ' ' || c == '\t')
532 goto NEXT_CHAR;
533
534 if (c == ';' || c == '\0')
535 {
536 /* We must have both tag and value, and tags must be one char except
537 for the possibility of "bh". */
538
539 if ( cur_tag && cur_val
540 && (cur_tag->ptr == 1 || *cur_tag->s == 'b')
541 )
542 {
543 (void) string_from_gstring(cur_val);
544 pdkim_strtrim(cur_val);
545
546 DEBUG(D_acl) debug_printf(" %s=%s\n", cur_tag->s, cur_val->s);
547
548 switch (*cur_tag->s)
549 {
550 case 'b': /* sig-data or body-hash */
551 switch (cur_tag->s[1])
552 {
553 case '\0': pdkim_decode_base64(cur_val->s, &sig->sighash); break;
554 case 'h': if (cur_tag->ptr == 2)
555 pdkim_decode_base64(cur_val->s, &sig->bodyhash);
556 break;
557 default: break;
558 }
559 break;
560 case 'v': /* version */
561 /* We only support version 1, and that is currently the
562 only version there is. */
563 sig->version =
564 Ustrcmp(cur_val->s, PDKIM_SIGNATURE_VERSION) == 0 ? 1 : -1;
565 break;
566 case 'a': /* algorithm */
567 {
568 const uschar * list = cur_val->s;
569 int sep = '-';
570 uschar * elem;
571
572 if ((elem = string_nextinlist(&list, &sep, NULL, 0)))
573 sig->keytype = pdkim_keyname_to_keytype(elem);
574 if ((elem = string_nextinlist(&list, &sep, NULL, 0)))
575 for (int i = 0; i < nelem(pdkim_hashes); i++)
576 if (Ustrcmp(elem, pdkim_hashes[i].dkim_hashname) == 0)
577 { sig->hashtype = i; break; }
578 }
579
580 case 'c': /* canonicalization */
581 pdkim_cstring_to_canons(cur_val->s, 0,
582 &sig->canon_headers, &sig->canon_body);
583 break;
584 case 'q': /* Query method (for pubkey)*/
585 for (int i = 0; pdkim_querymethods[i]; i++)
586 if (Ustrcmp(cur_val->s, pdkim_querymethods[i]) == 0)
587 {
588 sig->querymethod = i; /* we never actually use this */
589 break;
590 }
591 break;
592 case 's': /* Selector */
593 sig->selector = string_copyn(cur_val->s, cur_val->ptr); break;
594 case 'd': /* SDID */
595 sig->domain = string_copyn(cur_val->s, cur_val->ptr); break;
596 case 'i': /* AUID */
597 sig->identity = pdkim_decode_qp(cur_val->s); break;
598 case 't': /* Timestamp */
599 sig->created = strtoul(CS cur_val->s, NULL, 10); break;
600 case 'x': /* Expiration */
601 sig->expires = strtoul(CS cur_val->s, NULL, 10); break;
602 case 'l': /* Body length count */
603 sig->bodylength = strtol(CS cur_val->s, NULL, 10); break;
604 case 'h': /* signed header fields */
605 sig->headernames = string_copyn(cur_val->s, cur_val->ptr); break;
606 case 'z': /* Copied headfields */
607 sig->copiedheaders = pdkim_decode_qp(cur_val->s); break;
608 /*XXX draft-ietf-dcrup-dkim-crypto-05 would need 'p' tag support
609 for rsafp signatures. But later discussion is dropping those. */
610 default:
611 DEBUG(D_acl) debug_printf(" Unknown tag encountered\n");
612 break;
613 }
614 }
615 cur_tag = cur_val = NULL;
616 in_b_val = FALSE;
617 where = PDKIM_HDR_LIMBO;
618 }
619 else
620 cur_val = string_catn(cur_val, p, 1);
621 }
622
623 NEXT_CHAR:
624 if (c == '\0')
625 break;
626
627 if (!in_b_val)
628 *q++ = c;
629 }
630
631 if (sig->keytype < 0 || sig->hashtype < 0) /* Cannot verify this signature */
632 return NULL;
633
634 *q = '\0';
635 /* Chomp raw header. The final newline must not be added to the signature. */
636 while (--q > sig->rawsig_no_b_val && (*q == '\r' || *q == '\n'))
637 *q = '\0';
638
639 DEBUG(D_acl)
640 {
641 debug_printf(
642 "DKIM >> Raw signature w/o b= tag value >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
643 pdkim_quoteprint(US sig->rawsig_no_b_val, Ustrlen(sig->rawsig_no_b_val));
644 debug_printf(
645 "DKIM >> Sig size: %4u bits\n", (unsigned) sig->sighash.len*8);
646 debug_printf(
647 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
648 }
649
650 if (!pdkim_set_sig_bodyhash(ctx, sig))
651 return NULL;
652
653 return sig;
654 }
655
656
657 /* -------------------------------------------------------------------------- */
658
659 pdkim_pubkey *
660 pdkim_parse_pubkey_record(const uschar *raw_record)
661 {
662 const uschar * ele;
663 int sep = ';';
664 pdkim_pubkey * pub;
665
666 pub = store_get(sizeof(pdkim_pubkey), TRUE); /* tainted */
667 memset(pub, 0, sizeof(pdkim_pubkey));
668
669 while ((ele = string_nextinlist(&raw_record, &sep, NULL, 0)))
670 {
671 const uschar * val;
672
673 if ((val = Ustrchr(ele, '=')))
674 {
675 int taglen = val++ - ele;
676
677 DEBUG(D_acl) debug_printf(" %.*s=%s\n", taglen, ele, val);
678 switch (ele[0])
679 {
680 case 'v': pub->version = val; break;
681 case 'h': pub->hashes = val; break;
682 case 'k': pub->keytype = val; break;
683 case 'g': pub->granularity = val; break;
684 case 'n': pub->notes = pdkim_decode_qp(val); break;
685 case 'p': pdkim_decode_base64(val, &pub->key); break;
686 case 's': pub->srvtype = val; break;
687 case 't': if (Ustrchr(val, 'y')) pub->testing = 1;
688 if (Ustrchr(val, 's')) pub->no_subdomaining = 1;
689 break;
690 default: DEBUG(D_acl) debug_printf(" Unknown tag encountered\n"); break;
691 }
692 }
693 }
694
695 /* Set fallback defaults */
696 if (!pub->version)
697 pub->version = string_copy(PDKIM_PUB_RECORD_VERSION);
698 else if (Ustrcmp(pub->version, PDKIM_PUB_RECORD_VERSION) != 0)
699 {
700 DEBUG(D_acl) debug_printf(" Bad v= field\n");
701 return NULL;
702 }
703
704 if (!pub->granularity) pub->granularity = US"*";
705 if (!pub->keytype ) pub->keytype = US"rsa";
706 if (!pub->srvtype ) pub->srvtype = US"*";
707
708 /* p= is required */
709 if (pub->key.data)
710 return pub;
711
712 DEBUG(D_acl) debug_printf(" Missing p= field\n");
713 return NULL;
714 }
715
716
717 /* -------------------------------------------------------------------------- */
718
719 /* Update one bodyhash with some additional data.
720 If we have to relax the data for this sig, return our copy of it. */
721
722 static blob *
723 pdkim_update_ctx_bodyhash(pdkim_bodyhash * b, blob * orig_data, blob * relaxed_data)
724 {
725 blob * canon_data = orig_data;
726 /* Defaults to simple canon (no further treatment necessary) */
727
728 if (b->canon_method == PDKIM_CANON_RELAXED)
729 {
730 /* Relax the line if not done already */
731 if (!relaxed_data)
732 {
733 BOOL seen_wsp = FALSE;
734 int q = 0;
735
736 /* We want to be able to free this else we allocate
737 for the entire message which could be many MB. Since
738 we don't know what allocations the SHA routines might
739 do, not safe to use store_get()/store_reset(). */
740
741 relaxed_data = store_malloc(sizeof(blob) + orig_data->len+1);
742 relaxed_data->data = US (relaxed_data+1);
743
744 for (const uschar * p = orig_data->data, * r = p + orig_data->len; p < r; p++)
745 {
746 char c = *p;
747 if (c == '\r')
748 {
749 if (q > 0 && relaxed_data->data[q-1] == ' ')
750 q--;
751 }
752 else if (c == '\t' || c == ' ')
753 {
754 c = ' '; /* Turns WSP into SP */
755 if (seen_wsp)
756 continue;
757 seen_wsp = TRUE;
758 }
759 else
760 seen_wsp = FALSE;
761 relaxed_data->data[q++] = c;
762 }
763 relaxed_data->data[q] = '\0';
764 relaxed_data->len = q;
765 }
766 canon_data = relaxed_data;
767 }
768
769 /* Make sure we don't exceed the to-be-signed body length */
770 if ( b->bodylength >= 0
771 && b->signed_body_bytes + (unsigned long)canon_data->len > b->bodylength
772 )
773 canon_data->len = b->bodylength - b->signed_body_bytes;
774
775 if (canon_data->len > 0)
776 {
777 exim_sha_update(&b->body_hash_ctx, CUS canon_data->data, canon_data->len);
778 b->signed_body_bytes += canon_data->len;
779 DEBUG(D_acl) pdkim_quoteprint(canon_data->data, canon_data->len);
780 }
781
782 return relaxed_data;
783 }
784
785
786 /* -------------------------------------------------------------------------- */
787
788 static void
789 pdkim_finish_bodyhash(pdkim_ctx * ctx)
790 {
791 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next) /* Finish hashes */
792 {
793 DEBUG(D_acl) debug_printf("DKIM: finish bodyhash %d/%d/%ld len %ld\n",
794 b->hashtype, b->canon_method, b->bodylength, b->signed_body_bytes);
795 exim_sha_finish(&b->body_hash_ctx, &b->bh);
796 }
797
798 /* Traverse all signatures */
799 for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next)
800 {
801 pdkim_bodyhash * b = sig->calc_body_hash;
802
803 DEBUG(D_acl)
804 {
805 debug_printf("DKIM [%s] Body bytes (%s) hashed: %lu\n"
806 "DKIM [%s] Body %s computed: ",
807 sig->domain, pdkim_canons[b->canon_method], b->signed_body_bytes,
808 sig->domain, pdkim_hashes[b->hashtype].dkim_hashname);
809 pdkim_hexprint(CUS b->bh.data, b->bh.len);
810 }
811
812 /* SIGNING -------------------------------------------------------------- */
813 if (ctx->flags & PDKIM_MODE_SIGN)
814 {
815 /* If bodylength limit is set, and we have received less bytes
816 than the requested amount, effectively remove the limit tag. */
817 if (b->signed_body_bytes < sig->bodylength)
818 sig->bodylength = -1;
819 }
820
821 else
822 /* VERIFICATION --------------------------------------------------------- */
823 /* Be careful that the header sig included a bodyash */
824
825 if ( sig->bodyhash.data
826 && memcmp(b->bh.data, sig->bodyhash.data, b->bh.len) == 0)
827 {
828 DEBUG(D_acl) debug_printf("DKIM [%s] Body hash compared OK\n", sig->domain);
829 }
830 else
831 {
832 DEBUG(D_acl)
833 {
834 debug_printf("DKIM [%s] Body hash signature from headers: ", sig->domain);
835 pdkim_hexprint(sig->bodyhash.data, sig->bodyhash.len);
836 debug_printf("DKIM [%s] Body hash did NOT verify\n", sig->domain);
837 }
838 sig->verify_status = PDKIM_VERIFY_FAIL;
839 sig->verify_ext_status = PDKIM_VERIFY_FAIL_BODY;
840 }
841 }
842 }
843
844
845
846 static void
847 pdkim_body_complete(pdkim_ctx * ctx)
848 {
849 /* In simple body mode, if any empty lines were buffered,
850 replace with one. rfc 4871 3.4.3 */
851 /*XXX checking the signed-body-bytes is a gross hack; I think
852 it indicates that all linebreaks should be buffered, including
853 the one terminating a text line */
854
855 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
856 if ( b->canon_method == PDKIM_CANON_SIMPLE
857 && b->signed_body_bytes == 0
858 && b->num_buffered_blanklines > 0
859 )
860 (void) pdkim_update_ctx_bodyhash(b, &lineending, NULL);
861
862 ctx->flags |= PDKIM_SEEN_EOD;
863 ctx->linebuf_offset = 0;
864 }
865
866
867
868 /* -------------------------------------------------------------------------- */
869 /* Call from pdkim_feed below for processing complete body lines */
870 /* NOTE: the line is not NUL-terminated; but we have a count */
871
872 static void
873 pdkim_bodyline_complete(pdkim_ctx * ctx)
874 {
875 blob line = {.data = ctx->linebuf, .len = ctx->linebuf_offset};
876 blob * rnl = NULL;
877 blob * rline = NULL;
878
879 /* Ignore extra data if we've seen the end-of-data marker */
880 if (ctx->flags & PDKIM_SEEN_EOD) goto all_skip;
881
882 /* We've always got one extra byte to stuff a zero ... */
883 ctx->linebuf[line.len] = '\0';
884
885 /* Terminate on EOD marker */
886 if (ctx->flags & PDKIM_DOT_TERM)
887 {
888 if (memcmp(line.data, ".\r\n", 3) == 0)
889 { pdkim_body_complete(ctx); return; }
890
891 /* Unstuff dots */
892 if (memcmp(line.data, "..", 2) == 0)
893 { line.data++; line.len--; }
894 }
895
896 /* Empty lines need to be buffered until we find a non-empty line */
897 if (memcmp(line.data, "\r\n", 2) == 0)
898 {
899 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
900 b->num_buffered_blanklines++;
901 goto all_skip;
902 }
903
904 /* Process line for each bodyhash separately */
905 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
906 {
907 if (b->canon_method == PDKIM_CANON_RELAXED)
908 {
909 /* Lines with just spaces need to be buffered too */
910 uschar * cp = line.data;
911 char c;
912
913 while ((c = *cp))
914 {
915 if (c == '\r' && cp[1] == '\n') break;
916 if (c != ' ' && c != '\t') goto hash_process;
917 cp++;
918 }
919
920 b->num_buffered_blanklines++;
921 goto hash_skip;
922 }
923
924 hash_process:
925 /* At this point, we have a non-empty line, so release the buffered ones. */
926
927 while (b->num_buffered_blanklines)
928 {
929 rnl = pdkim_update_ctx_bodyhash(b, &lineending, rnl);
930 b->num_buffered_blanklines--;
931 }
932
933 rline = pdkim_update_ctx_bodyhash(b, &line, rline);
934 hash_skip: ;
935 }
936
937 if (rnl) store_free(rnl);
938 if (rline) store_free(rline);
939
940 all_skip:
941
942 ctx->linebuf_offset = 0;
943 return;
944 }
945
946
947 /* -------------------------------------------------------------------------- */
948 /* Callback from pdkim_feed below for processing complete headers */
949 #define DKIM_SIGNATURE_HEADERNAME "DKIM-Signature:"
950
951 static int
952 pdkim_header_complete(pdkim_ctx * ctx)
953 {
954 if ( (ctx->cur_header->ptr > 1) &&
955 (ctx->cur_header->s[ctx->cur_header->ptr-1] == '\r') )
956 --ctx->cur_header->ptr;
957 (void) string_from_gstring(ctx->cur_header);
958
959 #ifdef EXPERIMENTAL_ARC
960 /* Feed the header line to ARC processing */
961 (void) arc_header_feed(ctx->cur_header, !(ctx->flags & PDKIM_MODE_SIGN));
962 #endif
963
964 if (++ctx->num_headers > PDKIM_MAX_HEADERS) goto BAIL;
965
966 /* SIGNING -------------------------------------------------------------- */
967 if (ctx->flags & PDKIM_MODE_SIGN)
968 for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) /* Traverse all signatures */
969
970 /* Add header to the signed headers list (in reverse order) */
971 sig->headers = pdkim_prepend_stringlist(sig->headers, ctx->cur_header->s);
972
973 /* VERIFICATION ----------------------------------------------------------- */
974 /* DKIM-Signature: headers are added to the verification list */
975 else
976 {
977 #ifdef notdef
978 DEBUG(D_acl)
979 {
980 debug_printf("DKIM >> raw hdr: ");
981 pdkim_quoteprint(CUS ctx->cur_header->s, ctx->cur_header->ptr);
982 }
983 #endif
984 if (strncasecmp(CCS ctx->cur_header->s,
985 DKIM_SIGNATURE_HEADERNAME,
986 Ustrlen(DKIM_SIGNATURE_HEADERNAME)) == 0)
987 {
988 pdkim_signature * sig, * last_sig;
989 /* Create and chain new signature block. We could error-check for all
990 required tags here, but prefer to create the internal sig and expicitly
991 fail verification of it later. */
992
993 DEBUG(D_acl) debug_printf(
994 "DKIM >> Found sig, trying to parse >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
995
996 sig = pdkim_parse_sig_header(ctx, ctx->cur_header->s);
997
998 if (!(last_sig = ctx->sig))
999 ctx->sig = sig;
1000 else
1001 {
1002 while (last_sig->next) last_sig = last_sig->next;
1003 last_sig->next = sig;
1004 }
1005
1006 if (--dkim_collect_input == 0)
1007 {
1008 ctx->headers = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->s);
1009 ctx->cur_header->s[ctx->cur_header->ptr = 0] = '\0';
1010 return PDKIM_ERR_EXCESS_SIGS;
1011 }
1012 }
1013
1014 /* all headers are stored for signature verification */
1015 ctx->headers = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->s);
1016 }
1017
1018 BAIL:
1019 ctx->cur_header->s[ctx->cur_header->ptr = 0] = '\0'; /* leave buffer for reuse */
1020 return PDKIM_OK;
1021 }
1022
1023
1024
1025 /* -------------------------------------------------------------------------- */
1026 #define HEADER_BUFFER_FRAG_SIZE 256
1027
1028 DLLEXPORT int
1029 pdkim_feed(pdkim_ctx * ctx, uschar * data, int len)
1030 {
1031 /* Alternate EOD signal, used in non-dotstuffing mode */
1032 if (!data)
1033 pdkim_body_complete(ctx);
1034
1035 else for (int p = 0; p < len; p++)
1036 {
1037 uschar c = data[p];
1038 int rc;
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 "DKIM >> 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("DKIM: 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 "DKIM >> 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 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1406 }
1407 return NULL;
1408 }
1409
1410 DEBUG(D_acl) debug_printf(
1411 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\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 if ((sig->keytype = pdkim_keyname_to_keytype(p->keytype)) < 0)
1422 {
1423 DEBUG(D_acl) debug_printf("verify_init: unhandled keytype %s\n", p->keytype);
1424 sig->verify_status = PDKIM_VERIFY_INVALID;
1425 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
1426 return NULL;
1427 }
1428
1429 if (sig->keytype == KEYTYPE_ED25519)
1430 check_bare_ed25519_pubkey(p);
1431
1432 if ((*errstr = exim_dkim_verify_init(&p->key,
1433 sig->keytype == KEYTYPE_ED25519 ? KEYFMT_ED25519_BARE : KEYFMT_DER,
1434 vctx, &sig->keybits)))
1435 {
1436 DEBUG(D_acl) debug_printf("verify_init: %s\n", *errstr);
1437 sig->verify_status = PDKIM_VERIFY_INVALID;
1438 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
1439 return NULL;
1440 }
1441
1442 vctx->keytype = sig->keytype;
1443 return p;
1444 }
1445
1446
1447 /* -------------------------------------------------------------------------- */
1448 /* Sort and filter the sigs developed from the message */
1449
1450 static pdkim_signature *
1451 sort_sig_methods(pdkim_signature * siglist)
1452 {
1453 pdkim_signature * yield, ** ss;
1454 const uschar * prefs;
1455 uschar * ele;
1456 int sep;
1457
1458 if (!siglist) return NULL;
1459
1460 /* first select in order of hashtypes */
1461 DEBUG(D_acl) debug_printf("DKIM: dkim_verify_hashes '%s'\n", dkim_verify_hashes);
1462 for (prefs = dkim_verify_hashes, sep = 0, yield = NULL, ss = &yield;
1463 ele = string_nextinlist(&prefs, &sep, NULL, 0); )
1464 {
1465 int i = pdkim_hashname_to_hashtype(CUS ele, 0);
1466 for (pdkim_signature * s = siglist, * next, ** prev = &siglist; s;
1467 s = next)
1468 {
1469 next = s->next;
1470 if (s->hashtype == i)
1471 { *prev = next; s->next = NULL; *ss = s; ss = &s->next; }
1472 else
1473 prev = &s->next;
1474 }
1475 }
1476
1477 /* then in order of keytypes */
1478 siglist = yield;
1479 DEBUG(D_acl) debug_printf("DKIM: dkim_verify_keytypes '%s'\n", dkim_verify_keytypes);
1480 for (prefs = dkim_verify_keytypes, sep = 0, yield = NULL, ss = &yield;
1481 ele = string_nextinlist(&prefs, &sep, NULL, 0); )
1482 {
1483 int i = pdkim_keyname_to_keytype(CUS ele);
1484 for (pdkim_signature * s = siglist, * next, ** prev = &siglist; s;
1485 s = next)
1486 {
1487 next = s->next;
1488 if (s->keytype == i)
1489 { *prev = next; s->next = NULL; *ss = s; ss = &s->next; }
1490 else
1491 prev = &s->next;
1492 }
1493 }
1494
1495 DEBUG(D_acl) for (pdkim_signature * s = yield; s; s = s->next)
1496 debug_printf(" retain d=%s s=%s a=%s\n",
1497 s->domain, s->selector, dkim_sig_to_a_tag(s));
1498 return yield;
1499 }
1500
1501
1502 /* -------------------------------------------------------------------------- */
1503
1504 DLLEXPORT int
1505 pdkim_feed_finish(pdkim_ctx * ctx, pdkim_signature ** return_signatures,
1506 const uschar ** err)
1507 {
1508 BOOL verify_pass = FALSE;
1509
1510 /* Check if we must still flush a (partial) header. If that is the
1511 case, the message has no body, and we must compute a body hash
1512 out of '<CR><LF>' */
1513 if (ctx->cur_header && ctx->cur_header->ptr > 0)
1514 {
1515 blob * rnl = NULL;
1516 int rc;
1517
1518 if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1519 return rc;
1520
1521 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
1522 rnl = pdkim_update_ctx_bodyhash(b, &lineending, rnl);
1523 if (rnl) store_free(rnl);
1524 }
1525 else
1526 DEBUG(D_acl) debug_printf(
1527 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1528
1529 /* Build (and/or evaluate) body hash. Do this even if no DKIM sigs, in case we
1530 have a hash to do for ARC. */
1531
1532 pdkim_finish_bodyhash(ctx);
1533
1534 /* Sort and filter the recived signatures */
1535
1536 if (!(ctx->flags & PDKIM_MODE_SIGN))
1537 ctx->sig = sort_sig_methods(ctx->sig);
1538
1539 if (!ctx->sig)
1540 {
1541 DEBUG(D_acl) debug_printf("DKIM: no signatures\n");
1542 *return_signatures = NULL;
1543 return PDKIM_OK;
1544 }
1545
1546 for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next)
1547 {
1548 hctx hhash_ctx;
1549 uschar * sig_hdr = US"";
1550 blob hhash;
1551 gstring * hdata = NULL;
1552 es_ctx sctx;
1553
1554 if ( !(ctx->flags & PDKIM_MODE_SIGN)
1555 && sig->verify_status == PDKIM_VERIFY_FAIL)
1556 {
1557 DEBUG(D_acl)
1558 debug_printf("DKIM: [%s] abandoning this signature\n", sig->domain);
1559 continue;
1560 }
1561
1562 /*XXX The hash of the headers is needed for GCrypt (for which we can do RSA
1563 signing only, as it happens) and for either GnuTLS and OpenSSL when we are
1564 signing with EC (specifically, Ed25519). The former is because the GCrypt
1565 signing operation is pure (does not do its own hash) so we must hash. The
1566 latter is because we (stupidly, but this is what the IETF draft is saying)
1567 must hash with the declared hash method, then pass the result to the library
1568 hash-and-sign routine (because that's all the libraries are providing. And
1569 we're stuck with whatever that hidden hash method is, too). We may as well
1570 do this hash incrementally.
1571 We don't need the hash we're calculating here for the GnuTLS and OpenSSL
1572 cases of RSA signing, since those library routines can do hash-and-sign.
1573
1574 Some time in the future we could easily avoid doing the hash here for those
1575 cases (which will be common for a long while. We could also change from
1576 the current copy-all-the-headers-into-one-block, then call the hash-and-sign
1577 implementation - to a proper incremental one. Unfortunately, GnuTLS just
1578 cannot do incremental - either signing or verification. Unsure about GCrypt.
1579 */
1580
1581 /*XXX The header hash is also used (so far) by the verify operation */
1582
1583 if (!exim_sha_init(&hhash_ctx, pdkim_hashes[sig->hashtype].exim_hashmethod))
1584 {
1585 log_write(0, LOG_MAIN|LOG_PANIC,
1586 "DKIM: hash setup error, possibly nonhandled hashtype");
1587 break;
1588 }
1589
1590 if (ctx->flags & PDKIM_MODE_SIGN)
1591 DEBUG(D_acl) debug_printf(
1592 "DKIM >> Headers to be signed: >>>>>>>>>>>>\n"
1593 " %s\n",
1594 sig->sign_headers);
1595
1596 DEBUG(D_acl) debug_printf(
1597 "DKIM >> Header data for hash, canonicalized (%-7s), in sequence >>\n",
1598 pdkim_canons[sig->canon_headers]);
1599
1600
1601 /* SIGNING ---------------------------------------------------------------- */
1602 /* When signing, walk through our header list and add them to the hash. As we
1603 go, construct a list of the header's names to use for the h= parameter.
1604 Then append to that list any remaining header names for which there was no
1605 header to sign. */
1606
1607 if (ctx->flags & PDKIM_MODE_SIGN)
1608 {
1609 gstring * g = NULL;
1610 const uschar * l;
1611 uschar * s;
1612 int sep = 0;
1613
1614 /* Import private key, including the keytype which we need for building
1615 the signature header */
1616
1617 if ((*err = exim_dkim_signing_init(CUS sig->privkey, &sctx)))
1618 {
1619 log_write(0, LOG_MAIN|LOG_PANIC, "signing_init: %s", *err);
1620 return PDKIM_ERR_RSA_PRIVKEY;
1621 }
1622 sig->keytype = sctx.keytype;
1623
1624 sig->headernames = NULL; /* Collected signed header names */
1625 for (pdkim_stringlist * p = sig->headers; p; p = p->next)
1626 {
1627 uschar * rh = p->value;
1628
1629 if (header_name_match(rh, sig->sign_headers) == PDKIM_OK)
1630 {
1631 /* Collect header names (Note: colon presence is guaranteed here) */
1632 g = string_append_listele_n(g, ':', rh, Ustrchr(rh, ':') - rh);
1633
1634 if (sig->canon_headers == PDKIM_CANON_RELAXED)
1635 rh = pdkim_relax_header(rh, TRUE); /* cook header for relaxed canon */
1636
1637 /* Feed header to the hash algorithm */
1638 exim_sha_update(&hhash_ctx, CUS rh, Ustrlen(rh));
1639
1640 /* Remember headers block for signing (when the library cannot do incremental) */
1641 /*XXX we could avoid doing this for all but the GnuTLS/RSA case */
1642 hdata = exim_dkim_data_append(hdata, rh);
1643
1644 DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1645 }
1646 }
1647
1648 /* Any headers we wanted to sign but were not present must also be listed.
1649 Ignore elements that have been ticked-off or are marked as never-oversign. */
1650
1651 l = sig->sign_headers;
1652 while((s = string_nextinlist(&l, &sep, NULL, 0)))
1653 {
1654 if (*s == '+') /* skip oversigning marker */
1655 s++;
1656 if (*s != '_' && *s != '=')
1657 g = string_append_listele(g, ':', s);
1658 }
1659 sig->headernames = string_from_gstring(g);
1660
1661 /* Create signature header with b= omitted */
1662 sig_hdr = pdkim_create_header(sig, FALSE);
1663 }
1664
1665 /* VERIFICATION ----------------------------------------------------------- */
1666 /* When verifying, walk through the header name list in the h= parameter and
1667 add the headers to the hash in that order. */
1668 else
1669 {
1670 uschar * p = sig->headernames;
1671 uschar * q;
1672
1673 if (p)
1674 {
1675 /* clear tags */
1676 for (pdkim_stringlist * hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1677 hdrs->tag = 0;
1678
1679 p = string_copy(p);
1680 while(1)
1681 {
1682 if ((q = Ustrchr(p, ':')))
1683 *q = '\0';
1684
1685 /*XXX walk the list of headers in same order as received. */
1686 for (pdkim_stringlist * hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1687 if ( hdrs->tag == 0
1688 && strncasecmp(CCS hdrs->value, CCS p, Ustrlen(p)) == 0
1689 && (hdrs->value)[Ustrlen(p)] == ':'
1690 )
1691 {
1692 /* cook header for relaxed canon, or just copy it for simple */
1693
1694 uschar * rh = sig->canon_headers == PDKIM_CANON_RELAXED
1695 ? pdkim_relax_header(hdrs->value, TRUE)
1696 : string_copy(CUS hdrs->value);
1697
1698 /* Feed header to the hash algorithm */
1699 exim_sha_update(&hhash_ctx, CUS rh, Ustrlen(rh));
1700
1701 DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1702 hdrs->tag = 1;
1703 break;
1704 }
1705
1706 if (!q) break;
1707 p = q+1;
1708 }
1709
1710 sig_hdr = string_copy(sig->rawsig_no_b_val);
1711 }
1712 }
1713
1714 DEBUG(D_acl) debug_printf(
1715 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1716
1717 DEBUG(D_acl)
1718 {
1719 debug_printf(
1720 "DKIM >> Signed DKIM-Signature header, pre-canonicalized >>>>>>>>>>>>>\n");
1721 pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr));
1722 debug_printf(
1723 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1724 }
1725
1726 /* Relax header if necessary */
1727 if (sig->canon_headers == PDKIM_CANON_RELAXED)
1728 sig_hdr = pdkim_relax_header(sig_hdr, FALSE);
1729
1730 DEBUG(D_acl)
1731 {
1732 debug_printf("DKIM >> Signed DKIM-Signature header, canonicalized (%-7s) >>>>>>>\n",
1733 pdkim_canons[sig->canon_headers]);
1734 pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr));
1735 debug_printf(
1736 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1737 }
1738
1739 /* Finalize header hash */
1740 exim_sha_update(&hhash_ctx, CUS sig_hdr, Ustrlen(sig_hdr));
1741 exim_sha_finish(&hhash_ctx, &hhash);
1742
1743 DEBUG(D_acl)
1744 {
1745 debug_printf("DKIM [%s] Header %s computed: ",
1746 sig->domain, pdkim_hashes[sig->hashtype].dkim_hashname);
1747 pdkim_hexprint(hhash.data, hhash.len);
1748 }
1749
1750 /* Remember headers block for signing (when the signing library cannot do
1751 incremental) */
1752 if (ctx->flags & PDKIM_MODE_SIGN)
1753 hdata = exim_dkim_data_append(hdata, US sig_hdr);
1754
1755 /* SIGNING ---------------------------------------------------------------- */
1756 if (ctx->flags & PDKIM_MODE_SIGN)
1757 {
1758 hashmethod hm = sig->keytype == KEYTYPE_ED25519
1759 #if defined(SIGN_OPENSSL)
1760 ? HASH_NULL
1761 #else
1762 ? HASH_SHA2_512
1763 #endif
1764 : pdkim_hashes[sig->hashtype].exim_hashmethod;
1765
1766 #ifdef SIGN_HAVE_ED25519
1767 /* For GCrypt, and for EC, we pass the hash-of-headers to the signing
1768 routine. For anything else we just pass the headers. */
1769
1770 if (sig->keytype != KEYTYPE_ED25519)
1771 #endif
1772 {
1773 hhash.data = hdata->s;
1774 hhash.len = hdata->ptr;
1775 }
1776
1777 if ((*err = exim_dkim_sign(&sctx, hm, &hhash, &sig->sighash)))
1778 {
1779 log_write(0, LOG_MAIN|LOG_PANIC, "signing: %s", *err);
1780 return PDKIM_ERR_RSA_SIGNING;
1781 }
1782
1783 DEBUG(D_acl)
1784 {
1785 debug_printf( "DKIM [%s] b computed: ", sig->domain);
1786 pdkim_hexprint(sig->sighash.data, sig->sighash.len);
1787 }
1788
1789 sig->signature_header = pdkim_create_header(sig, TRUE);
1790 }
1791
1792 /* VERIFICATION ----------------------------------------------------------- */
1793 else
1794 {
1795 ev_ctx vctx;
1796 hashmethod hm;
1797
1798 /* Make sure we have all required signature tags */
1799 if (!( sig->domain && *sig->domain
1800 && sig->selector && *sig->selector
1801 && sig->headernames && *sig->headernames
1802 && sig->bodyhash.data
1803 && sig->sighash.data
1804 && sig->keytype >= 0
1805 && sig->hashtype >= 0
1806 && sig->version
1807 ) )
1808 {
1809 sig->verify_status = PDKIM_VERIFY_INVALID;
1810 sig->verify_ext_status = PDKIM_VERIFY_INVALID_SIGNATURE_ERROR;
1811
1812 DEBUG(D_acl) debug_printf(
1813 " Error in DKIM-Signature header: tags missing or invalid (%s)\n"
1814 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
1815 !(sig->domain && *sig->domain) ? "d="
1816 : !(sig->selector && *sig->selector) ? "s="
1817 : !(sig->headernames && *sig->headernames) ? "h="
1818 : !sig->bodyhash.data ? "bh="
1819 : !sig->sighash.data ? "b="
1820 : sig->keytype < 0 || sig->hashtype < 0 ? "a="
1821 : "v="
1822 );
1823 goto NEXT_VERIFY;
1824 }
1825
1826 /* Make sure sig uses supported DKIM version (only v1) */
1827 if (sig->version != 1)
1828 {
1829 sig->verify_status = PDKIM_VERIFY_INVALID;
1830 sig->verify_ext_status = PDKIM_VERIFY_INVALID_DKIM_VERSION;
1831
1832 DEBUG(D_acl) debug_printf(
1833 " Error in DKIM-Signature header: unsupported DKIM version\n"
1834 "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1835 goto NEXT_VERIFY;
1836 }
1837
1838 DEBUG(D_acl)
1839 {
1840 debug_printf( "DKIM [%s] b from mail: ", sig->domain);
1841 pdkim_hexprint(sig->sighash.data, sig->sighash.len);
1842 }
1843
1844 if (!(sig->pubkey = pdkim_key_from_dns(ctx, sig, &vctx, err)))
1845 {
1846 log_write(0, LOG_MAIN, "DKIM: %s%s %s%s [failed key import]",
1847 sig->domain ? "d=" : "", sig->domain ? sig->domain : US"",
1848 sig->selector ? "s=" : "", sig->selector ? sig->selector : US"");
1849 goto NEXT_VERIFY;
1850 }
1851
1852 /* If the pubkey limits to a list of specific hashes, ignore sigs that
1853 do not have the hash part of the sig algorithm matching */
1854
1855 if (sig->pubkey->hashes)
1856 {
1857 const uschar * list = sig->pubkey->hashes, * ele;
1858 int sep = ':';
1859 while ((ele = string_nextinlist(&list, &sep, NULL, 0)))
1860 if (Ustrcmp(ele, pdkim_hashes[sig->hashtype].dkim_hashname) == 0) break;
1861 if (!ele)
1862 {
1863 DEBUG(D_acl) debug_printf("pubkey h=%s vs. sig a=%s_%s\n",
1864 sig->pubkey->hashes,
1865 pdkim_keytypes[sig->keytype],
1866 pdkim_hashes[sig->hashtype].dkim_hashname);
1867 sig->verify_status = PDKIM_VERIFY_FAIL;
1868 sig->verify_ext_status = PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH;
1869 goto NEXT_VERIFY;
1870 }
1871 }
1872
1873 hm = sig->keytype == KEYTYPE_ED25519
1874 #if defined(SIGN_OPENSSL)
1875 ? HASH_NULL
1876 #else
1877 ? HASH_SHA2_512
1878 #endif
1879 : pdkim_hashes[sig->hashtype].exim_hashmethod;
1880
1881 /* Check the signature */
1882
1883 if ((*err = exim_dkim_verify(&vctx, hm, &hhash, &sig->sighash)))
1884 {
1885 DEBUG(D_acl) debug_printf("headers verify: %s\n", *err);
1886 sig->verify_status = PDKIM_VERIFY_FAIL;
1887 sig->verify_ext_status = PDKIM_VERIFY_FAIL_MESSAGE;
1888 goto NEXT_VERIFY;
1889 }
1890 if (*dkim_verify_min_keysizes)
1891 {
1892 unsigned minbits;
1893 uschar * ss = expand_getkeyed(US pdkim_keytypes[sig->keytype],
1894 dkim_verify_min_keysizes);
1895 if (ss && (minbits = atoi(CS ss)) > sig->keybits)
1896 {
1897 DEBUG(D_acl) debug_printf("Key too short: Actual: %s %u Minima '%s'\n",
1898 pdkim_keytypes[sig->keytype], sig->keybits, dkim_verify_min_keysizes);
1899 sig->verify_status = PDKIM_VERIFY_FAIL;
1900 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_KEYSIZE;
1901 }
1902 }
1903
1904
1905 /* We have a winner! (if bodyhash was correct earlier) */
1906 if (sig->verify_status == PDKIM_VERIFY_NONE)
1907 {
1908 sig->verify_status = PDKIM_VERIFY_PASS;
1909 verify_pass = TRUE;
1910 if (dkim_verify_minimal) break;
1911 }
1912
1913 NEXT_VERIFY:
1914
1915 DEBUG(D_acl)
1916 {
1917 debug_printf("DKIM [%s] %s signature status: %s",
1918 sig->domain, dkim_sig_to_a_tag(sig),
1919 pdkim_verify_status_str(sig->verify_status));
1920 if (sig->verify_ext_status > 0)
1921 debug_printf(" (%s)\n",
1922 pdkim_verify_ext_status_str(sig->verify_ext_status));
1923 else
1924 debug_printf("\n");
1925 }
1926 }
1927 }
1928
1929 /* If requested, set return pointer to signature(s) */
1930 if (return_signatures)
1931 *return_signatures = ctx->sig;
1932
1933 return ctx->flags & PDKIM_MODE_SIGN || verify_pass
1934 ? PDKIM_OK : PDKIM_FAIL;
1935 }
1936
1937
1938 /* -------------------------------------------------------------------------- */
1939
1940 DLLEXPORT pdkim_ctx *
1941 pdkim_init_verify(uschar * (*dns_txt_callback)(const uschar *), BOOL dot_stuffing)
1942 {
1943 pdkim_ctx * ctx;
1944
1945 ctx = store_get(sizeof(pdkim_ctx), FALSE);
1946 memset(ctx, 0, sizeof(pdkim_ctx));
1947
1948 if (dot_stuffing) ctx->flags = PDKIM_DOT_TERM;
1949 /* The line-buffer is for message data, hence tainted */
1950 ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN, TRUE);
1951 ctx->dns_txt_callback = dns_txt_callback;
1952
1953 return ctx;
1954 }
1955
1956
1957 /* -------------------------------------------------------------------------- */
1958
1959 DLLEXPORT pdkim_signature *
1960 pdkim_init_sign(pdkim_ctx * ctx,
1961 uschar * domain, uschar * selector, uschar * privkey,
1962 uschar * hashname, const uschar ** errstr)
1963 {
1964 int hashtype;
1965 pdkim_signature * sig;
1966
1967 if (!domain || !selector || !privkey)
1968 return NULL;
1969
1970 /* Allocate & init one signature struct */
1971
1972 sig = store_get(sizeof(pdkim_signature), FALSE);
1973 memset(sig, 0, sizeof(pdkim_signature));
1974
1975 sig->bodylength = -1;
1976
1977 sig->domain = string_copy(US domain);
1978 sig->selector = string_copy(US selector);
1979 sig->privkey = string_copy(US privkey);
1980 sig->keytype = -1;
1981
1982 for (hashtype = 0; hashtype < nelem(pdkim_hashes); hashtype++)
1983 if (Ustrcmp(hashname, pdkim_hashes[hashtype].dkim_hashname) == 0)
1984 { sig->hashtype = hashtype; break; }
1985 if (hashtype >= nelem(pdkim_hashes))
1986 {
1987 log_write(0, LOG_MAIN|LOG_PANIC,
1988 "DKIM: unrecognised hashname '%s'", hashname);
1989 return NULL;
1990 }
1991
1992 DEBUG(D_acl)
1993 {
1994 pdkim_signature s = *sig;
1995 ev_ctx vctx;
1996
1997 debug_printf("DKIM (checking verify key)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1998 if (!pdkim_key_from_dns(ctx, &s, &vctx, errstr))
1999 debug_printf("WARNING: bad dkim key in dns\n");
2000 debug_printf("DKIM (finished checking verify key)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
2001 }
2002 return sig;
2003 }
2004
2005
2006 /* -------------------------------------------------------------------------- */
2007
2008 DLLEXPORT void
2009 pdkim_set_optional(pdkim_signature * sig,
2010 char * sign_headers,
2011 char * identity,
2012 int canon_headers,
2013 int canon_body,
2014 long bodylength,
2015 unsigned long created,
2016 unsigned long expires)
2017 {
2018 if (identity)
2019 sig->identity = string_copy(US identity);
2020
2021 sig->sign_headers = string_copy(sign_headers
2022 ? US sign_headers : US PDKIM_DEFAULT_SIGN_HEADERS);
2023
2024 sig->canon_headers = canon_headers;
2025 sig->canon_body = canon_body;
2026 sig->bodylength = bodylength;
2027 sig->created = created;
2028 sig->expires = expires;
2029
2030 return;
2031 }
2032
2033
2034
2035 /* Set up a blob for calculating the bodyhash according to the
2036 given needs. Use an existing one if possible, or create a new one.
2037
2038 Return: hashblob pointer, or NULL on error
2039 */
2040 pdkim_bodyhash *
2041 pdkim_set_bodyhash(pdkim_ctx * ctx, int hashtype, int canon_method,
2042 long bodylength)
2043 {
2044 pdkim_bodyhash * b;
2045
2046 if (hashtype == -1 || canon_method == -1) return NULL;
2047
2048 for (b = ctx->bodyhash; b; b = b->next)
2049 if ( hashtype == b->hashtype
2050 && canon_method == b->canon_method
2051 && bodylength == b->bodylength)
2052 {
2053 DEBUG(D_receive) debug_printf("DKIM: using existing bodyhash %d/%d/%ld\n",
2054 hashtype, canon_method, bodylength);
2055 return b;
2056 }
2057
2058 DEBUG(D_receive) debug_printf("DKIM: new bodyhash %d/%d/%ld\n",
2059 hashtype, canon_method, bodylength);
2060 b = store_get(sizeof(pdkim_bodyhash), FALSE);
2061 b->next = ctx->bodyhash;
2062 b->hashtype = hashtype;
2063 b->canon_method = canon_method;
2064 b->bodylength = bodylength;
2065 if (!exim_sha_init(&b->body_hash_ctx, /*XXX hash method: extend for sha512 */
2066 pdkim_hashes[hashtype].exim_hashmethod))
2067 {
2068 DEBUG(D_acl)
2069 debug_printf("DKIM: hash init error, possibly nonhandled hashtype\n");
2070 return NULL;
2071 }
2072 b->signed_body_bytes = 0;
2073 b->num_buffered_blanklines = 0;
2074 ctx->bodyhash = b;
2075 return b;
2076 }
2077
2078
2079 /* Set up a blob for calculating the bodyhash according to the
2080 needs of this signature. Use an existing one if possible, or
2081 create a new one.
2082
2083 Return: hashblob pointer, or NULL on error (only used as a boolean).
2084 */
2085 pdkim_bodyhash *
2086 pdkim_set_sig_bodyhash(pdkim_ctx * ctx, pdkim_signature * sig)
2087 {
2088 pdkim_bodyhash * b = pdkim_set_bodyhash(ctx,
2089 sig->hashtype, sig->canon_body, sig->bodylength);
2090 sig->calc_body_hash = b;
2091 return b;
2092 }
2093
2094
2095 /* -------------------------------------------------------------------------- */
2096
2097
2098 void
2099 pdkim_init_context(pdkim_ctx * ctx, BOOL dot_stuffed,
2100 uschar * (*dns_txt_callback)(const uschar *))
2101 {
2102 memset(ctx, 0, sizeof(pdkim_ctx));
2103 ctx->flags = dot_stuffed ? PDKIM_MODE_SIGN | PDKIM_DOT_TERM : PDKIM_MODE_SIGN;
2104 /* The line buffer is for message data, hence tainted */
2105 ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN, TRUE);
2106 DEBUG(D_acl) ctx->dns_txt_callback = dns_txt_callback;
2107 }
2108
2109
2110 void
2111 pdkim_init(void)
2112 {
2113 exim_dkim_init();
2114 }
2115
2116
2117
2118 #endif /*DISABLE_DKIM*/