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