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