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