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