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