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