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