4fb22a1133557e83c51895ec232f68fb6e9448b6
[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;
472 uschar *q;
473 gstring * cur_tag = NULL;
474 gstring * cur_val = NULL;
475 BOOL past_hname = FALSE;
476 BOOL in_b_val = FALSE;
477 int where = PDKIM_HDR_LIMBO;
478
479 sig = store_get(sizeof(pdkim_signature), GET_UNTAINTED);
480 memset(sig, 0, sizeof(pdkim_signature));
481 sig->bodylength = -1;
482
483 /* Set so invalid/missing data error display is accurate */
484 sig->version = 0;
485 sig->keytype = -1;
486 sig->hashtype = -1;
487
488 q = sig->rawsig_no_b_val = store_get(Ustrlen(raw_hdr)+1, GET_TAINTED);
489
490 for (uschar * p = raw_hdr; ; p++)
491   {
492   char c = *p;
493
494   /* Ignore FWS */
495   if (c == '\r' || c == '\n')
496     goto NEXT_CHAR;
497
498   /* Fast-forward through header name */
499   if (!past_hname)
500     {
501     if (c == ':') past_hname = TRUE;
502     goto NEXT_CHAR;
503     }
504
505   if (where == PDKIM_HDR_LIMBO)
506     {
507     /* In limbo, just wait for a tag-char to appear */
508     if (!(c >= 'a' && c <= 'z'))
509       goto NEXT_CHAR;
510
511     where = PDKIM_HDR_TAG;
512     }
513
514   if (where == PDKIM_HDR_TAG)
515     if (c == '=')
516       {
517       if (Ustrcmp(string_from_gstring(cur_tag), "b") == 0)
518         {
519         *q++ = '=';
520         in_b_val = TRUE;
521         }
522       where = PDKIM_HDR_VALUE;
523       goto NEXT_CHAR;
524       }
525     else if (!isspace(c))
526       cur_tag = string_catn(cur_tag, p, 1);
527
528   if (where == PDKIM_HDR_VALUE)
529     {
530     if (c == '\r' || c == '\n' || c == ' ' || c == '\t')
531       goto NEXT_CHAR;
532
533     if (c == ';' || c == '\0')
534       {
535       /* We must have both tag and value, and tags must be one char except
536       for the possibility of "bh". */
537
538       if (  cur_tag && cur_val
539          && (cur_tag->ptr == 1 || *cur_tag->s == 'b')
540          )
541         {
542         (void) string_from_gstring(cur_val);
543         pdkim_strtrim(cur_val);
544
545         DEBUG(D_acl) debug_printf(" %s=%s\n", cur_tag->s, cur_val->s);
546
547         switch (*cur_tag->s)
548           {
549           case 'b':                             /* sig-data or body-hash */
550             switch (cur_tag->s[1])
551               {
552               case '\0': pdkim_decode_base64(cur_val->s, &sig->sighash); break;
553               case 'h':  if (cur_tag->ptr != 2) goto bad_tag;
554                          pdkim_decode_base64(cur_val->s, &sig->bodyhash);
555                          break;
556               default:   goto bad_tag;
557               }
558             break;
559           case 'v':                                     /* version */
560               /* We only support version 1, and that is currently the
561                  only version there is. */
562             sig->version =
563                 Ustrcmp(cur_val->s, PDKIM_SIGNATURE_VERSION) == 0 ? 1 : -1;
564             break;
565           case 'a':                                     /* algorithm */
566             {
567             const uschar * list = cur_val->s;
568             int sep = '-';
569             uschar * elem;
570
571             if ((elem = string_nextinlist(&list, &sep, NULL, 0)))
572               sig->keytype = pdkim_keyname_to_keytype(elem);
573             if ((elem = string_nextinlist(&list, &sep, NULL, 0)))
574               for (int i = 0; i < nelem(pdkim_hashes); i++)
575                 if (Ustrcmp(elem, pdkim_hashes[i].dkim_hashname) == 0)
576                   { sig->hashtype = i; break; }
577             }
578             break;
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_copy_from_gstring(cur_val); break;
594           case 'd':                                     /* SDID */
595             sig->domain = string_copy_from_gstring(cur_val); 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_copy_from_gstring(cur_val); 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             goto bad_tag;
612           }
613         }
614         else
615 bad_tag:  DEBUG(D_acl) debug_printf(" Unknown tag encountered: %Y\n", cur_tag);
616
617       cur_tag = cur_val = NULL;
618       in_b_val = FALSE;
619       where = PDKIM_HDR_LIMBO;
620       }
621     else
622       cur_val = string_catn(cur_val, p, 1);
623     }
624
625 NEXT_CHAR:
626   if (c == '\0')
627     break;
628
629   if (!in_b_val)
630     *q++ = c;
631   }
632
633 if (sig->keytype < 0 || sig->hashtype < 0)      /* Cannot verify this signature */
634   return NULL;
635
636 *q = '\0';
637 /* Chomp raw header. The final newline must not be added to the signature. */
638 while (--q > sig->rawsig_no_b_val  && (*q == '\r' || *q == '\n'))
639   *q = '\0';
640
641 DEBUG(D_acl)
642   {
643   debug_printf(
644           "DKIM >> Raw signature w/o b= tag value >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
645   pdkim_quoteprint(US sig->rawsig_no_b_val, Ustrlen(sig->rawsig_no_b_val));
646   debug_printf(
647           "DKIM >> Sig size: %4u bits\n", (unsigned) sig->sighash.len*8);
648   debug_printf(
649           "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
650   }
651
652 if (!pdkim_set_sig_bodyhash(ctx, sig))
653   return NULL;
654
655 return sig;
656 }
657
658
659 /* -------------------------------------------------------------------------- */
660
661 pdkim_pubkey *
662 pdkim_parse_pubkey_record(const uschar * raw_record)
663 {
664 pdkim_pubkey * pub = store_get(sizeof(pdkim_pubkey), GET_TAINTED);
665
666 memset(pub, 0, sizeof(pdkim_pubkey));
667
668 for (const uschar * ele = raw_record, * tspec, * end, * val; *ele; ele = end)
669   {
670   Uskip_whitespace(&ele);
671   end = US strchrnul(CS ele, ';');
672   tspec = string_copyn(ele, end - ele);
673   if (*end) end++;                      /* skip the ; */
674
675   if ((val = Ustrchr(tspec, '=')))
676     {
677     int taglen = val++ - tspec;
678
679     DEBUG(D_acl) debug_printf(" %.*s=%s\n", taglen, tspec, val);
680     while (taglen > 1 && isspace(tspec[taglen-1]))
681       taglen--;                 /* Ignore whitespace before = */
682     Uskip_whitespace(&val);     /* Ignore whitespace after = */
683     if (isspace(val[ Ustrlen(val)-1 ]))
684       {                         /* Ignore whitespace after value */
685       gstring * g = string_cat(NULL, val);
686       while (isspace(gstring_last_char(g)))
687         gstring_trim(g, 1);
688       val = string_from_gstring(g);
689       }
690
691     if (taglen == 1) switch (tspec[0])
692       {
693       case 'v': pub->version = val;                     break;
694       case 'h': pub->hashes = val;                      break;
695       case 'k': pub->keytype = val;                     break;
696       case 'g': pub->granularity = val;                 break;
697       case 'n': pub->notes = pdkim_decode_qp(val);      break;
698       case 'p': pdkim_decode_base64(val, &pub->key);    break;
699       case 's': pub->srvtype = val;                     break;
700       case 't': if (Ustrchr(val, 'y')) pub->testing = 1;
701                 if (Ustrchr(val, 's')) pub->no_subdomaining = 1;
702                 break;
703       default:  goto bad_tag;
704       }
705     else
706 bad_tag:
707        DEBUG(D_acl) debug_printf(" Unknown tag encountered\n");
708     }
709   }
710
711 /* Set fallback defaults */
712 if (!pub->version)
713   pub->version = string_copy(PDKIM_PUB_RECORD_VERSION);
714 else if (Ustrcmp(pub->version, PDKIM_PUB_RECORD_VERSION) != 0)
715   {
716   DEBUG(D_acl) debug_printf(" Bad v= field\n");
717   return NULL;
718   }
719
720 if (!pub->granularity) pub->granularity = US"*";
721 if (!pub->keytype    ) pub->keytype     = US"rsa";
722 if (!pub->srvtype    ) pub->srvtype     = US"*";
723
724 /* p= is required */
725 if (pub->key.data)
726   return pub;
727
728 DEBUG(D_acl) debug_printf(" Missing p= field\n");
729 return NULL;
730 }
731
732
733 /* -------------------------------------------------------------------------- */
734
735 /* Update one bodyhash with some additional data.
736 If we have to relax the data for this sig, return our copy of it. */
737
738 static blob *
739 pdkim_update_ctx_bodyhash(pdkim_bodyhash * b, const blob * orig_data, blob * relaxed_data)
740 {
741 const blob * canon_data = orig_data;
742 size_t left;
743
744 /* Defaults to simple canon (no further treatment necessary) */
745
746 if (b->canon_method == PDKIM_CANON_RELAXED)
747   {
748   /* Relax the line if not done already */
749   if (!relaxed_data)
750     {
751     BOOL seen_wsp = FALSE;
752     int q = 0;
753
754     /* We want to be able to free this else we allocate
755     for the entire message which could be many MB. Since
756     we don't know what allocations the SHA routines might
757     do, not safe to use store_get()/store_reset(). */
758
759     relaxed_data = store_malloc(sizeof(blob) + orig_data->len+1);
760     relaxed_data->data = US (relaxed_data+1);
761
762     for (const uschar * p = orig_data->data, * r = p + orig_data->len; p < r; p++)
763       {
764       char c = *p;
765       if (c == '\r')
766         {
767         if (q > 0 && relaxed_data->data[q-1] == ' ')
768           q--;
769         }
770       else if (c == '\t' || c == ' ')
771         {
772         c = ' '; /* Turns WSP into SP */
773         if (seen_wsp)
774           continue;
775         seen_wsp = TRUE;
776         }
777       else
778         seen_wsp = FALSE;
779       relaxed_data->data[q++] = c;
780       }
781     relaxed_data->data[q] = '\0';
782     relaxed_data->len = q;
783     }
784   canon_data = relaxed_data;
785   }
786
787 /* Make sure we don't exceed the to-be-signed body length */
788 left = canon_data->len;
789 if (  b->bodylength >= 0
790    && left > (unsigned long)b->bodylength - b->signed_body_bytes
791    )
792   left = (unsigned long)b->bodylength - b->signed_body_bytes;
793
794 if (left > 0)
795   {
796   exim_sha_update(&b->body_hash_ctx, CUS canon_data->data, left);
797   b->signed_body_bytes += left;
798   DEBUG(D_acl) pdkim_quoteprint(canon_data->data, left);
799   }
800
801 return relaxed_data;
802 }
803
804
805 /* -------------------------------------------------------------------------- */
806
807 static void
808 pdkim_finish_bodyhash(pdkim_ctx * ctx)
809 {
810 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)     /* Finish hashes */
811   {
812   DEBUG(D_acl) debug_printf("DKIM: finish bodyhash %s/%s/%ld len %ld\n",
813       pdkim_hashes[b->hashtype].dkim_hashname, pdkim_canons[b->canon_method],
814       b->bodylength, b->signed_body_bytes);
815   exim_sha_finish(&b->body_hash_ctx, &b->bh);
816   }
817
818 /* Traverse all signatures */
819 for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next)
820   {
821   pdkim_bodyhash * b = sig->calc_body_hash;
822
823   DEBUG(D_acl)
824     {
825     debug_printf("DKIM [%s]%s Body bytes (%s) hashed: %lu\n"
826                  "DKIM [%s]%s Body %s computed: ",
827         sig->domain, sig->selector, pdkim_canons[b->canon_method], b->signed_body_bytes,
828         sig->domain, sig->selector, pdkim_hashes[b->hashtype].dkim_hashname);
829     pdkim_hexprint(CUS b->bh.data, b->bh.len);
830     }
831
832   /* SIGNING -------------------------------------------------------------- */
833   if (ctx->flags & PDKIM_MODE_SIGN)
834     {
835     /* If bodylength limit is set, and we have received less bytes
836        than the requested amount, effectively remove the limit tag. */
837     if (b->signed_body_bytes < sig->bodylength)
838       sig->bodylength = -1;
839     }
840
841   else
842   /* VERIFICATION --------------------------------------------------------- */
843   /* Be careful that the header sig included a bodyash */
844
845     if (sig->bodyhash.data && sig->bodyhash.len == b->bh.len
846        && memcmp(b->bh.data, sig->bodyhash.data, b->bh.len) == 0)
847       {
848       DEBUG(D_acl) debug_printf("DKIM [%s] Body hash compared OK\n", sig->domain);
849       }
850     else
851       {
852       DEBUG(D_acl)
853         {
854         debug_printf("DKIM [%s] Body hash signature from headers: ", sig->domain);
855         pdkim_hexprint(sig->bodyhash.data, sig->bodyhash.len);
856         debug_printf("DKIM [%s] Body hash did NOT verify\n", sig->domain);
857         }
858       sig->verify_status     = PDKIM_VERIFY_FAIL;
859       sig->verify_ext_status = PDKIM_VERIFY_FAIL_BODY;
860       }
861   }
862 }
863
864
865
866 static void
867 pdkim_body_complete(pdkim_ctx * ctx)
868 {
869 /* In simple body mode, if any empty lines were buffered,
870 replace with one. rfc 4871 3.4.3 */
871 /*XXX checking the signed-body-bytes is a gross hack; I think
872 it indicates that all linebreaks should be buffered, including
873 the one terminating a text line */
874
875 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
876   if (  b->canon_method == PDKIM_CANON_SIMPLE
877      && b->signed_body_bytes == 0
878      && b->num_buffered_blanklines > 0
879      )
880     (void) pdkim_update_ctx_bodyhash(b, &lineending, NULL);
881
882 ctx->flags |= PDKIM_SEEN_EOD;
883 ctx->linebuf_offset = 0;
884 }
885
886
887
888 /* -------------------------------------------------------------------------- */
889 /* Call from pdkim_feed below for processing complete body lines */
890 /* NOTE: the line is not NUL-terminated; but we have a count */
891
892 static void
893 pdkim_bodyline_complete(pdkim_ctx * ctx)
894 {
895 blob line = {.data = ctx->linebuf, .len = ctx->linebuf_offset};
896 blob * rnl = NULL;
897 blob * rline = NULL;
898
899 /* Ignore extra data if we've seen the end-of-data marker */
900 if (ctx->flags & PDKIM_SEEN_EOD) goto all_skip;
901
902 /* We've always got one extra byte to stuff a zero ... */
903 ctx->linebuf[line.len] = '\0';
904
905 /* Terminate on EOD marker */
906 if (ctx->flags & PDKIM_DOT_TERM)
907   {
908   if (memcmp(line.data, ".\r\n", 3) == 0)
909     { pdkim_body_complete(ctx); return; }
910
911   /* Unstuff dots */
912   if (memcmp(line.data, "..", 2) == 0)
913     { line.data++; line.len--; }
914   }
915
916 /* Empty lines need to be buffered until we find a non-empty line */
917 if (memcmp(line.data, "\r\n", 2) == 0)
918   {
919   for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
920     b->num_buffered_blanklines++;
921   goto all_skip;
922   }
923
924 /* Process line for each bodyhash separately */
925 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
926   {
927   if (b->canon_method == PDKIM_CANON_RELAXED)
928     {
929     /* Lines with just spaces need to be buffered too */
930     uschar * cp = line.data;
931     char c;
932
933     while ((c = *cp))
934       {
935       if (c == '\r' && cp[1] == '\n') break;
936       if (c != ' ' && c != '\t') goto hash_process;
937       cp++;
938       }
939
940     b->num_buffered_blanklines++;
941     goto hash_skip;
942     }
943
944 hash_process:
945   /* At this point, we have a non-empty line, so release the buffered ones. */
946
947   while (b->num_buffered_blanklines)
948     {
949     rnl = pdkim_update_ctx_bodyhash(b, &lineending, rnl);
950     b->num_buffered_blanklines--;
951     }
952
953   rline = pdkim_update_ctx_bodyhash(b, &line, rline);
954 hash_skip: ;
955   }
956
957 if (rnl) store_free(rnl);
958 if (rline) store_free(rline);
959
960 all_skip:
961
962 ctx->linebuf_offset = 0;
963 return;
964 }
965
966
967 /* -------------------------------------------------------------------------- */
968 /* Callback from pdkim_feed below for processing complete headers */
969 #define DKIM_SIGNATURE_HEADERNAME "DKIM-Signature:"
970
971 static int
972 pdkim_header_complete(pdkim_ctx * ctx)
973 {
974 if (ctx->cur_header->ptr > 1)
975   gstring_trim_trailing(ctx->cur_header, '\r');
976 (void) string_from_gstring(ctx->cur_header);
977
978 #ifdef EXPERIMENTAL_ARC
979 /* Feed the header line to ARC processing */
980 (void) arc_header_feed(ctx->cur_header, !(ctx->flags & PDKIM_MODE_SIGN));
981 #endif
982
983 if (++ctx->num_headers > PDKIM_MAX_HEADERS) goto BAIL;
984
985 /* SIGNING -------------------------------------------------------------- */
986 if (ctx->flags & PDKIM_MODE_SIGN)
987   for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next)  /* Traverse all signatures */
988
989     /* Add header to the signed headers list (in reverse order) */
990     sig->headers = pdkim_prepend_stringlist(sig->headers, ctx->cur_header->s);
991
992 /* VERIFICATION ----------------------------------------------------------- */
993 /* DKIM-Signature: headers are added to the verification list */
994 else
995   {
996 #ifdef notdef
997   DEBUG(D_acl)
998     {
999     debug_printf("DKIM >> raw hdr: ");
1000     pdkim_quoteprint(CUS ctx->cur_header->s, ctx->cur_header->ptr);
1001     }
1002 #endif
1003   if (strncasecmp(CCS ctx->cur_header->s,
1004                   DKIM_SIGNATURE_HEADERNAME,
1005                   Ustrlen(DKIM_SIGNATURE_HEADERNAME)) == 0)
1006     {
1007     pdkim_signature * sig, * last_sig;
1008     /* Create and chain new signature block.  We could error-check for all
1009     required tags here, but prefer to create the internal sig and expicitly
1010     fail verification of it later. */
1011
1012     DEBUG(D_acl) debug_printf(
1013         "DKIM >> Found sig, trying to parse >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1014
1015     sig = pdkim_parse_sig_header(ctx, ctx->cur_header->s);
1016
1017     if (!(last_sig = ctx->sig))
1018       ctx->sig = sig;
1019     else
1020       {
1021       while (last_sig->next) last_sig = last_sig->next;
1022       last_sig->next = sig;
1023       }
1024
1025     if (dkim_collect_input && --dkim_collect_input == 0)
1026       {
1027       ctx->headers = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->s);
1028       ctx->cur_header->s[ctx->cur_header->ptr = 0] = '\0';
1029       return PDKIM_ERR_EXCESS_SIGS;
1030       }
1031     }
1032
1033   /* all headers are stored for signature verification */
1034   ctx->headers = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->s);
1035   }
1036
1037 BAIL:
1038 ctx->cur_header->s[ctx->cur_header->ptr = 0] = '\0';    /* leave buffer for reuse */
1039 return PDKIM_OK;
1040 }
1041
1042
1043
1044 /* -------------------------------------------------------------------------- */
1045 #define HEADER_BUFFER_FRAG_SIZE 256
1046
1047 DLLEXPORT int
1048 pdkim_feed(pdkim_ctx * ctx, uschar * data, int len)
1049 {
1050 /* Alternate EOD signal, used in non-dotstuffing mode */
1051 if (!data)
1052   pdkim_body_complete(ctx);
1053
1054 else for (int p = 0; p < len; p++)
1055   {
1056   uschar c = data[p];
1057   int rc;
1058
1059   if (ctx->flags & PDKIM_PAST_HDRS)
1060     {
1061     if (c == '\n' && !(ctx->flags & PDKIM_SEEN_CR))     /* emulate the CR */
1062       {
1063       ctx->linebuf[ctx->linebuf_offset++] = '\r';
1064       if (ctx->linebuf_offset == PDKIM_MAX_BODY_LINE_LEN-1)
1065         return PDKIM_ERR_LONG_LINE;
1066       }
1067
1068     /* Processing body byte */
1069     ctx->linebuf[ctx->linebuf_offset++] = c;
1070     if (c == '\r')
1071       ctx->flags |= PDKIM_SEEN_CR;
1072     else if (c == '\n')
1073       {
1074       ctx->flags &= ~PDKIM_SEEN_CR;
1075       pdkim_bodyline_complete(ctx);
1076       }
1077
1078     if (ctx->linebuf_offset == PDKIM_MAX_BODY_LINE_LEN-1)
1079       return PDKIM_ERR_LONG_LINE;
1080     }
1081   else
1082     {
1083     /* Processing header byte */
1084     if (c == '\r')
1085       ctx->flags |= PDKIM_SEEN_CR;
1086     else if (c == '\n')
1087       {
1088       if (!(ctx->flags & PDKIM_SEEN_CR))                /* emulate the CR */
1089         ctx->cur_header = string_catn(ctx->cur_header, CUS "\r", 1);
1090
1091       if (ctx->flags & PDKIM_SEEN_LF)           /* Seen last header line */
1092         {
1093         if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1094           return rc;
1095
1096         ctx->flags = (ctx->flags & ~(PDKIM_SEEN_LF|PDKIM_SEEN_CR)) | PDKIM_PAST_HDRS;
1097         DEBUG(D_acl) debug_printf(
1098             "DKIM >> Body data for hash, canonicalized >>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1099         continue;
1100         }
1101       else
1102         ctx->flags = (ctx->flags & ~PDKIM_SEEN_CR) | PDKIM_SEEN_LF;
1103       }
1104     else if (ctx->flags & PDKIM_SEEN_LF)
1105       {
1106       if (!(c == '\t' || c == ' '))                     /* End of header */
1107         if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1108           return rc;
1109       ctx->flags &= ~PDKIM_SEEN_LF;
1110       }
1111
1112     if (!ctx->cur_header || ctx->cur_header->ptr < PDKIM_MAX_HEADER_LEN)
1113       ctx->cur_header = string_catn(ctx->cur_header, CUS &data[p], 1);
1114     }
1115   }
1116 return PDKIM_OK;
1117 }
1118
1119
1120
1121 /* Extend a growing header with a continuation-linebreak */
1122 static gstring *
1123 pdkim_hdr_cont(gstring * str, int * col)
1124 {
1125 *col = 1;
1126 return string_catn(str, US"\r\n\t", 3);
1127 }
1128
1129
1130
1131 /*
1132  * RFC 5322 specifies that header line length SHOULD be no more than 78
1133  *  pdkim_headcat
1134  *
1135  * Returns gstring (not nul-terminated) appending to one supplied
1136  *
1137  * col: this int holds and receives column number (octets since last '\n')
1138  * str: partial string to append to
1139  * pad: padding, split line or space after before or after eg: ";".
1140  *               Only the initial charater is used.
1141  * intro: - must join to payload eg "h=", usually the tag name
1142  * payload: eg base64 data - long data can be split arbitrarily.
1143  *
1144  * this code doesn't fold the header in some of the places that RFC4871
1145  * allows: As per RFC5322(2.2.3) it only folds before or after tag-value
1146  * pairs and inside long values. it also always spaces or breaks after the
1147  * "pad"
1148  *
1149  * No guarantees are made for output given out-of range input. like tag
1150  * names longer than 78, or bogus col. Input is assumed to be free of line breaks.
1151  */
1152
1153 static gstring *
1154 pdkim_headcat(int * col, gstring * str,
1155   const uschar * pad, const uschar * intro, const uschar * payload)
1156 {
1157 int len, chomp, padded = 0;
1158
1159 /* If we can fit at least the pad at the end of current line, do it now.
1160 Otherwise, wrap if there is a pad. */
1161
1162 if (pad)
1163   if (*col + 1 <= 78)
1164     {
1165     str = string_catn(str, pad, 1);
1166     (*col)++;
1167     pad = NULL;
1168     padded = 1;
1169     }
1170   else
1171     str = pdkim_hdr_cont(str, col);
1172
1173 /* Special case: if the whole addition does not fit at the end of the current
1174 line, but could fit on a new line, wrap to give it its full, dedicated line.  */
1175
1176 len = (pad ? 2 : padded)
1177     + (intro ? Ustrlen(intro) : 0)
1178     + (payload ? Ustrlen(payload) : 0);
1179 if (len <= 77 && *col+len > 78)
1180   {
1181   str = pdkim_hdr_cont(str, col);
1182   padded = 0;
1183   }
1184
1185 /* Either we already dealt with the pad or we know there is room */
1186
1187 if (pad)
1188   {
1189   str = string_catn(str, pad, 1);
1190   str = string_catn(str, US" ", 1);
1191   *col += 2;
1192   }
1193 else if (padded && *col < 78)
1194   {
1195   str = string_catn(str, US" ", 1);
1196   (*col)++;
1197   }
1198
1199 /* Call recursively with intro as payload: it gets the same, special treatment
1200 (that is, not split if < 78).  */
1201
1202 if (intro)
1203   str = pdkim_headcat(col, str, NULL, NULL, intro);
1204
1205 if (payload)
1206   for (len = Ustrlen(payload); len; len -= chomp)
1207     {
1208     if (*col >= 78)
1209       str = pdkim_hdr_cont(str, col);
1210     chomp = *col+len > 78 ? 78 - *col : len;
1211     str = string_catn(str, payload, chomp);
1212     *col += chomp;
1213     payload += chomp;
1214     }
1215
1216 return str;
1217 }
1218
1219
1220 /* -------------------------------------------------------------------------- */
1221
1222 /* Signing: create signature header
1223 */
1224 static uschar *
1225 pdkim_create_header(pdkim_signature * sig, BOOL final)
1226 {
1227 uschar * base64_bh;
1228 uschar * base64_b;
1229 int col = 0;
1230 gstring * hdr;
1231 gstring * canon_all;
1232
1233 canon_all = string_cat (NULL, pdkim_canons[sig->canon_headers]);
1234 canon_all = string_catn(canon_all, US"/", 1);
1235 canon_all = string_cat (canon_all, pdkim_canons[sig->canon_body]);
1236 (void) string_from_gstring(canon_all);
1237
1238 hdr = string_cat(NULL, US"DKIM-Signature: v="PDKIM_SIGNATURE_VERSION);
1239 col = hdr->ptr;
1240
1241 /* Required and static bits */
1242 hdr = pdkim_headcat(&col, hdr, US";", US"a=", dkim_sig_to_a_tag(sig));
1243 hdr = pdkim_headcat(&col, hdr, US";", US"q=", pdkim_querymethods[sig->querymethod]);
1244 hdr = pdkim_headcat(&col, hdr, US";", US"c=", canon_all->s);
1245 hdr = pdkim_headcat(&col, hdr, US";", US"d=", sig->domain);
1246 hdr = pdkim_headcat(&col, hdr, US";", US"s=", sig->selector);
1247
1248 /* list of header names can be split between items. */
1249   {
1250   uschar * n = string_copy(sig->headernames);
1251   uschar * i = US"h=";
1252   uschar * s = US";";
1253
1254   while (*n)
1255     {
1256     uschar * c = Ustrchr(n, ':');
1257
1258     if (c) *c ='\0';
1259
1260     if (!i)
1261       hdr = pdkim_headcat(&col, hdr, NULL, NULL, US":");
1262
1263     hdr = pdkim_headcat(&col, hdr, s, i, n);
1264
1265     if (!c)
1266       break;
1267
1268     n = c+1;
1269     s = NULL;
1270     i = NULL;
1271     }
1272   }
1273
1274 base64_bh = pdkim_encode_base64(&sig->calc_body_hash->bh);
1275 hdr = pdkim_headcat(&col, hdr, US";", US"bh=", base64_bh);
1276
1277 /* Optional bits */
1278 if (sig->identity)
1279   hdr = pdkim_headcat(&col, hdr, US";", US"i=", sig->identity);
1280
1281 if (sig->created > 0)
1282   {
1283   uschar minibuf[21];
1284
1285   snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->created);
1286   hdr = pdkim_headcat(&col, hdr, US";", US"t=", minibuf);
1287 }
1288
1289 if (sig->expires > 0)
1290   {
1291   uschar minibuf[21];
1292
1293   snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->expires);
1294   hdr = pdkim_headcat(&col, hdr, US";", US"x=", minibuf);
1295   }
1296
1297 if (sig->bodylength >= 0)
1298   {
1299   uschar minibuf[21];
1300
1301   snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->bodylength);
1302   hdr = pdkim_headcat(&col, hdr, US";", US"l=", minibuf);
1303   }
1304
1305 /* Preliminary or final version? */
1306 if (final)
1307   {
1308   base64_b = pdkim_encode_base64(&sig->sighash);
1309   hdr = pdkim_headcat(&col, hdr, US";", US"b=", base64_b);
1310
1311   /* add trailing semicolon: I'm not sure if this is actually needed */
1312   hdr = pdkim_headcat(&col, hdr, NULL, US";", US"");
1313   }
1314 else
1315   {
1316   /* To satisfy the rule "all surrounding whitespace [...] deleted"
1317   ( RFC 6376 section 3.7 ) we ensure there is no whitespace here.  Otherwise
1318   the headcat routine could insert a linebreak which the relaxer would reduce
1319   to a single space preceding the terminating semicolon, resulting in an
1320   incorrect header-hash. */
1321   hdr = pdkim_headcat(&col, hdr, US";", US"b=;", US"");
1322   }
1323
1324 return string_from_gstring(hdr);
1325 }
1326
1327
1328 /* -------------------------------------------------------------------------- */
1329
1330 /* According to draft-ietf-dcrup-dkim-crypto-07 "keys are 256 bits" (referring
1331 to DNS, hence the pubkey).  Check for more than 32 bytes; if so assume the
1332 alternate possible representation (still) being discussed: a
1333 SubjectPublickeyInfo wrapped key - and drop all but the trailing 32-bytes (it
1334 should be a DER, with exactly 12 leading bytes - but we could accept a BER also,
1335 which could be any size).  We still rely on the crypto library for checking for
1336 undersize.
1337
1338 When the RFC is published this should be re-addressed. */
1339
1340 static void
1341 check_bare_ed25519_pubkey(pdkim_pubkey * p)
1342 {
1343 int excess = p->key.len - 32;
1344 if (excess > 0)
1345   {
1346   DEBUG(D_acl)
1347     debug_printf("DKIM: unexpected pubkey len %lu\n", (unsigned long) p->key.len);
1348   p->key.data += excess; p->key.len = 32;
1349   }
1350 }
1351
1352
1353 static pdkim_pubkey *
1354 pdkim_key_from_dns(pdkim_ctx * ctx, pdkim_signature * sig, ev_ctx * vctx,
1355   const uschar ** errstr)
1356 {
1357 uschar * dns_txt_name, * dns_txt_reply;
1358 pdkim_pubkey * p;
1359
1360 /* Fetch public key for signing domain, from DNS */
1361
1362 dns_txt_name = string_sprintf("%s._domainkey.%s.", sig->selector, sig->domain);
1363
1364 if (  !(dns_txt_reply = ctx->dns_txt_callback(dns_txt_name))
1365    || dns_txt_reply[0] == '\0'
1366    )
1367   {
1368   sig->verify_status =      PDKIM_VERIFY_INVALID;
1369   sig->verify_ext_status =  PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE;
1370   return NULL;
1371   }
1372
1373 DEBUG(D_acl)
1374   {
1375   debug_printf(
1376     "DKIM >> Parsing public key record >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"
1377     " %s\n"
1378     " Raw record: ",
1379     dns_txt_name);
1380   pdkim_quoteprint(CUS dns_txt_reply, Ustrlen(dns_txt_reply));
1381   }
1382
1383 if (  !(p = pdkim_parse_pubkey_record(CUS dns_txt_reply))
1384    || (Ustrcmp(p->srvtype, "*") != 0 && Ustrcmp(p->srvtype, "email") != 0)
1385    )
1386   {
1387   sig->verify_status =      PDKIM_VERIFY_INVALID;
1388   sig->verify_ext_status =  PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD;
1389
1390   DEBUG(D_acl)
1391     {
1392     if (p)
1393       debug_printf(" Invalid public key service type '%s'\n", p->srvtype);
1394     else
1395       debug_printf(" Error while parsing public key record\n");
1396     debug_printf(
1397       "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1398     }
1399   return NULL;
1400   }
1401
1402 DEBUG(D_acl) debug_printf(
1403       "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1404
1405 /* Import public key */
1406
1407 /* Normally we use the signature a= tag to tell us the pubkey format.
1408 When signing under debug we do a test-import of the pubkey, and at that
1409 time we do not have a signature so we must interpret the pubkey k= tag
1410 instead.  Assume writing on the sig is ok in that case. */
1411
1412 if (sig->keytype < 0)
1413   if ((sig->keytype = pdkim_keyname_to_keytype(p->keytype)) < 0)
1414     {
1415     DEBUG(D_acl) debug_printf("verify_init: unhandled keytype %s\n", p->keytype);
1416     sig->verify_status =      PDKIM_VERIFY_INVALID;
1417     sig->verify_ext_status =  PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
1418     return NULL;
1419     }
1420
1421 if (sig->keytype == KEYTYPE_ED25519)
1422   check_bare_ed25519_pubkey(p);
1423
1424 if ((*errstr = exim_dkim_verify_init(&p->key,
1425             sig->keytype == KEYTYPE_ED25519 ? KEYFMT_ED25519_BARE : KEYFMT_DER,
1426             vctx, &sig->keybits)))
1427   {
1428   DEBUG(D_acl) debug_printf("verify_init: %s\n", *errstr);
1429   sig->verify_status =      PDKIM_VERIFY_INVALID;
1430   sig->verify_ext_status =  PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
1431   return NULL;
1432   }
1433
1434 vctx->keytype = sig->keytype;
1435 return p;
1436 }
1437
1438
1439 /* -------------------------------------------------------------------------- */
1440 /* Sort and filter the sigs developed from the message */
1441
1442 static pdkim_signature *
1443 sort_sig_methods(pdkim_signature * siglist)
1444 {
1445 pdkim_signature * yield, ** ss;
1446 const uschar * prefs;
1447 uschar * ele;
1448 int sep;
1449
1450 if (!siglist) return NULL;
1451
1452 /* first select in order of hashtypes */
1453 DEBUG(D_acl) debug_printf("DKIM: dkim_verify_hashes   '%s'\n", dkim_verify_hashes);
1454 for (prefs = dkim_verify_hashes, sep = 0, yield = NULL, ss = &yield;
1455      ele = string_nextinlist(&prefs, &sep, NULL, 0); )
1456   {
1457   int i = pdkim_hashname_to_hashtype(CUS ele, 0);
1458   for (pdkim_signature * s = siglist, * next, ** prev = &siglist; s;
1459        s = next)
1460     {
1461     next = s->next;
1462     if (s->hashtype == i)
1463       { *prev = next; s->next = NULL; *ss = s; ss = &s->next; }
1464     else
1465       prev = &s->next;
1466     }
1467   }
1468
1469 /* then in order of keytypes */
1470 siglist = yield;
1471 DEBUG(D_acl) debug_printf("DKIM: dkim_verify_keytypes '%s'\n", dkim_verify_keytypes);
1472 for (prefs = dkim_verify_keytypes, sep = 0, yield = NULL, ss = &yield;
1473      ele = string_nextinlist(&prefs, &sep, NULL, 0); )
1474   {
1475   int i = pdkim_keyname_to_keytype(CUS ele);
1476   for (pdkim_signature * s = siglist, * next, ** prev = &siglist; s;
1477        s = next)
1478     {
1479     next = s->next;
1480     if (s->keytype == i)
1481       { *prev = next; s->next = NULL; *ss = s; ss = &s->next; }
1482     else
1483       prev = &s->next;
1484     }
1485   }
1486
1487 DEBUG(D_acl) for (pdkim_signature * s = yield; s; s = s->next)
1488   debug_printf(" retain d=%s s=%s a=%s\n",
1489     s->domain, s->selector, dkim_sig_to_a_tag(s));
1490 return yield;
1491 }
1492
1493
1494 /* -------------------------------------------------------------------------- */
1495
1496 DLLEXPORT int
1497 pdkim_feed_finish(pdkim_ctx * ctx, pdkim_signature ** return_signatures,
1498   const uschar ** err)
1499 {
1500 BOOL verify_pass = FALSE;
1501
1502 /* Check if we must still flush a (partial) header. If that is the
1503    case, the message has no body, and we must compute a body hash
1504    out of '<CR><LF>' */
1505 if (ctx->cur_header && ctx->cur_header->ptr > 0)
1506   {
1507   blob * rnl = NULL;
1508   int rc;
1509
1510   if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1511     return rc;
1512
1513   for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
1514     rnl = pdkim_update_ctx_bodyhash(b, &lineending, rnl);
1515   if (rnl) store_free(rnl);
1516   }
1517 else
1518   DEBUG(D_acl) debug_printf(
1519       "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1520
1521 /* Build (and/or evaluate) body hash.  Do this even if no DKIM sigs, in case we
1522 have a hash to do for ARC. */
1523
1524 pdkim_finish_bodyhash(ctx);
1525
1526 /* Sort and filter the recived signatures */
1527
1528 if (!(ctx->flags & PDKIM_MODE_SIGN))
1529   ctx->sig = sort_sig_methods(ctx->sig);
1530
1531 if (!ctx->sig)
1532   {
1533   DEBUG(D_acl) debug_printf("DKIM: no signatures\n");
1534   *return_signatures = NULL;
1535   return PDKIM_OK;
1536   }
1537
1538 for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next)
1539   {
1540   hctx hhash_ctx;
1541   uschar * sig_hdr = US"";
1542   blob hhash;
1543   gstring * hdata = NULL;
1544   es_ctx sctx;
1545
1546   if (  !(ctx->flags & PDKIM_MODE_SIGN)
1547      && sig->verify_status == PDKIM_VERIFY_FAIL)
1548     {
1549     DEBUG(D_acl)
1550        debug_printf("DKIM: [%s] abandoning this signature\n", sig->domain);
1551     continue;
1552     }
1553
1554   /*XXX The hash of the headers is needed for GCrypt (for which we can do RSA
1555   signing only, as it happens) and for either GnuTLS and OpenSSL when we are
1556   signing with EC (specifically, Ed25519).  The former is because the GCrypt
1557   signing operation is pure (does not do its own hash) so we must hash.  The
1558   latter is because we (stupidly, but this is what the IETF draft is saying)
1559   must hash with the declared hash method, then pass the result to the library
1560   hash-and-sign routine (because that's all the libraries are providing.  And
1561   we're stuck with whatever that hidden hash method is, too).  We may as well
1562   do this hash incrementally.
1563   We don't need the hash we're calculating here for the GnuTLS and OpenSSL
1564   cases of RSA signing, since those library routines can do hash-and-sign.
1565
1566   Some time in the future we could easily avoid doing the hash here for those
1567   cases (which will be common for a long while.  We could also change from
1568   the current copy-all-the-headers-into-one-block, then call the hash-and-sign
1569   implementation  - to a proper incremental one.  Unfortunately, GnuTLS just
1570   cannot do incremental - either signing or verification.  Unsure about GCrypt.
1571   */
1572
1573   /*XXX The header hash is also used (so far) by the verify operation */
1574
1575   if (!exim_sha_init(&hhash_ctx, pdkim_hashes[sig->hashtype].exim_hashmethod))
1576     {
1577     log_write(0, LOG_MAIN|LOG_PANIC,
1578       "DKIM: hash setup error, possibly nonhandled hashtype");
1579     break;
1580     }
1581
1582   if (ctx->flags & PDKIM_MODE_SIGN)
1583     DEBUG(D_acl) debug_printf(
1584         "DKIM >> Headers to be signed:                            >>>>>>>>>>>>\n"
1585         " %s\n",
1586         sig->sign_headers);
1587
1588   DEBUG(D_acl) debug_printf(
1589       "DKIM >> Header data for hash, canonicalized (%-7s), in sequence >>\n",
1590         pdkim_canons[sig->canon_headers]);
1591
1592
1593   /* SIGNING ---------------------------------------------------------------- */
1594   /* When signing, walk through our header list and add them to the hash. As we
1595      go, construct a list of the header's names to use for the h= parameter.
1596      Then append to that list any remaining header names for which there was no
1597      header to sign. */
1598
1599   if (ctx->flags & PDKIM_MODE_SIGN)
1600     {
1601     gstring * g = NULL;
1602     const uschar * l;
1603     uschar * s;
1604     int sep = 0;
1605
1606     /* Import private key, including the keytype which we need for building
1607     the signature header  */
1608
1609     if ((*err = exim_dkim_signing_init(CUS sig->privkey, &sctx)))
1610       {
1611       log_write(0, LOG_MAIN|LOG_PANIC, "signing_init: %s", *err);
1612       return PDKIM_ERR_RSA_PRIVKEY;
1613       }
1614     sig->keytype = sctx.keytype;
1615
1616     sig->headernames = NULL;                    /* Collected signed header names */
1617     for (pdkim_stringlist * p = sig->headers; p; p = p->next)
1618       {
1619       uschar * rh = p->value;
1620
1621       if (header_name_match(rh, sig->sign_headers) == PDKIM_OK)
1622         {
1623         /* Collect header names (Note: colon presence is guaranteed here) */
1624         g = string_append_listele_n(g, ':', rh, Ustrchr(rh, ':') - rh);
1625
1626         if (sig->canon_headers == PDKIM_CANON_RELAXED)
1627           rh = pdkim_relax_header(rh, TRUE);    /* cook header for relaxed canon */
1628
1629         /* Feed header to the hash algorithm */
1630         exim_sha_update_string(&hhash_ctx, CUS rh);
1631
1632         /* Remember headers block for signing (when the library cannot do incremental)  */
1633         /*XXX we could avoid doing this for all but the GnuTLS/RSA case */
1634         hdata = exim_dkim_data_append(hdata, rh);
1635
1636         DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1637         }
1638       }
1639
1640     /* Any headers we wanted to sign but were not present must also be listed.
1641     Ignore elements that have been ticked-off or are marked as never-oversign. */
1642
1643     l = sig->sign_headers;
1644     while((s = string_nextinlist(&l, &sep, NULL, 0)))
1645       {
1646       if (*s == '+')                    /* skip oversigning marker */
1647         s++;
1648       if (*s != '_' && *s != '=')
1649         g = string_append_listele(g, ':', s);
1650       }
1651     sig->headernames = string_from_gstring(g);
1652
1653     /* Create signature header with b= omitted */
1654     sig_hdr = pdkim_create_header(sig, FALSE);
1655     }
1656
1657   /* VERIFICATION ----------------------------------------------------------- */
1658   /* When verifying, walk through the header name list in the h= parameter and
1659      add the headers to the hash in that order. */
1660   else
1661     {
1662     uschar * p = sig->headernames;
1663     uschar * q;
1664
1665     if (p)
1666       {
1667       /* clear tags */
1668       for (pdkim_stringlist * hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1669         hdrs->tag = 0;
1670
1671       p = string_copy(p);
1672       while(1)
1673         {
1674         if ((q = Ustrchr(p, ':')))
1675           *q = '\0';
1676
1677   /*XXX walk the list of headers in same order as received. */
1678         for (pdkim_stringlist * hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1679           if (  hdrs->tag == 0
1680              && strncasecmp(CCS hdrs->value, CCS p, Ustrlen(p)) == 0
1681              && (hdrs->value)[Ustrlen(p)] == ':'
1682              )
1683             {
1684             /* cook header for relaxed canon, or just copy it for simple  */
1685
1686             uschar * rh = sig->canon_headers == PDKIM_CANON_RELAXED
1687               ? pdkim_relax_header(hdrs->value, TRUE)
1688               : string_copy(CUS hdrs->value);
1689
1690             /* Feed header to the hash algorithm */
1691             exim_sha_update_string(&hhash_ctx, CUS rh);
1692
1693             DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1694             hdrs->tag = 1;
1695             break;
1696             }
1697
1698         if (!q) break;
1699         p = q+1;
1700         }
1701
1702       sig_hdr = string_copy(sig->rawsig_no_b_val);
1703       }
1704     }
1705
1706   DEBUG(D_acl) debug_printf(
1707             "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1708
1709   DEBUG(D_acl)
1710     {
1711     debug_printf(
1712             "DKIM >> Signed DKIM-Signature header, pre-canonicalized >>>>>>>>>>>>>\n");
1713     pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr));
1714     debug_printf(
1715             "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1716     }
1717
1718   /* Relax header if necessary */
1719   if (sig->canon_headers == PDKIM_CANON_RELAXED)
1720     sig_hdr = pdkim_relax_header(sig_hdr, FALSE);
1721
1722   DEBUG(D_acl)
1723     {
1724     debug_printf("DKIM >> Signed DKIM-Signature header, canonicalized (%-7s) >>>>>>>\n",
1725             pdkim_canons[sig->canon_headers]);
1726     pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr));
1727     debug_printf(
1728             "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1729     }
1730
1731   /* Finalize header hash */
1732   exim_sha_update_string(&hhash_ctx, CUS sig_hdr);
1733   exim_sha_finish(&hhash_ctx, &hhash);
1734
1735   DEBUG(D_acl)
1736     {
1737     debug_printf("DKIM [%s] Header %s computed: ",
1738       sig->domain, pdkim_hashes[sig->hashtype].dkim_hashname);
1739     pdkim_hexprint(hhash.data, hhash.len);
1740     }
1741
1742   /* Remember headers block for signing (when the signing library cannot do
1743   incremental)  */
1744   if (ctx->flags & PDKIM_MODE_SIGN)
1745     hdata = exim_dkim_data_append(hdata, US sig_hdr);
1746
1747   /* SIGNING ---------------------------------------------------------------- */
1748   if (ctx->flags & PDKIM_MODE_SIGN)
1749     {
1750     hashmethod hm = sig->keytype == KEYTYPE_ED25519
1751 #if defined(SIGN_OPENSSL)
1752       ? HASH_NULL
1753 #else
1754       ? HASH_SHA2_512
1755 #endif
1756       : pdkim_hashes[sig->hashtype].exim_hashmethod;
1757
1758 #ifdef SIGN_HAVE_ED25519
1759     /* For GCrypt, and for EC, we pass the hash-of-headers to the signing
1760     routine.  For anything else we just pass the headers. */
1761
1762     if (sig->keytype != KEYTYPE_ED25519)
1763 #endif
1764       {
1765       hhash.data = hdata->s;
1766       hhash.len = hdata->ptr;
1767       }
1768
1769     if ((*err = exim_dkim_sign(&sctx, hm, &hhash, &sig->sighash)))
1770       {
1771       log_write(0, LOG_MAIN|LOG_PANIC, "signing: %s", *err);
1772       return PDKIM_ERR_RSA_SIGNING;
1773       }
1774
1775     DEBUG(D_acl)
1776       {
1777       debug_printf( "DKIM [%s] b computed: ", sig->domain);
1778       pdkim_hexprint(sig->sighash.data, sig->sighash.len);
1779       }
1780
1781     sig->signature_header = pdkim_create_header(sig, TRUE);
1782     }
1783
1784   /* VERIFICATION ----------------------------------------------------------- */
1785   else
1786     {
1787     ev_ctx vctx;
1788     hashmethod hm;
1789
1790     /* Make sure we have all required signature tags */
1791     if (!(  sig->domain        && *sig->domain
1792          && sig->selector      && *sig->selector
1793          && sig->headernames   && *sig->headernames
1794          && sig->bodyhash.data
1795          && sig->sighash.data
1796          && sig->keytype >= 0
1797          && sig->hashtype >= 0
1798          && sig->version
1799        ) )
1800       {
1801       sig->verify_status     = PDKIM_VERIFY_INVALID;
1802       sig->verify_ext_status = PDKIM_VERIFY_INVALID_SIGNATURE_ERROR;
1803
1804       DEBUG(D_acl) debug_printf(
1805           " Error in DKIM-Signature header: tags missing or invalid (%s)\n"
1806           "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
1807           !(sig->domain && *sig->domain) ? "d="
1808           : !(sig->selector && *sig->selector) ? "s="
1809           : !(sig->headernames && *sig->headernames) ? "h="
1810           : !sig->bodyhash.data ? "bh="
1811           : !sig->sighash.data ? "b="
1812           : sig->keytype < 0 || sig->hashtype < 0 ? "a="
1813           : "v="
1814           );
1815       goto NEXT_VERIFY;
1816       }
1817
1818     /* Make sure sig uses supported DKIM version (only v1) */
1819     if (sig->version != 1)
1820       {
1821       sig->verify_status     = PDKIM_VERIFY_INVALID;
1822       sig->verify_ext_status = PDKIM_VERIFY_INVALID_DKIM_VERSION;
1823
1824       DEBUG(D_acl) debug_printf(
1825           " Error in DKIM-Signature header: unsupported DKIM version\n"
1826           "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1827       goto NEXT_VERIFY;
1828       }
1829
1830     DEBUG(D_acl)
1831       {
1832       debug_printf( "DKIM [%s] b from mail: ", sig->domain);
1833       pdkim_hexprint(sig->sighash.data, sig->sighash.len);
1834       }
1835
1836     if (!(sig->pubkey = pdkim_key_from_dns(ctx, sig, &vctx, err)))
1837       {
1838       log_write(0, LOG_MAIN, "DKIM: %s%s %s%s [failed key import]",
1839         sig->domain   ? "d=" : "", sig->domain   ? sig->domain   : US"",
1840         sig->selector ? "s=" : "", sig->selector ? sig->selector : US"");
1841       goto NEXT_VERIFY;
1842       }
1843
1844     /* If the pubkey limits to a list of specific hashes, ignore sigs that
1845     do not have the hash part of the sig algorithm matching */
1846
1847     if (sig->pubkey->hashes)
1848       {
1849       const uschar * list = sig->pubkey->hashes, * ele;
1850       int sep = ':';
1851       while ((ele = string_nextinlist(&list, &sep, NULL, 0)))
1852         if (Ustrcmp(ele, pdkim_hashes[sig->hashtype].dkim_hashname) == 0) break;
1853       if (!ele)
1854         {
1855         DEBUG(D_acl) debug_printf("pubkey h=%s vs. sig a=%s_%s\n",
1856           sig->pubkey->hashes,
1857           pdkim_keytypes[sig->keytype],
1858           pdkim_hashes[sig->hashtype].dkim_hashname);
1859         sig->verify_status =      PDKIM_VERIFY_FAIL;
1860         sig->verify_ext_status =  PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH;
1861         goto NEXT_VERIFY;
1862         }
1863       }
1864
1865     hm = sig->keytype == KEYTYPE_ED25519
1866 #if defined(SIGN_OPENSSL)
1867       ? HASH_NULL
1868 #else
1869       ? HASH_SHA2_512
1870 #endif
1871       : pdkim_hashes[sig->hashtype].exim_hashmethod;
1872
1873     /* Check the signature */
1874
1875     if ((*err = exim_dkim_verify(&vctx, hm, &hhash, &sig->sighash)))
1876       {
1877       DEBUG(D_acl) debug_printf("headers verify: %s\n", *err);
1878       sig->verify_status =      PDKIM_VERIFY_FAIL;
1879       sig->verify_ext_status =  PDKIM_VERIFY_FAIL_MESSAGE;
1880       goto NEXT_VERIFY;
1881       }
1882     if (*dkim_verify_min_keysizes)
1883       {
1884       unsigned minbits;
1885       const uschar * ss = expand_getkeyed(US pdkim_keytypes[sig->keytype],
1886                                     dkim_verify_min_keysizes);
1887       if (ss &&  (minbits = atoi(CCS ss)) > sig->keybits)
1888         {
1889         DEBUG(D_acl) debug_printf("Key too short: Actual: %s %u  Minima '%s'\n",
1890           pdkim_keytypes[sig->keytype], sig->keybits, dkim_verify_min_keysizes);
1891         sig->verify_status =      PDKIM_VERIFY_FAIL;
1892         sig->verify_ext_status =  PDKIM_VERIFY_INVALID_PUBKEY_KEYSIZE;
1893         }
1894       }
1895
1896
1897     /* We have a winner! (if bodyhash was correct earlier) */
1898     if (sig->verify_status == PDKIM_VERIFY_NONE)
1899       {
1900       sig->verify_status = PDKIM_VERIFY_PASS;
1901       verify_pass = TRUE;
1902       if (dkim_verify_minimal) break;
1903       }
1904
1905 NEXT_VERIFY:
1906
1907     DEBUG(D_acl)
1908       {
1909       debug_printf("DKIM [%s] %s signature status: %s",
1910               sig->domain, dkim_sig_to_a_tag(sig),
1911               pdkim_verify_status_str(sig->verify_status));
1912       if (sig->verify_ext_status > 0)
1913         debug_printf(" (%s)\n",
1914                 pdkim_verify_ext_status_str(sig->verify_ext_status));
1915       else
1916         debug_printf("\n");
1917       }
1918     }
1919   }
1920
1921 /* If requested, set return pointer to signature(s) */
1922 if (return_signatures)
1923   *return_signatures = ctx->sig;
1924
1925 return ctx->flags & PDKIM_MODE_SIGN  ||  verify_pass
1926   ? PDKIM_OK : PDKIM_FAIL;
1927 }
1928
1929
1930 /* -------------------------------------------------------------------------- */
1931
1932 DLLEXPORT pdkim_ctx *
1933 pdkim_init_verify(uschar * (*dns_txt_callback)(const uschar *), BOOL dot_stuffing)
1934 {
1935 pdkim_ctx * ctx;
1936
1937 ctx = store_get(sizeof(pdkim_ctx), GET_UNTAINTED);
1938 memset(ctx, 0, sizeof(pdkim_ctx));
1939
1940 if (dot_stuffing) ctx->flags = PDKIM_DOT_TERM;
1941 /* The line-buffer is for message data, hence tainted */
1942 ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN, GET_TAINTED);
1943 ctx->dns_txt_callback = dns_txt_callback;
1944 ctx->cur_header = string_get_tainted(36, GET_TAINTED);
1945
1946 return ctx;
1947 }
1948
1949
1950 /* -------------------------------------------------------------------------- */
1951
1952 DLLEXPORT pdkim_signature *
1953 pdkim_init_sign(pdkim_ctx * ctx,
1954   uschar * domain, uschar * selector, uschar * privkey,
1955   uschar * hashname, const uschar ** errstr)
1956 {
1957 int hashtype;
1958 pdkim_signature * sig;
1959
1960 if (!domain || !selector || !privkey)
1961   return NULL;
1962
1963 /* Allocate & init one signature struct */
1964
1965 sig = store_get(sizeof(pdkim_signature), GET_UNTAINTED);
1966 memset(sig, 0, sizeof(pdkim_signature));
1967
1968 sig->bodylength = -1;
1969
1970 sig->domain = string_copy(US domain);
1971 sig->selector = string_copy(US selector);
1972 sig->privkey = string_copy(US privkey);
1973 sig->keytype = -1;
1974
1975 for (hashtype = 0; hashtype < nelem(pdkim_hashes); hashtype++)
1976   if (Ustrcmp(hashname, pdkim_hashes[hashtype].dkim_hashname) == 0)
1977   { sig->hashtype = hashtype; break; }
1978 if (hashtype >= nelem(pdkim_hashes))
1979   {
1980   log_write(0, LOG_MAIN|LOG_PANIC,
1981     "DKIM: unrecognised hashname '%s'", hashname);
1982   return NULL;
1983   }
1984
1985 DEBUG(D_acl)
1986   {
1987   pdkim_signature s = *sig;
1988   ev_ctx vctx;
1989
1990   debug_printf("DKIM (checking verify key)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1991   if (!pdkim_key_from_dns(ctx, &s, &vctx, errstr))
1992     debug_printf("WARNING: bad dkim key in dns\n");
1993   debug_printf("DKIM (finished checking verify key)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1994   }
1995 return sig;
1996 }
1997
1998
1999 /* -------------------------------------------------------------------------- */
2000
2001 DLLEXPORT void
2002 pdkim_set_optional(pdkim_signature * sig,
2003                        char * sign_headers,
2004                        char * identity,
2005                        int canon_headers,
2006                        int canon_body,
2007                        long bodylength,
2008                        unsigned long created,
2009                        unsigned long expires)
2010 {
2011 if (identity)
2012   sig->identity = string_copy(US identity);
2013
2014 sig->sign_headers = string_copy(sign_headers
2015         ? US sign_headers : US PDKIM_DEFAULT_SIGN_HEADERS);
2016
2017 sig->canon_headers = canon_headers;
2018 sig->canon_body = canon_body;
2019 sig->bodylength = bodylength;
2020 sig->created = created;
2021 sig->expires = expires;
2022
2023 return;
2024 }
2025
2026
2027
2028 /* Set up a blob for calculating the bodyhash according to the
2029 given needs.  Use an existing one if possible, or create a new one.
2030
2031 Return: hashblob pointer, or NULL on error
2032 */
2033 pdkim_bodyhash *
2034 pdkim_set_bodyhash(pdkim_ctx * ctx, int hashtype, int canon_method,
2035         long bodylength)
2036 {
2037 pdkim_bodyhash * b;
2038
2039 if (hashtype == -1 || canon_method == -1) return NULL;
2040
2041 for (b = ctx->bodyhash; b; b = b->next)
2042   if (  hashtype == b->hashtype
2043      && canon_method == b->canon_method
2044      && bodylength == b->bodylength)
2045     {
2046     DEBUG(D_receive) debug_printf("DKIM: using existing bodyhash %s/%s/%ld\n",
2047       pdkim_hashes[hashtype].dkim_hashname, pdkim_canons[canon_method], bodylength);
2048     return b;
2049     }
2050
2051 DEBUG(D_receive) debug_printf("DKIM: new bodyhash %s/%s/%ld\n",
2052     pdkim_hashes[hashtype].dkim_hashname, pdkim_canons[canon_method], bodylength);
2053 b = store_get(sizeof(pdkim_bodyhash), GET_UNTAINTED);
2054 b->next = ctx->bodyhash;
2055 b->hashtype = hashtype;
2056 b->canon_method = canon_method;
2057 b->bodylength = bodylength;
2058 if (!exim_sha_init(&b->body_hash_ctx,           /*XXX hash method: extend for sha512 */
2059                   pdkim_hashes[hashtype].exim_hashmethod))
2060   {
2061   DEBUG(D_acl)
2062     debug_printf("DKIM: hash init error, possibly nonhandled hashtype\n");
2063   return NULL;
2064   }
2065 b->signed_body_bytes = 0;
2066 b->num_buffered_blanklines = 0;
2067 ctx->bodyhash = b;
2068 return b;
2069 }
2070
2071
2072 /* Set up a blob for calculating the bodyhash according to the
2073 needs of this signature.  Use an existing one if possible, or
2074 create a new one.
2075
2076 Return: hashblob pointer, or NULL on error (only used as a boolean).
2077 */
2078 pdkim_bodyhash *
2079 pdkim_set_sig_bodyhash(pdkim_ctx * ctx, pdkim_signature * sig)
2080 {
2081 pdkim_bodyhash * b = pdkim_set_bodyhash(ctx,
2082                         sig->hashtype, sig->canon_body, sig->bodylength);
2083 sig->calc_body_hash = b;
2084 return b;
2085 }
2086
2087
2088 /* -------------------------------------------------------------------------- */
2089
2090
2091 void
2092 pdkim_init_context(pdkim_ctx * ctx, BOOL dot_stuffed,
2093   uschar * (*dns_txt_callback)(const uschar *))
2094 {
2095 memset(ctx, 0, sizeof(pdkim_ctx));
2096 ctx->flags = dot_stuffed ? PDKIM_MODE_SIGN | PDKIM_DOT_TERM : PDKIM_MODE_SIGN;
2097 /* The line buffer is for message data, hence tainted */
2098 ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN, GET_TAINTED);
2099 DEBUG(D_acl) ctx->dns_txt_callback = dns_txt_callback;
2100 }
2101
2102
2103 void
2104 pdkim_init(void)
2105 {
2106 exim_dkim_init();
2107 }
2108
2109
2110
2111 #endif  /*DISABLE_DKIM*/