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