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