b884671da9867888e04ffb6362e24a1543abad68
[users/jgh/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;
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       /* We must have both tag and value, and tags must be one char except
494       for the possibility of "bh". */
495
496       if (  cur_tag && cur_val
497          && (cur_tag->ptr == 1 || *cur_tag->s == 'b')
498          )
499         {
500         (void) string_from_gstring(cur_val);
501         pdkim_strtrim(cur_val);
502
503         DEBUG(D_acl) debug_printf(" %s=%s\n", cur_tag->s, cur_val->s);
504
505         switch (*cur_tag->s)
506           {
507           case 'b':
508             switch (cur_tag->s[1])
509               {
510               case '\0': pdkim_decode_base64(cur_val->s, &sig->sighash); break;
511               case 'h':  if (cur_tag->ptr == 2)
512                            pdkim_decode_base64(cur_val->s, &sig->bodyhash);
513                          break;
514               default:   break;
515               }
516             break;
517           case 'v':
518               /* We only support version 1, and that is currently the
519                  only version there is. */
520             sig->version =
521               Ustrcmp(cur_val->s, PDKIM_SIGNATURE_VERSION) == 0 ? 1 : -1;
522             break;
523           case 'a':
524             {
525             uschar * s = Ustrchr(cur_val->s, '-');
526
527             for(i = 0; i < nelem(pdkim_keytypes); i++)
528               if (Ustrncmp(cur_val->s, pdkim_keytypes[i], s - cur_val->s) == 0)
529                 { sig->keytype = i; break; }
530             for (++s, i = 0; i < nelem(pdkim_hashes); i++)
531               if (Ustrcmp(s, pdkim_hashes[i].dkim_hashname) == 0)
532                 { sig->hashtype = i; break; }
533             break;
534             }
535
536           case 'c':
537             for (i = 0; pdkim_combined_canons[i].str; i++)
538               if (Ustrcmp(cur_val->s, pdkim_combined_canons[i].str) == 0)
539                 {
540                 sig->canon_headers = pdkim_combined_canons[i].canon_headers;
541                 sig->canon_body    = pdkim_combined_canons[i].canon_body;
542                 break;
543                 }
544             break;
545           case 'q':
546             for (i = 0; pdkim_querymethods[i]; i++)
547               if (Ustrcmp(cur_val->s, pdkim_querymethods[i]) == 0)
548                 {
549                 sig->querymethod = i;
550                 break;
551                 }
552             break;
553           case 's':
554             sig->selector = string_copyn(cur_val->s, cur_val->ptr); break;
555           case 'd':
556             sig->domain = string_copyn(cur_val->s, cur_val->ptr); break;
557           case 'i':
558             sig->identity = pdkim_decode_qp(cur_val->s); break;
559           case 't':
560             sig->created = strtoul(CS cur_val->s, NULL, 10); break;
561           case 'x':
562             sig->expires = strtoul(CS cur_val->s, NULL, 10); break;
563           case 'l':
564             sig->bodylength = strtol(CS cur_val->s, NULL, 10); break;
565           case 'h':
566             sig->headernames = string_copyn(cur_val->s, cur_val->ptr); break;
567           case 'z':
568             sig->copiedheaders = pdkim_decode_qp(cur_val->s); break;
569           default:
570             DEBUG(D_acl) debug_printf(" Unknown tag encountered\n");
571             break;
572           }
573         }
574       cur_tag = cur_val = NULL;
575       in_b_val = FALSE;
576       where = PDKIM_HDR_LIMBO;
577       }
578     else
579       cur_val = string_catn(cur_val, p, 1);
580     }
581
582 NEXT_CHAR:
583   if (c == '\0')
584     break;
585
586   if (!in_b_val)
587     *q++ = c;
588   }
589
590 *q = '\0';
591 /* Chomp raw header. The final newline must not be added to the signature. */
592 while (--q > sig->rawsig_no_b_val  && (*q == '\r' || *q == '\n'))
593   *q = '\0';
594
595 DEBUG(D_acl)
596   {
597   debug_printf(
598           "PDKIM >> Raw signature w/o b= tag value >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
599   pdkim_quoteprint(US sig->rawsig_no_b_val, Ustrlen(sig->rawsig_no_b_val));
600   debug_printf(
601           "PDKIM >> Sig size: %4u bits\n", (unsigned) sig->sighash.len*8);
602   debug_printf(
603           "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
604   }
605
606 /*XXX hash method: extend for sha512 */
607 if (!exim_sha_init(&sig->body_hash_ctx,
608                pdkim_hashes[sig->hashtype].exim_hashmethod))
609   {
610   DEBUG(D_acl)
611     debug_printf("PDKIM: hash init error, possibly nonhandled hashtype\n");
612   return NULL;
613   }
614 return sig;
615 }
616
617
618 /* -------------------------------------------------------------------------- */
619
620 static pdkim_pubkey *
621 pdkim_parse_pubkey_record(pdkim_ctx *ctx, const uschar *raw_record)
622 {
623 const uschar * ele;
624 int sep = ';';
625 pdkim_pubkey * pub;
626
627 pub = store_get(sizeof(pdkim_pubkey));
628 memset(pub, 0, sizeof(pdkim_pubkey));
629
630 while ((ele = string_nextinlist(&raw_record, &sep, NULL, 0)))
631   {
632   const uschar * val;
633
634   if ((val = Ustrchr(ele, '=')))
635     {
636     int taglen = val++ - ele;
637
638     DEBUG(D_acl) debug_printf(" %.*s=%s\n", taglen, ele, val);
639     switch (ele[0])
640       {
641       case 'v': pub->version = val;                     break;
642       case 'h': pub->hashes = val;                      break;
643       case 'k': break;
644       case 'g': pub->granularity = val;                 break;
645       case 'n': pub->notes = pdkim_decode_qp(val);      break;
646       case 'p': pdkim_decode_base64(val, &pub->key);    break;
647       case 's': pub->srvtype = val;                     break;
648       case 't': if (Ustrchr(val, 'y')) pub->testing = 1;
649                 if (Ustrchr(val, 's')) pub->no_subdomaining = 1;
650                 break;
651       default:  DEBUG(D_acl) debug_printf(" Unknown tag encountered\n"); break;
652       }
653     }
654   }
655
656 /* Set fallback defaults */
657 if (!pub->version    ) pub->version     = string_copy(PDKIM_PUB_RECORD_VERSION);
658 else if (Ustrcmp(pub->version, PDKIM_PUB_RECORD_VERSION) != 0)
659   {
660   DEBUG(D_acl) debug_printf(" Bad v= field\n");
661   return NULL;
662   }
663
664 if (!pub->granularity) pub->granularity = US"*";
665 /*
666 if (!pub->keytype    ) pub->keytype     = US"rsa";
667 */
668 if (!pub->srvtype    ) pub->srvtype     = US"*";
669
670 /* p= is required */
671 if (pub->key.data)
672   return pub;
673
674 DEBUG(D_acl) debug_printf(" Missing p= field\n");
675 return NULL;
676 }
677
678
679 /* -------------------------------------------------------------------------- */
680
681 /* Update the bodyhash for one sig, with some additional data.
682 If we have to relax the data for this sig, return our copy of it. */
683
684 /*XXX Currently we calculate a hash for each sig.  But it is possible
685 that multi-signing will be wanted using different signing algos
686 (rsa, ec) using the same hash and canonicalization.  Consider in future
687 hanging the hash+cacnon from the ctx and only referencing from the sig,
688 so that it can be calculated only once - being over the body this
689 caould be meagbytes, hence expensive. */
690
691 static blob *
692 pdkim_update_sig_bodyhash(pdkim_signature * sig, blob * orig_data, blob * relaxed_data)
693 {
694 blob * canon_data = orig_data;
695 /* Defaults to simple canon (no further treatment necessary) */
696
697 if (sig->canon_body == PDKIM_CANON_RELAXED)
698   {
699   /* Relax the line if not done already */
700   if (!relaxed_data)
701     {
702     BOOL seen_wsp = FALSE;
703     const uschar * p;
704     int q = 0;
705
706     /* We want to be able to free this else we allocate
707     for the entire message which could be many MB. Since
708     we don't know what allocations the SHA routines might
709     do, not safe to use store_get()/store_reset(). */
710
711     relaxed_data = store_malloc(sizeof(blob) + orig_data->len+1);
712     relaxed_data->data = US (relaxed_data+1);
713
714     for (p = orig_data->data; *p; p++)
715       {
716       char c = *p;
717       if (c == '\r')
718         {
719         if (q > 0 && relaxed_data->data[q-1] == ' ')
720           q--;
721         }
722       else if (c == '\t' || c == ' ')
723         {
724         c = ' '; /* Turns WSP into SP */
725         if (seen_wsp)
726           continue;
727         seen_wsp = TRUE;
728         }
729       else
730         seen_wsp = FALSE;
731       relaxed_data->data[q++] = c;
732       }
733     relaxed_data->data[q] = '\0';
734     relaxed_data->len = q;
735     }
736   canon_data = relaxed_data;
737   }
738
739 /* Make sure we don't exceed the to-be-signed body length */
740 if (  sig->bodylength >= 0
741    && sig->signed_body_bytes + (unsigned long)canon_data->len > sig->bodylength
742    )
743   canon_data->len = sig->bodylength - sig->signed_body_bytes;
744
745 if (canon_data->len > 0)
746   {
747   exim_sha_update(&sig->body_hash_ctx, CUS canon_data->data, canon_data->len);
748   sig->signed_body_bytes += canon_data->len;
749   DEBUG(D_acl) pdkim_quoteprint(canon_data->data, canon_data->len);
750   }
751
752 return relaxed_data;
753 }
754
755
756 /* -------------------------------------------------------------------------- */
757
758 static void
759 pdkim_finish_bodyhash(pdkim_ctx * ctx)
760 {
761 pdkim_signature * sig;
762
763 /* Traverse all signatures */
764 for (sig = ctx->sig; sig; sig = sig->next)
765   {                                     /* Finish hashes */
766   blob bh;
767
768   exim_sha_finish(&sig->body_hash_ctx, &bh);
769
770   DEBUG(D_acl)
771     {
772     debug_printf("PDKIM [%s] Body bytes hashed: %lu\n"
773                  "PDKIM [%s] Body %s computed: ",
774                 sig->domain, sig->signed_body_bytes,
775                 sig->domain, pdkim_hashes[sig->hashtype].dkim_hashname);
776     pdkim_hexprint(CUS bh.data, bh.len);
777     }
778
779   /* SIGNING -------------------------------------------------------------- */
780   if (ctx->flags & PDKIM_MODE_SIGN)
781     {
782     sig->bodyhash = bh;
783
784     /* If bodylength limit is set, and we have received less bytes
785        than the requested amount, effectively remove the limit tag. */
786     if (sig->signed_body_bytes < sig->bodylength)
787       sig->bodylength = -1;
788     }
789
790   else
791   /* VERIFICATION --------------------------------------------------------- */
792   /* Be careful that the header sig included a bodyash */
793
794     if (sig->bodyhash.data && memcmp(bh.data, sig->bodyhash.data, bh.len) == 0)
795       {
796       DEBUG(D_acl) debug_printf("PDKIM [%s] Body hash verified OK\n", sig->domain);
797       }
798     else
799       {
800       DEBUG(D_acl)
801         {
802         debug_printf("PDKIM [%s] Body hash signature from headers: ", sig->domain);
803         pdkim_hexprint(sig->bodyhash.data, sig->bodyhash.len);
804         debug_printf("PDKIM [%s] Body hash did NOT verify\n", sig->domain);
805         }
806       sig->verify_status     = PDKIM_VERIFY_FAIL;
807       sig->verify_ext_status = PDKIM_VERIFY_FAIL_BODY;
808       }
809   }
810 }
811
812
813
814 static void
815 pdkim_body_complete(pdkim_ctx * ctx)
816 {
817 pdkim_signature * sig;
818
819 /* In simple body mode, if any empty lines were buffered,
820 replace with one. rfc 4871 3.4.3 */
821 /*XXX checking the signed-body-bytes is a gross hack; I think
822 it indicates that all linebreaks should be buffered, including
823 the one terminating a text line */
824
825 for (sig = ctx->sig; sig; sig = sig->next)
826   if (  sig->canon_body == PDKIM_CANON_SIMPLE
827      && sig->signed_body_bytes == 0
828      && sig->num_buffered_blanklines > 0
829      )
830     (void) pdkim_update_sig_bodyhash(sig, &lineending, NULL);
831
832 ctx->flags |= PDKIM_SEEN_EOD;
833 ctx->linebuf_offset = 0;
834 }
835
836
837
838 /* -------------------------------------------------------------------------- */
839 /* Call from pdkim_feed below for processing complete body lines */
840
841 static void
842 pdkim_bodyline_complete(pdkim_ctx * ctx)
843 {
844 blob line = {.data = ctx->linebuf, .len = ctx->linebuf_offset};
845 pdkim_signature * sig;
846 blob * rnl = NULL;
847 blob * rline = NULL;
848
849 /* Ignore extra data if we've seen the end-of-data marker */
850 if (ctx->flags & PDKIM_SEEN_EOD) goto all_skip;
851
852 /* We've always got one extra byte to stuff a zero ... */
853 ctx->linebuf[line.len] = '\0';
854
855 /* Terminate on EOD marker */
856 if (ctx->flags & PDKIM_DOT_TERM)
857   {
858   if (memcmp(line.data, ".\r\n", 3) == 0)
859     { pdkim_body_complete(ctx); return; }
860
861   /* Unstuff dots */
862   if (memcmp(line.data, "..", 2) == 0)
863     { line.data++; line.len--; }
864   }
865
866 /* Empty lines need to be buffered until we find a non-empty line */
867 if (memcmp(line.data, "\r\n", 2) == 0)
868   {
869   for (sig = ctx->sig; sig; sig = sig->next) sig->num_buffered_blanklines++;
870   goto all_skip;
871   }
872
873 /* Process line for each sig separately */
874 for (sig = ctx->sig; sig; sig = sig->next)
875   {
876   if (sig->canon_body == PDKIM_CANON_RELAXED)
877     {
878     /* Lines with just spaces need to be buffered too */
879     uschar * cp = line.data;
880     char c;
881
882     while ((c = *cp))
883       {
884       if (c == '\r' && cp[1] == '\n') break;
885       if (c != ' ' && c != '\t') goto sig_process;
886       cp++;
887       }
888
889     sig->num_buffered_blanklines++;
890     goto sig_skip;
891     }
892
893 sig_process:
894   /* At this point, we have a non-empty line, so release the buffered ones. */
895
896   while (sig->num_buffered_blanklines)
897     {
898     rnl = pdkim_update_sig_bodyhash(sig, &lineending, rnl);
899     sig->num_buffered_blanklines--;
900     }
901
902   rline = pdkim_update_sig_bodyhash(sig, &line, rline);
903 sig_skip: ;
904   }
905
906 if (rnl) store_free(rnl);
907 if (rline) store_free(rline);
908
909 all_skip:
910
911 ctx->linebuf_offset = 0;
912 return;
913 }
914
915
916 /* -------------------------------------------------------------------------- */
917 /* Callback from pdkim_feed below for processing complete headers */
918 #define DKIM_SIGNATURE_HEADERNAME "DKIM-Signature:"
919
920 static int
921 pdkim_header_complete(pdkim_ctx * ctx)
922 {
923 pdkim_signature * sig, * last_sig;
924
925 /* Special case: The last header can have an extra \r appended */
926 if ( (ctx->cur_header->ptr > 1) &&
927      (ctx->cur_header->s[ctx->cur_header->ptr-1] == '\r') )
928   --ctx->cur_header->ptr;
929 (void) string_from_gstring(ctx->cur_header);
930
931 if (++ctx->num_headers > PDKIM_MAX_HEADERS) goto BAIL;
932
933 /* SIGNING -------------------------------------------------------------- */
934 if (ctx->flags & PDKIM_MODE_SIGN)
935   for (sig = ctx->sig; sig; sig = sig->next)                    /* Traverse all signatures */
936
937     /* Add header to the signed headers list (in reverse order) */
938     sig->headers = pdkim_prepend_stringlist(sig->headers, ctx->cur_header->s);
939
940 /* VERIFICATION ----------------------------------------------------------- */
941 /* DKIM-Signature: headers are added to the verification list */
942 else
943   {
944 #ifdef notdef
945   DEBUG(D_acl)
946     {
947     debug_printf("PDKIM >> raw hdr: ");
948     pdkim_quoteprint(CUS ctx->cur_header->s, ctx->cur_header->ptr);
949     }
950 #endif
951   if (strncasecmp(CCS ctx->cur_header->s,
952                   DKIM_SIGNATURE_HEADERNAME,
953                   Ustrlen(DKIM_SIGNATURE_HEADERNAME)) == 0)
954     {
955     /* Create and chain new signature block.  We could error-check for all
956     required tags here, but prefer to create the internal sig and expicitly
957     fail verification of it later. */
958
959     DEBUG(D_acl) debug_printf(
960         "PDKIM >> Found sig, trying to parse >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
961
962     sig = pdkim_parse_sig_header(ctx, ctx->cur_header->s);
963
964     if (!(last_sig = ctx->sig))
965       ctx->sig = sig;
966     else
967       {
968       while (last_sig->next) last_sig = last_sig->next;
969       last_sig->next = sig;
970       }
971     }
972
973   /* all headers are stored for signature verification */
974   ctx->headers = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->s);
975   }
976
977 BAIL:
978 ctx->cur_header->s[ctx->cur_header->ptr = 0] = '\0';    /* leave buffer for reuse */
979 return PDKIM_OK;
980 }
981
982
983
984 /* -------------------------------------------------------------------------- */
985 #define HEADER_BUFFER_FRAG_SIZE 256
986
987 DLLEXPORT int
988 pdkim_feed(pdkim_ctx * ctx, uschar * data, int len)
989 {
990 int p, rc;
991
992 /* Alternate EOD signal, used in non-dotstuffing mode */
993 if (!data)
994   pdkim_body_complete(ctx);
995
996 else for (p = 0; p<len; p++)
997   {
998   uschar c = data[p];
999
1000   if (ctx->flags & PDKIM_PAST_HDRS)
1001     {
1002     if (c == '\n' && !(ctx->flags & PDKIM_SEEN_CR))     /* emulate the CR */
1003       {
1004       ctx->linebuf[ctx->linebuf_offset++] = '\r';
1005       if (ctx->linebuf_offset == PDKIM_MAX_BODY_LINE_LEN-1)
1006         return PDKIM_ERR_LONG_LINE;
1007       }
1008
1009     /* Processing body byte */
1010     ctx->linebuf[ctx->linebuf_offset++] = c;
1011     if (c == '\r')
1012       ctx->flags |= PDKIM_SEEN_CR;
1013     else if (c == '\n')
1014       {
1015       ctx->flags &= ~PDKIM_SEEN_CR;
1016       pdkim_bodyline_complete(ctx);
1017       }
1018
1019     if (ctx->linebuf_offset == PDKIM_MAX_BODY_LINE_LEN-1)
1020       return PDKIM_ERR_LONG_LINE;
1021     }
1022   else
1023     {
1024     /* Processing header byte */
1025     if (c == '\r')
1026       ctx->flags |= PDKIM_SEEN_CR;
1027     else if (c == '\n')
1028       {
1029       if (!(ctx->flags & PDKIM_SEEN_CR))                /* emulate the CR */
1030         ctx->cur_header = string_catn(ctx->cur_header, CUS "\r", 1);
1031
1032       if (ctx->flags & PDKIM_SEEN_LF)           /* Seen last header line */
1033         {
1034         if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1035           return rc;
1036
1037         ctx->flags = (ctx->flags & ~(PDKIM_SEEN_LF|PDKIM_SEEN_CR)) | PDKIM_PAST_HDRS;
1038         DEBUG(D_acl) debug_printf(
1039             "PDKIM >> Body data for hash, canonicalized >>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1040         continue;
1041         }
1042       else
1043         ctx->flags = (ctx->flags & ~PDKIM_SEEN_CR) | PDKIM_SEEN_LF;
1044       }
1045     else if (ctx->flags & PDKIM_SEEN_LF)
1046       {
1047       if (!(c == '\t' || c == ' '))                     /* End of header */
1048         if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1049           return rc;
1050       ctx->flags &= ~PDKIM_SEEN_LF;
1051       }
1052
1053     if (!ctx->cur_header || ctx->cur_header->ptr < PDKIM_MAX_HEADER_LEN)
1054       ctx->cur_header = string_catn(ctx->cur_header, CUS &data[p], 1);
1055     }
1056   }
1057 return PDKIM_OK;
1058 }
1059
1060
1061
1062 /* Extend a growing header with a continuation-linebreak */
1063 static gstring *
1064 pdkim_hdr_cont(gstring * str, int * col)
1065 {
1066 *col = 1;
1067 return string_catn(str, US"\r\n\t", 3);
1068 }
1069
1070
1071
1072 /*
1073  * RFC 5322 specifies that header line length SHOULD be no more than 78
1074  * lets make it so!
1075  *  pdkim_headcat
1076  *
1077  * returns uschar * (not nul-terminated)
1078  *
1079  * col: this int holds and receives column number (octets since last '\n')
1080  * str: partial string to append to
1081  * pad: padding, split line or space after before or after eg: ";"
1082  * intro: - must join to payload eg "h=", usually the tag name
1083  * payload: eg base64 data - long data can be split arbitrarily.
1084  *
1085  * this code doesn't fold the header in some of the places that RFC4871
1086  * allows: As per RFC5322(2.2.3) it only folds before or after tag-value
1087  * pairs and inside long values. it also always spaces or breaks after the
1088  * "pad"
1089  *
1090  * no guarantees are made for output given out-of range input. like tag
1091  * names longer than 78, or bogus col. Input is assumed to be free of line breaks.
1092  */
1093
1094 static gstring *
1095 pdkim_headcat(int * col, gstring * str,
1096   const uschar * pad, const uschar * intro, const uschar * payload)
1097 {
1098 size_t l;
1099
1100 if (pad)
1101   {
1102   l = Ustrlen(pad);
1103   if (*col + l > 78)
1104     str = pdkim_hdr_cont(str, col);
1105   str = string_catn(str, pad, l);
1106   *col += l;
1107   }
1108
1109 l = (pad?1:0) + (intro?Ustrlen(intro):0);
1110
1111 if (*col + l > 78)
1112   { /*can't fit intro - start a new line to make room.*/
1113   str = pdkim_hdr_cont(str, col);
1114   l = intro?Ustrlen(intro):0;
1115   }
1116
1117 l += payload ? Ustrlen(payload):0 ;
1118
1119 while (l>77)
1120   { /* this fragment will not fit on a single line */
1121   if (pad)
1122     {
1123     str = string_catn(str, US" ", 1);
1124     *col += 1;
1125     pad = NULL; /* only want this once */
1126     l--;
1127     }
1128
1129   if (intro)
1130     {
1131     size_t sl = Ustrlen(intro);
1132
1133     str = string_catn(str, intro, sl);
1134     *col += sl;
1135     l -= sl;
1136     intro = NULL; /* only want this once */
1137     }
1138
1139   if (payload)
1140     {
1141     size_t sl = Ustrlen(payload);
1142     size_t chomp = *col+sl < 77 ? sl : 78-*col;
1143
1144     str = string_catn(str, payload, chomp);
1145     *col += chomp;
1146     payload += chomp;
1147     l -= chomp-1;
1148     }
1149
1150   /* the while precondition tells us it didn't fit. */
1151   str = pdkim_hdr_cont(str, col);
1152   }
1153
1154 if (*col + l > 78)
1155   {
1156   str = pdkim_hdr_cont(str, col);
1157   pad = NULL;
1158   }
1159
1160 if (pad)
1161   {
1162   str = string_catn(str, US" ", 1);
1163   *col += 1;
1164   pad = NULL;
1165   }
1166
1167 if (intro)
1168   {
1169   size_t sl = Ustrlen(intro);
1170
1171   str = string_catn(str, intro, sl);
1172   *col += sl;
1173   l -= sl;
1174   intro = NULL;
1175   }
1176
1177 if (payload)
1178   {
1179   size_t sl = Ustrlen(payload);
1180
1181   str = string_catn(str, payload, sl);
1182   *col += sl;
1183   }
1184
1185 return str;
1186 }
1187
1188
1189 /* -------------------------------------------------------------------------- */
1190
1191 static uschar *
1192 pdkim_create_header(pdkim_signature * sig, BOOL final)
1193 {
1194 uschar * base64_bh;
1195 uschar * base64_b;
1196 int col = 0;
1197 gstring * hdr;
1198 gstring * canon_all;
1199
1200 canon_all = string_cat (NULL, pdkim_canons[sig->canon_headers]);
1201 canon_all = string_catn(canon_all, US"/", 1);
1202 canon_all = string_cat (canon_all, pdkim_canons[sig->canon_body]);
1203 (void) string_from_gstring(canon_all);
1204
1205 hdr = string_cat(NULL, US"DKIM-Signature: v="PDKIM_SIGNATURE_VERSION);
1206 col = hdr->ptr;
1207
1208 /* Required and static bits */
1209 hdr = pdkim_headcat(&col, hdr, US";", US"a=", dkim_sig_to_a_tag(sig));
1210 hdr = pdkim_headcat(&col, hdr, US";", US"q=", pdkim_querymethods[sig->querymethod]);
1211 hdr = pdkim_headcat(&col, hdr, US";", US"c=", canon_all->s);
1212 hdr = pdkim_headcat(&col, hdr, US";", US"d=", sig->domain);
1213 hdr = pdkim_headcat(&col, hdr, US";", US"s=", sig->selector);
1214
1215 /* list of header names can be split between items. */
1216   {
1217   uschar * n = string_copy(sig->headernames);
1218   uschar * i = US"h=";
1219   uschar * s = US";";
1220
1221   while (*n)
1222     {
1223     uschar * c = Ustrchr(n, ':');
1224
1225     if (c) *c ='\0';
1226
1227     if (!i)
1228       hdr = pdkim_headcat(&col, hdr, NULL, NULL, US":");
1229
1230     hdr = pdkim_headcat(&col, hdr, s, i, n);
1231
1232     if (!c)
1233       break;
1234
1235     n = c+1;
1236     s = NULL;
1237     i = NULL;
1238     }
1239   }
1240
1241 base64_bh = pdkim_encode_base64(&sig->bodyhash);
1242 hdr = pdkim_headcat(&col, hdr, US";", US"bh=", base64_bh);
1243
1244 /* Optional bits */
1245 if (sig->identity)
1246   hdr = pdkim_headcat(&col, hdr, US";", US"i=", sig->identity);
1247
1248 if (sig->created > 0)
1249   {
1250   uschar minibuf[20];
1251
1252   snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->created);
1253   hdr = pdkim_headcat(&col, hdr, US";", US"t=", minibuf);
1254 }
1255
1256 if (sig->expires > 0)
1257   {
1258   uschar minibuf[20];
1259
1260   snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->expires);
1261   hdr = pdkim_headcat(&col, hdr, US";", US"x=", minibuf);
1262   }
1263
1264 if (sig->bodylength >= 0)
1265   {
1266   uschar minibuf[20];
1267
1268   snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->bodylength);
1269   hdr = pdkim_headcat(&col, hdr, US";", US"l=", minibuf);
1270   }
1271
1272 /* Preliminary or final version? */
1273 if (final)
1274   {
1275   base64_b = pdkim_encode_base64(&sig->sighash);
1276   hdr = pdkim_headcat(&col, hdr, US";", US"b=", base64_b);
1277
1278   /* add trailing semicolon: I'm not sure if this is actually needed */
1279   hdr = pdkim_headcat(&col, hdr, NULL, US";", US"");
1280   }
1281 else
1282   {
1283   /* To satisfy the rule "all surrounding whitespace [...] deleted"
1284   ( RFC 6376 section 3.7 ) we ensure there is no whitespace here.  Otherwise
1285   the headcat routine could insert a linebreak which the relaxer would reduce
1286   to a single space preceding the terminating semicolon, resulting in an
1287   incorrect header-hash. */
1288   hdr = pdkim_headcat(&col, hdr, US";", US"b=;", US"");
1289   }
1290
1291 return string_from_gstring(hdr);
1292 }
1293
1294
1295 /* -------------------------------------------------------------------------- */
1296
1297 static pdkim_pubkey *
1298 pdkim_key_from_dns(pdkim_ctx * ctx, pdkim_signature * sig, ev_ctx * vctx,
1299   const uschar ** errstr)
1300 {
1301 uschar * dns_txt_name, * dns_txt_reply;
1302 pdkim_pubkey * p;
1303
1304 /* Fetch public key for signing domain, from DNS */
1305
1306 dns_txt_name = string_sprintf("%s._domainkey.%s.", sig->selector, sig->domain);
1307
1308 dns_txt_reply = store_get(PDKIM_DNS_TXT_MAX_RECLEN);
1309 memset(dns_txt_reply, 0, PDKIM_DNS_TXT_MAX_RECLEN);
1310
1311 if (  ctx->dns_txt_callback(CS dns_txt_name, CS dns_txt_reply) != PDKIM_OK 
1312    || dns_txt_reply[0] == '\0'
1313    )
1314   {
1315   sig->verify_status =      PDKIM_VERIFY_INVALID;
1316   sig->verify_ext_status =  PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE;
1317   return NULL;
1318   }
1319
1320 DEBUG(D_acl)
1321   {
1322   debug_printf(
1323     "PDKIM >> Parsing public key record >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"
1324     " %s\n"
1325     " Raw record: ",
1326     dns_txt_name);
1327   pdkim_quoteprint(CUS dns_txt_reply, Ustrlen(dns_txt_reply));
1328   }
1329
1330 if (  !(p = pdkim_parse_pubkey_record(ctx, CUS dns_txt_reply))
1331    || (Ustrcmp(p->srvtype, "*") != 0 && Ustrcmp(p->srvtype, "email") != 0)
1332    )
1333   {
1334   sig->verify_status =      PDKIM_VERIFY_INVALID;
1335   sig->verify_ext_status =  PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD;
1336
1337   DEBUG(D_acl)
1338     {
1339     if (p)
1340       debug_printf(" Invalid public key service type '%s'\n", p->srvtype);
1341     else
1342       debug_printf(" Error while parsing public key record\n");
1343     debug_printf(
1344       "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1345     }
1346   return NULL;
1347   }
1348
1349 DEBUG(D_acl) debug_printf(
1350       "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1351
1352 /* Import public key */
1353 if ((*errstr = exim_dkim_verify_init(&p->key, vctx)))
1354   {
1355   DEBUG(D_acl) debug_printf("verify_init: %s\n", *errstr);
1356   sig->verify_status =      PDKIM_VERIFY_INVALID;
1357   sig->verify_ext_status =  PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
1358   return NULL;
1359   }
1360
1361 return p;
1362 }
1363
1364
1365 /* -------------------------------------------------------------------------- */
1366
1367 DLLEXPORT int
1368 pdkim_feed_finish(pdkim_ctx * ctx, pdkim_signature ** return_signatures,
1369   const uschar ** err)
1370 {
1371 pdkim_signature * sig;
1372
1373 /* Check if we must still flush a (partial) header. If that is the
1374    case, the message has no body, and we must compute a body hash
1375    out of '<CR><LF>' */
1376 if (ctx->cur_header && ctx->cur_header->ptr > 0)
1377   {
1378   blob * rnl = NULL;
1379   int rc;
1380
1381   if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1382     return rc;
1383
1384   for (sig = ctx->sig; sig; sig = sig->next)
1385     rnl = pdkim_update_sig_bodyhash(sig, &lineending, rnl);
1386   if (rnl) store_free(rnl);
1387   }
1388 else
1389   DEBUG(D_acl) debug_printf(
1390       "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1391
1392 /* Build (and/or evaluate) body hash */
1393 pdkim_finish_bodyhash(ctx);
1394
1395 for (sig = ctx->sig; sig; sig = sig->next)
1396   {
1397   hctx hhash_ctx;
1398   uschar * sig_hdr = US"";
1399   blob hhash;
1400   gstring * hdata = NULL;
1401
1402   if (!exim_sha_init(&hhash_ctx, pdkim_hashes[sig->hashtype].exim_hashmethod))
1403     {
1404     DEBUG(D_acl)
1405       debug_printf("PDKIM: hash setup error, possibly nonhandled hashtype\n");
1406     break;
1407     }
1408
1409   if (ctx->flags & PDKIM_MODE_SIGN)
1410     DEBUG(D_acl) debug_printf(
1411         "PDKIM >> Headers to be signed:                            >>>>>>>>>>>>\n"
1412         " %s\n",
1413         sig->sign_headers);
1414
1415   DEBUG(D_acl) debug_printf(
1416       "PDKIM >> Header data for hash, canonicalized, in sequence >>>>>>>>>>>>\n");
1417
1418
1419   /* SIGNING ---------------------------------------------------------------- */
1420   /* When signing, walk through our header list and add them to the hash. As we
1421      go, construct a list of the header's names to use for the h= parameter.
1422      Then append to that list any remaining header names for which there was no
1423      header to sign. */
1424
1425   if (ctx->flags & PDKIM_MODE_SIGN)
1426     {
1427     gstring * g = NULL;
1428     pdkim_stringlist *p;
1429     const uschar * l;
1430     uschar * s;
1431     int sep = 0;
1432
1433     sig->headernames = NULL;            /* Collected signed header names */
1434
1435     for (p = sig->headers; p; p = p->next)
1436       {
1437       uschar * rh = p->value;
1438
1439       if (header_name_match(rh, sig->sign_headers) == PDKIM_OK)
1440         {
1441         /* Collect header names (Note: colon presence is guaranteed here) */
1442         g = string_append_listele_n(g, ':', rh, Ustrchr(rh, ':') - rh);
1443
1444         if (sig->canon_headers == PDKIM_CANON_RELAXED)
1445           rh = pdkim_relax_header(rh, TRUE);    /* cook header for relaxed canon */
1446
1447         /* Feed header to the hash algorithm */
1448         exim_sha_update(&hhash_ctx, CUS rh, Ustrlen(rh));
1449
1450         /* Remember headers block for signing (when the library cannot do incremental)  */
1451         hdata = exim_dkim_data_append(hdata, rh);
1452
1453         DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1454         }
1455       }
1456
1457     /* Any headers we wanted to sign but were not present must also be listed.
1458     Ignore elements that have been ticked-off or are marked as never-oversign. */
1459
1460     l = sig->sign_headers;
1461     while((s = string_nextinlist(&l, &sep, NULL, 0)))
1462       {
1463       if (*s == '+')                    /* skip oversigning marker */
1464         s++;
1465       if (*s != '_' && *s != '=')
1466         g = string_append_listele(g, ':', s);
1467       }
1468     sig->headernames = string_from_gstring(g);
1469
1470     /* Create signature header with b= omitted */
1471     sig_hdr = pdkim_create_header(sig, FALSE);
1472     }
1473
1474   /* VERIFICATION ----------------------------------------------------------- */
1475   /* When verifying, walk through the header name list in the h= parameter and
1476      add the headers to the hash in that order. */
1477   else
1478     {
1479     uschar * p = sig->headernames;
1480     uschar * q;
1481     pdkim_stringlist * hdrs;
1482
1483     if (p)
1484       {
1485       /* clear tags */
1486       for (hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1487         hdrs->tag = 0;
1488
1489       p = string_copy(p);
1490       while(1)
1491         {
1492         if ((q = Ustrchr(p, ':')))
1493           *q = '\0';
1494
1495   /*XXX walk the list of headers in same order as received. */
1496         for (hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1497           if (  hdrs->tag == 0
1498              && strncasecmp(CCS hdrs->value, CCS p, Ustrlen(p)) == 0
1499              && (hdrs->value)[Ustrlen(p)] == ':'
1500              )
1501             {
1502             /* cook header for relaxed canon, or just copy it for simple  */
1503
1504             uschar * rh = sig->canon_headers == PDKIM_CANON_RELAXED
1505               ? pdkim_relax_header(hdrs->value, TRUE)
1506               : string_copy(CUS hdrs->value);
1507
1508             /* Feed header to the hash algorithm */
1509             exim_sha_update(&hhash_ctx, CUS rh, Ustrlen(rh));
1510
1511             DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1512             hdrs->tag = 1;
1513             break;
1514             }
1515
1516         if (!q) break;
1517         p = q+1;
1518         }
1519
1520       sig_hdr = string_copy(sig->rawsig_no_b_val);
1521       }
1522     }
1523
1524   DEBUG(D_acl) debug_printf(
1525             "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1526
1527   DEBUG(D_acl)
1528     {
1529     debug_printf(
1530             "PDKIM >> Signed DKIM-Signature header, pre-canonicalized >>>>>>>>>>>>>\n");
1531     pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr));
1532     debug_printf(
1533             "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1534     }
1535
1536   /* Relax header if necessary */
1537   if (sig->canon_headers == PDKIM_CANON_RELAXED)
1538     sig_hdr = pdkim_relax_header(sig_hdr, FALSE);
1539
1540   DEBUG(D_acl)
1541     {
1542     debug_printf(
1543             "PDKIM >> Signed DKIM-Signature header, canonicalized >>>>>>>>>>>>>>>>>\n");
1544     pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr));
1545     debug_printf(
1546             "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1547     }
1548
1549   /* Finalize header hash */
1550   exim_sha_update(&hhash_ctx, CUS sig_hdr, Ustrlen(sig_hdr));
1551   exim_sha_finish(&hhash_ctx, &hhash);
1552
1553   DEBUG(D_acl)
1554     {
1555     debug_printf("PDKIM [%s] Header %s computed: ",
1556       sig->domain, pdkim_hashes[sig->hashtype].dkim_hashname);
1557     pdkim_hexprint(hhash.data, hhash.len);
1558     }
1559
1560   /* Remember headers block for signing (when the signing library cannot do
1561   incremental)  */
1562   if (ctx->flags & PDKIM_MODE_SIGN)
1563     hdata = exim_dkim_data_append(hdata, US sig_hdr);
1564
1565   /* SIGNING ---------------------------------------------------------------- */
1566   if (ctx->flags & PDKIM_MODE_SIGN)
1567     {
1568     es_ctx sctx;
1569
1570     /* Import private key, including the keytype */
1571 /*XXX extend for non-RSA algos */
1572     if ((*err = exim_dkim_signing_init(US sig->privkey, &sctx)))
1573       {
1574       DEBUG(D_acl) debug_printf("signing_init: %s\n", *err);
1575       return PDKIM_ERR_RSA_PRIVKEY;
1576       }
1577
1578     /* Do signing.  With OpenSSL we are signing the hash of headers just
1579     calculated, with GnuTLS we have to sign an entire block of headers
1580     (due to available interfaces) and it recalculates the hash internally. */
1581
1582 #if defined(SIGN_GNUTLS)
1583     hhash.data = hdata->s;
1584     hhash.len =  hdata->ptr;
1585 #endif
1586
1587 /*XXX extend for non-RSA algos */
1588     if ((*err = exim_dkim_sign(&sctx,
1589                   pdkim_hashes[sig->hashtype].exim_hashmethod,
1590                   &hhash, &sig->sighash)))
1591       {
1592       DEBUG(D_acl) debug_printf("signing: %s\n", *err);
1593       return PDKIM_ERR_RSA_SIGNING;
1594       }
1595
1596     DEBUG(D_acl)
1597       {
1598       debug_printf( "PDKIM [%s] b computed: ", sig->domain);
1599       pdkim_hexprint(sig->sighash.data, sig->sighash.len);
1600       }
1601
1602     sig->signature_header = pdkim_create_header(sig, TRUE);
1603     }
1604
1605   /* VERIFICATION ----------------------------------------------------------- */
1606   else
1607     {
1608     ev_ctx vctx;
1609
1610     /* Make sure we have all required signature tags */
1611     if (!(  sig->domain        && *sig->domain
1612          && sig->selector      && *sig->selector
1613          && sig->headernames   && *sig->headernames
1614          && sig->bodyhash.data
1615          && sig->sighash.data
1616          && sig->keytype >= 0
1617          && sig->hashtype >= 0
1618          && sig->version
1619        ) )
1620       {
1621       sig->verify_status     = PDKIM_VERIFY_INVALID;
1622       sig->verify_ext_status = PDKIM_VERIFY_INVALID_SIGNATURE_ERROR;
1623
1624       DEBUG(D_acl) debug_printf(
1625           " Error in DKIM-Signature header: tags missing or invalid\n"
1626           "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1627       goto NEXT_VERIFY;
1628       }
1629
1630     /* Make sure sig uses supported DKIM version (only v1) */
1631     if (sig->version != 1)
1632       {
1633       sig->verify_status     = PDKIM_VERIFY_INVALID;
1634       sig->verify_ext_status = PDKIM_VERIFY_INVALID_DKIM_VERSION;
1635
1636       DEBUG(D_acl) debug_printf(
1637           " Error in DKIM-Signature header: unsupported DKIM version\n"
1638           "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1639       goto NEXT_VERIFY;
1640       }
1641
1642     DEBUG(D_acl)
1643       {
1644       debug_printf( "PDKIM [%s] b from mail: ", sig->domain);
1645       pdkim_hexprint(sig->sighash.data, sig->sighash.len);
1646       }
1647
1648     if (!(sig->pubkey = pdkim_key_from_dns(ctx, sig, &vctx, err)))
1649       goto NEXT_VERIFY;
1650
1651     /* If the pubkey limits to a list of specific hashes, ignore sigs that
1652     do not have the hash part of the sig algorithm matching */
1653
1654     if (sig->pubkey->hashes)
1655       {
1656       const uschar * list = sig->pubkey->hashes, * ele;
1657       int sep = ':';
1658       while ((ele = string_nextinlist(&list, &sep, NULL, 0)))
1659         if (Ustrcmp(ele, pdkim_hashes[sig->hashtype].dkim_hashname) == 0) break;
1660       if (!ele)
1661         {
1662         DEBUG(D_acl) debug_printf("pubkey h=%s vs. sig a=%s_%s\n",
1663           sig->pubkey->hashes,
1664           pdkim_keytypes[sig->keytype],
1665           pdkim_hashes[sig->hashtype].dkim_hashname);
1666         sig->verify_status =      PDKIM_VERIFY_FAIL;
1667         sig->verify_ext_status =  PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH;
1668         goto NEXT_VERIFY;
1669         }
1670       }
1671
1672     /* Check the signature */
1673 /*XXX needs extension for non-RSA */
1674     if ((*err = exim_dkim_verify(&vctx,
1675                   pdkim_hashes[sig->hashtype].exim_hashmethod,
1676                   &hhash, &sig->sighash)))
1677       {
1678       DEBUG(D_acl) debug_printf("headers verify: %s\n", *err);
1679       sig->verify_status =      PDKIM_VERIFY_FAIL;
1680       sig->verify_ext_status =  PDKIM_VERIFY_FAIL_MESSAGE;
1681       goto NEXT_VERIFY;
1682       }
1683
1684
1685     /* We have a winner! (if bodyhash was correct earlier) */
1686     if (sig->verify_status == PDKIM_VERIFY_NONE)
1687       sig->verify_status = PDKIM_VERIFY_PASS;
1688
1689 NEXT_VERIFY:
1690
1691     DEBUG(D_acl)
1692       {
1693       debug_printf("PDKIM [%s] signature status: %s",
1694               sig->domain, pdkim_verify_status_str(sig->verify_status));
1695       if (sig->verify_ext_status > 0)
1696         debug_printf(" (%s)\n",
1697                 pdkim_verify_ext_status_str(sig->verify_ext_status));
1698       else
1699         debug_printf("\n");
1700       }
1701     }
1702   }
1703
1704 /* If requested, set return pointer to signature(s) */
1705 if (return_signatures)
1706   *return_signatures = ctx->sig;
1707
1708 return PDKIM_OK;
1709 }
1710
1711
1712 /* -------------------------------------------------------------------------- */
1713
1714 DLLEXPORT pdkim_ctx *
1715 pdkim_init_verify(int(*dns_txt_callback)(char *, char *), BOOL dot_stuffing)
1716 {
1717 pdkim_ctx * ctx;
1718
1719 ctx = store_get(sizeof(pdkim_ctx));
1720 memset(ctx, 0, sizeof(pdkim_ctx));
1721
1722 if (dot_stuffing) ctx->flags = PDKIM_DOT_TERM;
1723 ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN);
1724 ctx->dns_txt_callback = dns_txt_callback;
1725
1726 return ctx;
1727 }
1728
1729
1730 /* -------------------------------------------------------------------------- */
1731
1732 /*XXX ? needs extension to cover non-RSA algo?  */
1733
1734 DLLEXPORT pdkim_signature *
1735 pdkim_init_sign(pdkim_ctx * ctx,
1736   uschar * domain, uschar * selector, uschar * privkey,
1737   uschar * hashname, const uschar ** errstr)
1738 {
1739 int hashtype;
1740 pdkim_signature * sig;
1741
1742 if (!domain || !selector || !privkey)
1743   return NULL;
1744
1745 /* Allocate & init one signature struct */
1746
1747 sig = store_get(sizeof(pdkim_signature));
1748 memset(sig, 0, sizeof(pdkim_signature));
1749
1750 sig->bodylength = -1;
1751
1752 sig->domain = string_copy(US domain);
1753 sig->selector = string_copy(US selector);
1754 sig->privkey = string_copy(US privkey);
1755 /*XXX no keytype yet; comes from privkey */
1756
1757 for (hashtype = 0; hashtype < nelem(pdkim_hashes); hashtype++)
1758   if (Ustrcmp(hashname, pdkim_hashes[hashtype].dkim_hashname) == 0)
1759   { sig->hashtype = hashtype; break; }
1760 if (hashtype >= nelem(pdkim_hashes))
1761   {
1762   DEBUG(D_acl)
1763     debug_printf("PDKIM: unrecognised hashname '%s'\n", hashname);
1764   return NULL;
1765   }
1766
1767 if (!exim_sha_init(&sig->body_hash_ctx, pdkim_hashes[hashtype].exim_hashmethod))
1768   {
1769   DEBUG(D_acl)
1770     debug_printf("PDKIM: hash setup error, possibly nonhandled hashtype\n");
1771   return NULL;
1772   }
1773
1774 DEBUG(D_acl)
1775   {
1776   pdkim_signature s = *sig;
1777   ev_ctx vctx;
1778
1779   debug_printf("PDKIM (checking verify key)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1780   if (!pdkim_key_from_dns(ctx, &s, &vctx, errstr))
1781     debug_printf("WARNING: bad dkim key in dns\n");
1782   debug_printf("PDKIM (finished checking verify key)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1783   }
1784 return sig;
1785 }
1786
1787
1788 /* -------------------------------------------------------------------------- */
1789
1790 DLLEXPORT void
1791 pdkim_set_optional(pdkim_signature * sig,
1792                        char * sign_headers,
1793                        char * identity,
1794                        int canon_headers,
1795                        int canon_body,
1796                        long bodylength,
1797                        unsigned long created,
1798                        unsigned long expires)
1799 {
1800 if (identity)
1801   sig->identity = string_copy(US identity);
1802
1803 sig->sign_headers = string_copy(sign_headers
1804         ? US sign_headers : US PDKIM_DEFAULT_SIGN_HEADERS);
1805
1806 sig->canon_headers = canon_headers;
1807 sig->canon_body = canon_body;
1808 sig->bodylength = bodylength;
1809 sig->created = created;
1810 sig->expires = expires;
1811
1812 return;
1813 }
1814
1815
1816
1817 void
1818 pdkim_init_context(pdkim_ctx * ctx, BOOL dot_stuffed,
1819   int(*dns_txt_callback)(char *, char *))
1820 {
1821 memset(ctx, 0, sizeof(pdkim_ctx));
1822 ctx->flags = dot_stuffed ? PDKIM_MODE_SIGN | PDKIM_DOT_TERM : PDKIM_MODE_SIGN;
1823 ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN);
1824 DEBUG(D_acl) ctx->dns_txt_callback = dns_txt_callback;
1825 }
1826
1827
1828 void
1829 pdkim_init(void)
1830 {
1831 exim_dkim_init();
1832 }
1833
1834
1835
1836 #endif  /*DISABLE_DKIM*/