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