SECURITY: Avoid memory corruption in dkim handling
[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 - 2020  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 #ifdef DISABLE_TLS
30 # error Must not DISABLE_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 const pdkim_hashtype pdkim_hashes[] = {
75   { US"sha1",   HASH_SHA1 },
76   { US"sha256", HASH_SHA2_256 },
77   { US"sha512", HASH_SHA2_512 }
78 };
79
80 const uschar * pdkim_keytypes[] = {
81   [KEYTYPE_RSA] =       US"rsa",
82 #ifdef SIGN_HAVE_ED25519
83   [KEYTYPE_ED25519] =   US"ed25519",            /* Works for 3.6.0 GnuTLS, OpenSSL 1.1.1 */
84 #endif
85
86 #ifdef notyet_EC_dkim_extensions        /* https://tools.ietf.org/html/draft-srose-dkim-ecc-00 */
87   US"eccp256",
88   US"eccp348",
89   US"ed448",
90 #endif
91 };
92
93 typedef struct pdkim_combined_canon_entry {
94   const uschar *        str;
95   int                   canon_headers;
96   int                   canon_body;
97 } pdkim_combined_canon_entry;
98
99 pdkim_combined_canon_entry pdkim_combined_canons[] = {
100   { US"simple/simple",    PDKIM_CANON_SIMPLE,   PDKIM_CANON_SIMPLE },
101   { US"simple/relaxed",   PDKIM_CANON_SIMPLE,   PDKIM_CANON_RELAXED },
102   { US"relaxed/simple",   PDKIM_CANON_RELAXED,  PDKIM_CANON_SIMPLE },
103   { US"relaxed/relaxed",  PDKIM_CANON_RELAXED,  PDKIM_CANON_RELAXED },
104   { US"simple",           PDKIM_CANON_SIMPLE,   PDKIM_CANON_SIMPLE },
105   { US"relaxed",          PDKIM_CANON_RELAXED,  PDKIM_CANON_SIMPLE },
106   { NULL,                 0,                    0 }
107 };
108
109
110 static blob lineending = {.data = US"\r\n", .len = 2};
111
112 /* -------------------------------------------------------------------------- */
113 uschar *
114 dkim_sig_to_a_tag(const pdkim_signature * sig)
115 {
116 if (  sig->keytype < 0  || sig->keytype > nelem(pdkim_keytypes)
117    || sig->hashtype < 0 || sig->hashtype > nelem(pdkim_hashes))
118   return US"err";
119 return string_sprintf("%s-%s",
120   pdkim_keytypes[sig->keytype], pdkim_hashes[sig->hashtype].dkim_hashname);
121 }
122
123
124 static int
125 pdkim_keyname_to_keytype(const uschar * s)
126 {
127 for (int i = 0; i < nelem(pdkim_keytypes); i++)
128   if (Ustrcmp(s, pdkim_keytypes[i]) == 0) return i;
129 return -1;
130 }
131
132 int
133 pdkim_hashname_to_hashtype(const uschar * s, unsigned len)
134 {
135 if (!len) len = Ustrlen(s);
136 for (int i = 0; i < nelem(pdkim_hashes); i++)
137   if (Ustrncmp(s, pdkim_hashes[i].dkim_hashname, len) == 0)
138     return i;
139 return -1;
140 }
141
142 void
143 pdkim_cstring_to_canons(const uschar * s, unsigned len,
144   int * canon_head, int * canon_body)
145 {
146 if (!len) len = Ustrlen(s);
147 for (int i = 0; pdkim_combined_canons[i].str; i++)
148   if (  Ustrncmp(s, pdkim_combined_canons[i].str, len) == 0
149      && len == Ustrlen(pdkim_combined_canons[i].str))
150     {
151     *canon_head = pdkim_combined_canons[i].canon_headers;
152     *canon_body = pdkim_combined_canons[i].canon_body;
153     break;
154     }
155 }
156
157
158
159 const char *
160 pdkim_verify_status_str(int status)
161 {
162 switch(status)
163   {
164   case PDKIM_VERIFY_NONE:    return "PDKIM_VERIFY_NONE";
165   case PDKIM_VERIFY_INVALID: return "PDKIM_VERIFY_INVALID";
166   case PDKIM_VERIFY_FAIL:    return "PDKIM_VERIFY_FAIL";
167   case PDKIM_VERIFY_PASS:    return "PDKIM_VERIFY_PASS";
168   default:                   return "PDKIM_VERIFY_UNKNOWN";
169   }
170 }
171
172 const char *
173 pdkim_verify_ext_status_str(int ext_status)
174 {
175 switch(ext_status)
176   {
177   case PDKIM_VERIFY_FAIL_BODY: return "PDKIM_VERIFY_FAIL_BODY";
178   case PDKIM_VERIFY_FAIL_MESSAGE: return "PDKIM_VERIFY_FAIL_MESSAGE";
179   case PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH: return "PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH";
180   case PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE: return "PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE";
181   case PDKIM_VERIFY_INVALID_BUFFER_SIZE: return "PDKIM_VERIFY_INVALID_BUFFER_SIZE";
182   case PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD: return "PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD";
183   case PDKIM_VERIFY_INVALID_PUBKEY_IMPORT: return "PDKIM_VERIFY_INVALID_PUBKEY_IMPORT";
184   case PDKIM_VERIFY_INVALID_PUBKEY_KEYSIZE: return "PDKIM_VERIFY_INVALID_PUBKEY_KEYSIZE";
185   case PDKIM_VERIFY_INVALID_SIGNATURE_ERROR: return "PDKIM_VERIFY_INVALID_SIGNATURE_ERROR";
186   case PDKIM_VERIFY_INVALID_DKIM_VERSION: return "PDKIM_VERIFY_INVALID_DKIM_VERSION";
187   default: return "PDKIM_VERIFY_UNKNOWN";
188   }
189 }
190
191 const uschar *
192 pdkim_errstr(int status)
193 {
194 switch(status)
195   {
196   case PDKIM_OK:                return US"OK";
197   case PDKIM_FAIL:              return US"FAIL";
198   case PDKIM_ERR_RSA_PRIVKEY:   return US"PRIVKEY";
199   case PDKIM_ERR_RSA_SIGNING:   return US"SIGNING";
200   case PDKIM_ERR_LONG_LINE:     return US"LONG_LINE";
201   case PDKIM_ERR_BUFFER_TOO_SMALL:      return US"BUFFER_TOO_SMALL";
202   case PDKIM_ERR_EXCESS_SIGS:   return US"EXCESS_SIGS";
203   case PDKIM_SIGN_PRIVKEY_WRAP: return US"PRIVKEY_WRAP";
204   case PDKIM_SIGN_PRIVKEY_B64D: return US"PRIVKEY_B64D";
205   default: return US"(unknown)";
206   }
207 }
208
209
210 /* -------------------------------------------------------------------------- */
211 /* Print debugging functions */
212 void
213 pdkim_quoteprint(const uschar *data, int len)
214 {
215 for (int i = 0; i < len; i++)
216   {
217   const int c = data[i];
218   switch (c)
219     {
220     case ' ' : debug_printf("{SP}"); break;
221     case '\t': debug_printf("{TB}"); break;
222     case '\r': debug_printf("{CR}"); break;
223     case '\n': debug_printf("{LF}"); break;
224     case '{' : debug_printf("{BO}"); break;
225     case '}' : debug_printf("{BC}"); break;
226     default:
227       if ( (c < 32) || (c > 127) )
228         debug_printf("{%02x}", c);
229       else
230         debug_printf("%c", c);
231       break;
232     }
233   }
234 debug_printf("\n");
235 }
236
237 void
238 pdkim_hexprint(const uschar *data, int len)
239 {
240 if (data) for (int i = 0 ; i < len; i++) debug_printf("%02x", data[i]);
241 else debug_printf("<NULL>");
242 debug_printf("\n");
243 }
244
245
246
247 static pdkim_stringlist *
248 pdkim_prepend_stringlist(pdkim_stringlist * base, const uschar * str)
249 {
250 pdkim_stringlist * new_entry = store_get(sizeof(pdkim_stringlist), FALSE);
251
252 memset(new_entry, 0, sizeof(pdkim_stringlist));
253 new_entry->value = string_copy(str);
254 if (base) new_entry->next = base;
255 return new_entry;
256 }
257
258
259
260 /* Trim whitespace fore & aft */
261
262 static void
263 pdkim_strtrim(gstring * str)
264 {
265 uschar * p = str->s;
266 uschar * q;
267
268 while (*p == '\t' || *p == ' ')         /* dump the leading whitespace */
269   { str->size--; str->ptr--; str->s++; }
270
271 while (  str->ptr > 0
272       && ((q = str->s + str->ptr - 1),  (*q == '\t' || *q == ' '))
273       )
274   str->ptr--;                           /* dump trailing whitespace */
275
276 (void) string_from_gstring(str);
277 }
278
279
280
281 /* -------------------------------------------------------------------------- */
282
283 DLLEXPORT void
284 pdkim_free_ctx(pdkim_ctx *ctx)
285 {
286 }
287
288
289 /* -------------------------------------------------------------------------- */
290 /* Matches the name of the passed raw "header" against
291    the passed colon-separated "tick", and invalidates
292    the entry in tick.  Entries can be prefixed for multi- or over-signing,
293    in which case do not invalidate.
294
295    Returns OK for a match, or fail-code
296 */
297
298 static int
299 header_name_match(const uschar * header, uschar * tick)
300 {
301 const uschar * ticklist = tick;
302 int sep = ':';
303 BOOL multisign;
304 uschar * hname, * p, * ele;
305 uschar * hcolon = Ustrchr(header, ':');         /* Get header name */
306
307 if (!hcolon)
308   return PDKIM_FAIL; /* This isn't a header */
309
310 /* if we had strncmpic() we wouldn't need this copy */
311 hname = string_copyn(header, hcolon-header);
312
313 while (p = US ticklist, ele = string_nextinlist(&ticklist, &sep, NULL, 0))
314   {
315   switch (*ele)
316   {
317   case '=': case '+':   multisign = TRUE; ele++; break;
318   default:              multisign = FALSE; break;
319   }
320
321   if (strcmpic(ele, hname) == 0)
322     {
323     if (!multisign)
324       *p = '_'; /* Invalidate this header name instance in tick-off list */
325     return PDKIM_OK;
326     }
327   }
328 return PDKIM_FAIL;
329 }
330
331
332 /* -------------------------------------------------------------------------- */
333 /* Performs "relaxed" canonicalization of a header. */
334
335 uschar *
336 pdkim_relax_header_n(const uschar * header, int len, BOOL append_crlf)
337 {
338 BOOL past_field_name = FALSE;
339 BOOL seen_wsp = FALSE;
340 uschar * relaxed = store_get(len+3, TRUE);      /* tainted */
341 uschar * q = relaxed;
342
343 for (const uschar * p = header; p - header < len; p++)
344   {
345   uschar c = *p;
346
347   if (c == '\r' || c == '\n')   /* Ignore CR & LF */
348     continue;
349   if (c == '\t' || c == ' ')
350     {
351     if (seen_wsp)
352       continue;
353     c = ' ';                    /* Turns WSP into SP */
354     seen_wsp = TRUE;
355     }
356   else
357     if (!past_field_name && c == ':')
358       {
359       if (seen_wsp) q--;        /* This removes WSP immediately before the colon */
360       seen_wsp = TRUE;          /* This removes WSP immediately after the colon */
361       past_field_name = TRUE;
362       }
363     else
364       seen_wsp = FALSE;
365
366   /* Lowercase header name */
367   if (!past_field_name) c = tolower(c);
368   *q++ = c;
369   }
370
371 if (q > relaxed && q[-1] == ' ') q--; /* Squash eventual trailing SP */
372
373 if (append_crlf) { *q++ = '\r'; *q++ = '\n'; }
374 *q = '\0';
375 return relaxed;
376 }
377
378
379 uschar *
380 pdkim_relax_header(const uschar * header, BOOL append_crlf)
381 {
382 return pdkim_relax_header_n(header, Ustrlen(header), append_crlf);
383 }
384
385
386 /* -------------------------------------------------------------------------- */
387 #define PDKIM_QP_ERROR_DECODE -1
388
389 static const uschar *
390 pdkim_decode_qp_char(const uschar *qp_p, int *c)
391 {
392 const uschar *initial_pos = qp_p;
393
394 /* Advance one char */
395 qp_p++;
396
397 /* Check for two hex digits and decode them */
398 if (isxdigit(*qp_p) && isxdigit(qp_p[1]))
399   {
400   /* Do hex conversion */
401   *c = (isdigit(*qp_p) ? *qp_p - '0' : toupper(*qp_p) - 'A' + 10) << 4;
402   *c |= isdigit(qp_p[1]) ? qp_p[1] - '0' : toupper(qp_p[1]) - 'A' + 10;
403   return qp_p + 2;
404   }
405
406 /* Illegal char here */
407 *c = PDKIM_QP_ERROR_DECODE;
408 return initial_pos;
409 }
410
411
412 /* -------------------------------------------------------------------------- */
413
414 static uschar *
415 pdkim_decode_qp(const uschar * str)
416 {
417 int nchar = 0;
418 uschar * q;
419 const uschar * p = str;
420 uschar * n = store_get(Ustrlen(str)+1, TRUE);
421
422 *n = '\0';
423 q = n;
424 while (*p)
425   {
426   if (*p == '=')
427     {
428     p = pdkim_decode_qp_char(p, &nchar);
429     if (nchar >= 0)
430       {
431       *q++ = nchar;
432       continue;
433       }
434     }
435   else
436     *q++ = *p;
437   p++;
438   }
439 *q = '\0';
440 return n;
441 }
442
443
444 /* -------------------------------------------------------------------------- */
445
446 void
447 pdkim_decode_base64(const uschar * str, blob * b)
448 {
449 int dlen = b64decode(str, &b->data);
450 if (dlen < 0) b->data = NULL;
451 b->len = dlen;
452 }
453
454 uschar *
455 pdkim_encode_base64(blob * b)
456 {
457 return b64encode(CUS b->data, b->len);
458 }
459
460
461 /* -------------------------------------------------------------------------- */
462 #define PDKIM_HDR_LIMBO 0
463 #define PDKIM_HDR_TAG   1
464 #define PDKIM_HDR_VALUE 2
465
466 static pdkim_signature *
467 pdkim_parse_sig_header(pdkim_ctx * ctx, uschar * raw_hdr)
468 {
469 pdkim_signature * sig;
470 uschar *q;
471 gstring * cur_tag = NULL;
472 gstring * cur_val = NULL;
473 BOOL past_hname = FALSE;
474 BOOL in_b_val = FALSE;
475 int where = PDKIM_HDR_LIMBO;
476
477 sig = store_get(sizeof(pdkim_signature), FALSE);
478 memset(sig, 0, sizeof(pdkim_signature));
479 sig->bodylength = -1;
480
481 /* Set so invalid/missing data error display is accurate */
482 sig->version = 0;
483 sig->keytype = -1;
484 sig->hashtype = -1;
485
486 q = sig->rawsig_no_b_val = store_get(Ustrlen(raw_hdr)+1, TRUE); /* tainted */
487
488 for (uschar * p = raw_hdr; ; p++)
489   {
490   char c = *p;
491
492   /* Ignore FWS */
493   if (c == '\r' || c == '\n')
494     goto NEXT_CHAR;
495
496   /* Fast-forward through header name */
497   if (!past_hname)
498     {
499     if (c == ':') past_hname = TRUE;
500     goto NEXT_CHAR;
501     }
502
503   if (where == PDKIM_HDR_LIMBO)
504     {
505     /* In limbo, just wait for a tag-char to appear */
506     if (!(c >= 'a' && c <= 'z'))
507       goto NEXT_CHAR;
508
509     where = PDKIM_HDR_TAG;
510     }
511
512   if (where == PDKIM_HDR_TAG)
513     {
514     if (c >= 'a' && c <= 'z')
515       cur_tag = string_catn(cur_tag, p, 1);
516
517     if (c == '=')
518       {
519       if (Ustrcmp(string_from_gstring(cur_tag), "b") == 0)
520         {
521         *q++ = '=';
522         in_b_val = TRUE;
523         }
524       where = PDKIM_HDR_VALUE;
525       goto NEXT_CHAR;
526       }
527     }
528
529   if (where == PDKIM_HDR_VALUE)
530     {
531     if (c == '\r' || c == '\n' || c == ' ' || c == '\t')
532       goto NEXT_CHAR;
533
534     if (c == ';' || c == '\0')
535       {
536       /* We must have both tag and value, and tags must be one char except
537       for the possibility of "bh". */
538
539       if (  cur_tag && cur_val
540          && (cur_tag->ptr == 1 || *cur_tag->s == 'b')
541          )
542         {
543         (void) string_from_gstring(cur_val);
544         pdkim_strtrim(cur_val);
545
546         DEBUG(D_acl) debug_printf(" %s=%s\n", cur_tag->s, cur_val->s);
547
548         switch (*cur_tag->s)
549           {
550           case 'b':                             /* sig-data or body-hash */
551             switch (cur_tag->s[1])
552               {
553               case '\0': pdkim_decode_base64(cur_val->s, &sig->sighash); break;
554               case 'h':  if (cur_tag->ptr == 2)
555                            pdkim_decode_base64(cur_val->s, &sig->bodyhash);
556                          break;
557               default:   break;
558               }
559             break;
560           case 'v':                                     /* version */
561               /* We only support version 1, and that is currently the
562                  only version there is. */
563             sig->version =
564               Ustrcmp(cur_val->s, PDKIM_SIGNATURE_VERSION) == 0 ? 1 : -1;
565             break;
566           case 'a':                                     /* algorithm */
567             {
568             const uschar * list = cur_val->s;
569             int sep = '-';
570             uschar * elem;
571
572             if ((elem = string_nextinlist(&list, &sep, NULL, 0)))
573               sig->keytype = pdkim_keyname_to_keytype(elem);
574             if ((elem = string_nextinlist(&list, &sep, NULL, 0)))
575               for (int i = 0; i < nelem(pdkim_hashes); i++)
576                 if (Ustrcmp(elem, pdkim_hashes[i].dkim_hashname) == 0)
577                   { sig->hashtype = i; break; }
578             }
579
580           case 'c':                                     /* canonicalization */
581             pdkim_cstring_to_canons(cur_val->s, 0,
582                                     &sig->canon_headers, &sig->canon_body);
583             break;
584           case 'q':                             /* Query method (for pubkey)*/
585             for (int i = 0; pdkim_querymethods[i]; i++)
586               if (Ustrcmp(cur_val->s, pdkim_querymethods[i]) == 0)
587                 {
588                 sig->querymethod = i;   /* we never actually use this */
589                 break;
590                 }
591             break;
592           case 's':                                     /* Selector */
593             sig->selector = string_copyn(cur_val->s, cur_val->ptr); break;
594           case 'd':                                     /* SDID */
595             sig->domain = string_copyn(cur_val->s, cur_val->ptr); break;
596           case 'i':                                     /* AUID */
597             sig->identity = pdkim_decode_qp(cur_val->s); break;
598           case 't':                                     /* Timestamp */
599             sig->created = strtoul(CS cur_val->s, NULL, 10); break;
600           case 'x':                                     /* Expiration */
601             sig->expires = strtoul(CS cur_val->s, NULL, 10); break;
602           case 'l':                                     /* Body length count */
603             sig->bodylength = strtol(CS cur_val->s, NULL, 10); break;
604           case 'h':                                     /* signed header fields */
605             sig->headernames = string_copyn(cur_val->s, cur_val->ptr); break;
606           case 'z':                                     /* Copied headfields */
607             sig->copiedheaders = pdkim_decode_qp(cur_val->s); break;
608 /*XXX draft-ietf-dcrup-dkim-crypto-05 would need 'p' tag support
609 for rsafp signatures.  But later discussion is dropping those. */
610           default:
611             DEBUG(D_acl) debug_printf(" Unknown tag encountered\n");
612             break;
613           }
614         }
615       cur_tag = cur_val = NULL;
616       in_b_val = FALSE;
617       where = PDKIM_HDR_LIMBO;
618       }
619     else
620       cur_val = string_catn(cur_val, p, 1);
621     }
622
623 NEXT_CHAR:
624   if (c == '\0')
625     break;
626
627   if (!in_b_val)
628     *q++ = c;
629   }
630
631 if (sig->keytype < 0 || sig->hashtype < 0)      /* Cannot verify this signature */
632   return NULL;
633
634 *q = '\0';
635 /* Chomp raw header. The final newline must not be added to the signature. */
636 while (--q > sig->rawsig_no_b_val  && (*q == '\r' || *q == '\n'))
637   *q = '\0';
638
639 DEBUG(D_acl)
640   {
641   debug_printf(
642           "DKIM >> Raw signature w/o b= tag value >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
643   pdkim_quoteprint(US sig->rawsig_no_b_val, Ustrlen(sig->rawsig_no_b_val));
644   debug_printf(
645           "DKIM >> Sig size: %4u bits\n", (unsigned) sig->sighash.len*8);
646   debug_printf(
647           "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
648   }
649
650 if (!pdkim_set_sig_bodyhash(ctx, sig))
651   return NULL;
652
653 return sig;
654 }
655
656
657 /* -------------------------------------------------------------------------- */
658
659 pdkim_pubkey *
660 pdkim_parse_pubkey_record(const uschar *raw_record)
661 {
662 const uschar * ele;
663 int sep = ';';
664 pdkim_pubkey * pub;
665
666 pub = store_get(sizeof(pdkim_pubkey), TRUE);    /* tainted */
667 memset(pub, 0, sizeof(pdkim_pubkey));
668
669 while ((ele = string_nextinlist(&raw_record, &sep, NULL, 0)))
670   {
671   const uschar * val;
672
673   if ((val = Ustrchr(ele, '=')))
674     {
675     int taglen = val++ - ele;
676
677     DEBUG(D_acl) debug_printf(" %.*s=%s\n", taglen, ele, val);
678     switch (ele[0])
679       {
680       case 'v': pub->version = val;                     break;
681       case 'h': pub->hashes = val;                      break;
682       case 'k': pub->keytype = val;                     break;
683       case 'g': pub->granularity = val;                 break;
684       case 'n': pub->notes = pdkim_decode_qp(val);      break;
685       case 'p': pdkim_decode_base64(val, &pub->key);    break;
686       case 's': pub->srvtype = val;                     break;
687       case 't': if (Ustrchr(val, 'y')) pub->testing = 1;
688                 if (Ustrchr(val, 's')) pub->no_subdomaining = 1;
689                 break;
690       default:  DEBUG(D_acl) debug_printf(" Unknown tag encountered\n"); break;
691       }
692     }
693   }
694
695 /* Set fallback defaults */
696 if (!pub->version)
697   pub->version = string_copy(PDKIM_PUB_RECORD_VERSION);
698 else if (Ustrcmp(pub->version, PDKIM_PUB_RECORD_VERSION) != 0)
699   {
700   DEBUG(D_acl) debug_printf(" Bad v= field\n");
701   return NULL;
702   }
703
704 if (!pub->granularity) pub->granularity = US"*";
705 if (!pub->keytype    ) pub->keytype     = US"rsa";
706 if (!pub->srvtype    ) pub->srvtype     = US"*";
707
708 /* p= is required */
709 if (pub->key.data)
710   return pub;
711
712 DEBUG(D_acl) debug_printf(" Missing p= field\n");
713 return NULL;
714 }
715
716
717 /* -------------------------------------------------------------------------- */
718
719 /* Update one bodyhash with some additional data.
720 If we have to relax the data for this sig, return our copy of it. */
721
722 static blob *
723 pdkim_update_ctx_bodyhash(pdkim_bodyhash * b, blob * orig_data, blob * relaxed_data)
724 {
725 const blob const * canon_data = orig_data;
726 size_t len;
727
728 /* Defaults to simple canon (no further treatment necessary) */
729
730 if (b->canon_method == PDKIM_CANON_RELAXED)
731   {
732   /* Relax the line if not done already */
733   if (!relaxed_data)
734     {
735     BOOL seen_wsp = FALSE;
736     int q = 0;
737
738     /* We want to be able to free this else we allocate
739     for the entire message which could be many MB. Since
740     we don't know what allocations the SHA routines might
741     do, not safe to use store_get()/store_reset(). */
742
743     relaxed_data = store_malloc(sizeof(blob) + orig_data->len+1);
744     relaxed_data->data = US (relaxed_data+1);
745
746     for (const uschar * p = orig_data->data, * r = p + orig_data->len; p < r; p++)
747       {
748       char c = *p;
749       if (c == '\r')
750         {
751         if (q > 0 && relaxed_data->data[q-1] == ' ')
752           q--;
753         }
754       else if (c == '\t' || c == ' ')
755         {
756         c = ' '; /* Turns WSP into SP */
757         if (seen_wsp)
758           continue;
759         seen_wsp = TRUE;
760         }
761       else
762         seen_wsp = FALSE;
763       relaxed_data->data[q++] = c;
764       }
765     relaxed_data->data[q] = '\0';
766     relaxed_data->len = q;
767     }
768   canon_data = relaxed_data;
769   }
770
771 /* Make sure we don't exceed the to-be-signed body length */
772 if (  b->bodylength >= 0
773    && b->signed_body_bytes + (unsigned long)canon_data->len > b->bodylength
774    )
775   len = b->bodylength - b->signed_body_bytes;
776
777 if (len > 0)
778   {
779   exim_sha_update(&b->body_hash_ctx, CUS canon_data->data, len);
780   b->signed_body_bytes += len;
781   DEBUG(D_acl) pdkim_quoteprint(canon_data->data, len);
782   }
783
784 return relaxed_data;
785 }
786
787
788 /* -------------------------------------------------------------------------- */
789
790 static void
791 pdkim_finish_bodyhash(pdkim_ctx * ctx)
792 {
793 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)     /* Finish hashes */
794   {
795   DEBUG(D_acl) debug_printf("DKIM: finish bodyhash %d/%d/%ld len %ld\n",
796             b->hashtype, b->canon_method, b->bodylength, b->signed_body_bytes);
797   exim_sha_finish(&b->body_hash_ctx, &b->bh);
798   }
799
800 /* Traverse all signatures */
801 for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next)
802   {
803   pdkim_bodyhash * b = sig->calc_body_hash;
804
805   DEBUG(D_acl)
806     {
807     debug_printf("DKIM [%s] Body bytes (%s) hashed: %lu\n"
808                  "DKIM [%s] Body %s computed: ",
809         sig->domain, pdkim_canons[b->canon_method], b->signed_body_bytes,
810         sig->domain, pdkim_hashes[b->hashtype].dkim_hashname);
811     pdkim_hexprint(CUS b->bh.data, b->bh.len);
812     }
813
814   /* SIGNING -------------------------------------------------------------- */
815   if (ctx->flags & PDKIM_MODE_SIGN)
816     {
817     /* If bodylength limit is set, and we have received less bytes
818        than the requested amount, effectively remove the limit tag. */
819     if (b->signed_body_bytes < sig->bodylength)
820       sig->bodylength = -1;
821     }
822
823   else
824   /* VERIFICATION --------------------------------------------------------- */
825   /* Be careful that the header sig included a bodyash */
826
827     if (  sig->bodyhash.data
828        && memcmp(b->bh.data, sig->bodyhash.data, b->bh.len) == 0)
829       {
830       DEBUG(D_acl) debug_printf("DKIM [%s] Body hash compared OK\n", sig->domain);
831       }
832     else
833       {
834       DEBUG(D_acl)
835         {
836         debug_printf("DKIM [%s] Body hash signature from headers: ", sig->domain);
837         pdkim_hexprint(sig->bodyhash.data, sig->bodyhash.len);
838         debug_printf("DKIM [%s] Body hash did NOT verify\n", sig->domain);
839         }
840       sig->verify_status     = PDKIM_VERIFY_FAIL;
841       sig->verify_ext_status = PDKIM_VERIFY_FAIL_BODY;
842       }
843   }
844 }
845
846
847
848 static void
849 pdkim_body_complete(pdkim_ctx * ctx)
850 {
851 /* In simple body mode, if any empty lines were buffered,
852 replace with one. rfc 4871 3.4.3 */
853 /*XXX checking the signed-body-bytes is a gross hack; I think
854 it indicates that all linebreaks should be buffered, including
855 the one terminating a text line */
856
857 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
858   if (  b->canon_method == PDKIM_CANON_SIMPLE
859      && b->signed_body_bytes == 0
860      && b->num_buffered_blanklines > 0
861      )
862     (void) pdkim_update_ctx_bodyhash(b, &lineending, NULL);
863
864 ctx->flags |= PDKIM_SEEN_EOD;
865 ctx->linebuf_offset = 0;
866 }
867
868
869
870 /* -------------------------------------------------------------------------- */
871 /* Call from pdkim_feed below for processing complete body lines */
872 /* NOTE: the line is not NUL-terminated; but we have a count */
873
874 static void
875 pdkim_bodyline_complete(pdkim_ctx * ctx)
876 {
877 blob line = {.data = ctx->linebuf, .len = ctx->linebuf_offset};
878 blob * rnl = NULL;
879 blob * rline = NULL;
880
881 /* Ignore extra data if we've seen the end-of-data marker */
882 if (ctx->flags & PDKIM_SEEN_EOD) goto all_skip;
883
884 /* We've always got one extra byte to stuff a zero ... */
885 ctx->linebuf[line.len] = '\0';
886
887 /* Terminate on EOD marker */
888 if (ctx->flags & PDKIM_DOT_TERM)
889   {
890   if (memcmp(line.data, ".\r\n", 3) == 0)
891     { pdkim_body_complete(ctx); return; }
892
893   /* Unstuff dots */
894   if (memcmp(line.data, "..", 2) == 0)
895     { line.data++; line.len--; }
896   }
897
898 /* Empty lines need to be buffered until we find a non-empty line */
899 if (memcmp(line.data, "\r\n", 2) == 0)
900   {
901   for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
902     b->num_buffered_blanklines++;
903   goto all_skip;
904   }
905
906 /* Process line for each bodyhash separately */
907 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
908   {
909   if (b->canon_method == PDKIM_CANON_RELAXED)
910     {
911     /* Lines with just spaces need to be buffered too */
912     uschar * cp = line.data;
913     char c;
914
915     while ((c = *cp))
916       {
917       if (c == '\r' && cp[1] == '\n') break;
918       if (c != ' ' && c != '\t') goto hash_process;
919       cp++;
920       }
921
922     b->num_buffered_blanklines++;
923     goto hash_skip;
924     }
925
926 hash_process:
927   /* At this point, we have a non-empty line, so release the buffered ones. */
928
929   while (b->num_buffered_blanklines)
930     {
931     rnl = pdkim_update_ctx_bodyhash(b, &lineending, rnl);
932     b->num_buffered_blanklines--;
933     }
934
935   rline = pdkim_update_ctx_bodyhash(b, &line, rline);
936 hash_skip: ;
937   }
938
939 if (rnl) store_free(rnl);
940 if (rline) store_free(rline);
941
942 all_skip:
943
944 ctx->linebuf_offset = 0;
945 return;
946 }
947
948
949 /* -------------------------------------------------------------------------- */
950 /* Callback from pdkim_feed below for processing complete headers */
951 #define DKIM_SIGNATURE_HEADERNAME "DKIM-Signature:"
952
953 static int
954 pdkim_header_complete(pdkim_ctx * ctx)
955 {
956 if ( (ctx->cur_header->ptr > 1) &&
957      (ctx->cur_header->s[ctx->cur_header->ptr-1] == '\r') )
958   --ctx->cur_header->ptr;
959 (void) string_from_gstring(ctx->cur_header);
960
961 #ifdef EXPERIMENTAL_ARC
962 /* Feed the header line to ARC processing */
963 (void) arc_header_feed(ctx->cur_header, !(ctx->flags & PDKIM_MODE_SIGN));
964 #endif
965
966 if (++ctx->num_headers > PDKIM_MAX_HEADERS) goto BAIL;
967
968 /* SIGNING -------------------------------------------------------------- */
969 if (ctx->flags & PDKIM_MODE_SIGN)
970   for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next)  /* Traverse all signatures */
971
972     /* Add header to the signed headers list (in reverse order) */
973     sig->headers = pdkim_prepend_stringlist(sig->headers, ctx->cur_header->s);
974
975 /* VERIFICATION ----------------------------------------------------------- */
976 /* DKIM-Signature: headers are added to the verification list */
977 else
978   {
979 #ifdef notdef
980   DEBUG(D_acl)
981     {
982     debug_printf("DKIM >> raw hdr: ");
983     pdkim_quoteprint(CUS ctx->cur_header->s, ctx->cur_header->ptr);
984     }
985 #endif
986   if (strncasecmp(CCS ctx->cur_header->s,
987                   DKIM_SIGNATURE_HEADERNAME,
988                   Ustrlen(DKIM_SIGNATURE_HEADERNAME)) == 0)
989     {
990     pdkim_signature * sig, * last_sig;
991     /* Create and chain new signature block.  We could error-check for all
992     required tags here, but prefer to create the internal sig and expicitly
993     fail verification of it later. */
994
995     DEBUG(D_acl) debug_printf(
996         "DKIM >> Found sig, trying to parse >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
997
998     sig = pdkim_parse_sig_header(ctx, ctx->cur_header->s);
999
1000     if (!(last_sig = ctx->sig))
1001       ctx->sig = sig;
1002     else
1003       {
1004       while (last_sig->next) last_sig = last_sig->next;
1005       last_sig->next = sig;
1006       }
1007
1008     if (dkim_collect_input && --dkim_collect_input == 0)
1009       {
1010       ctx->headers = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->s);
1011       ctx->cur_header->s[ctx->cur_header->ptr = 0] = '\0';
1012       return PDKIM_ERR_EXCESS_SIGS;
1013       }
1014     }
1015
1016   /* all headers are stored for signature verification */
1017   ctx->headers = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->s);
1018   }
1019
1020 BAIL:
1021 ctx->cur_header->s[ctx->cur_header->ptr = 0] = '\0';    /* leave buffer for reuse */
1022 return PDKIM_OK;
1023 }
1024
1025
1026
1027 /* -------------------------------------------------------------------------- */
1028 #define HEADER_BUFFER_FRAG_SIZE 256
1029
1030 DLLEXPORT int
1031 pdkim_feed(pdkim_ctx * ctx, uschar * data, int len)
1032 {
1033 /* Alternate EOD signal, used in non-dotstuffing mode */
1034 if (!data)
1035   pdkim_body_complete(ctx);
1036
1037 else for (int p = 0; p < len; p++)
1038   {
1039   uschar c = data[p];
1040   int rc;
1041
1042   if (ctx->flags & PDKIM_PAST_HDRS)
1043     {
1044     if (c == '\n' && !(ctx->flags & PDKIM_SEEN_CR))     /* emulate the CR */
1045       {
1046       ctx->linebuf[ctx->linebuf_offset++] = '\r';
1047       if (ctx->linebuf_offset == PDKIM_MAX_BODY_LINE_LEN-1)
1048         return PDKIM_ERR_LONG_LINE;
1049       }
1050
1051     /* Processing body byte */
1052     ctx->linebuf[ctx->linebuf_offset++] = c;
1053     if (c == '\r')
1054       ctx->flags |= PDKIM_SEEN_CR;
1055     else if (c == '\n')
1056       {
1057       ctx->flags &= ~PDKIM_SEEN_CR;
1058       pdkim_bodyline_complete(ctx);
1059       }
1060
1061     if (ctx->linebuf_offset == PDKIM_MAX_BODY_LINE_LEN-1)
1062       return PDKIM_ERR_LONG_LINE;
1063     }
1064   else
1065     {
1066     /* Processing header byte */
1067     if (c == '\r')
1068       ctx->flags |= PDKIM_SEEN_CR;
1069     else if (c == '\n')
1070       {
1071       if (!(ctx->flags & PDKIM_SEEN_CR))                /* emulate the CR */
1072         ctx->cur_header = string_catn(ctx->cur_header, CUS "\r", 1);
1073
1074       if (ctx->flags & PDKIM_SEEN_LF)           /* Seen last header line */
1075         {
1076         if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1077           return rc;
1078
1079         ctx->flags = (ctx->flags & ~(PDKIM_SEEN_LF|PDKIM_SEEN_CR)) | PDKIM_PAST_HDRS;
1080         DEBUG(D_acl) debug_printf(
1081             "DKIM >> Body data for hash, canonicalized >>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1082         continue;
1083         }
1084       else
1085         ctx->flags = (ctx->flags & ~PDKIM_SEEN_CR) | PDKIM_SEEN_LF;
1086       }
1087     else if (ctx->flags & PDKIM_SEEN_LF)
1088       {
1089       if (!(c == '\t' || c == ' '))                     /* End of header */
1090         if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1091           return rc;
1092       ctx->flags &= ~PDKIM_SEEN_LF;
1093       }
1094
1095     if (!ctx->cur_header || ctx->cur_header->ptr < PDKIM_MAX_HEADER_LEN)
1096       ctx->cur_header = string_catn(ctx->cur_header, CUS &data[p], 1);
1097     }
1098   }
1099 return PDKIM_OK;
1100 }
1101
1102
1103
1104 /* Extend a growing header with a continuation-linebreak */
1105 static gstring *
1106 pdkim_hdr_cont(gstring * str, int * col)
1107 {
1108 *col = 1;
1109 return string_catn(str, US"\r\n\t", 3);
1110 }
1111
1112
1113
1114 /*
1115  * RFC 5322 specifies that header line length SHOULD be no more than 78
1116  *  pdkim_headcat
1117  *
1118  * Returns gstring (not nul-terminated) appending to one supplied
1119  *
1120  * col: this int holds and receives column number (octets since last '\n')
1121  * str: partial string to append to
1122  * pad: padding, split line or space after before or after eg: ";".
1123  *               Only the initial charater is used.
1124  * intro: - must join to payload eg "h=", usually the tag name
1125  * payload: eg base64 data - long data can be split arbitrarily.
1126  *
1127  * this code doesn't fold the header in some of the places that RFC4871
1128  * allows: As per RFC5322(2.2.3) it only folds before or after tag-value
1129  * pairs and inside long values. it also always spaces or breaks after the
1130  * "pad"
1131  *
1132  * No guarantees are made for output given out-of range input. like tag
1133  * names longer than 78, or bogus col. Input is assumed to be free of line breaks.
1134  */
1135
1136 static gstring *
1137 pdkim_headcat(int * col, gstring * str,
1138   const uschar * pad, const uschar * intro, const uschar * payload)
1139 {
1140 int len, chomp, padded = 0;
1141
1142 /* If we can fit at least the pad at the end of current line, do it now.
1143 Otherwise, wrap if there is a pad. */
1144
1145 if (pad)
1146   if (*col + 1 <= 78)
1147     {
1148     str = string_catn(str, pad, 1);
1149     (*col)++;
1150     pad = NULL;
1151     padded = 1;
1152     }
1153   else
1154     str = pdkim_hdr_cont(str, col);
1155
1156 /* Special case: if the whole addition does not fit at the end of the current
1157 line, but could fit on a new line, wrap to give it its full, dedicated line.  */
1158
1159 len = (pad ? 2 : padded)
1160     + (intro ? Ustrlen(intro) : 0)
1161     + (payload ? Ustrlen(payload) : 0);
1162 if (len <= 77 && *col+len > 78)
1163   {
1164   str = pdkim_hdr_cont(str, col);
1165   padded = 0;
1166   }
1167
1168 /* Either we already dealt with the pad or we know there is room */
1169
1170 if (pad)
1171   {
1172   str = string_catn(str, pad, 1);
1173   str = string_catn(str, US" ", 1);
1174   *col += 2;
1175   }
1176 else if (padded && *col < 78)
1177   {
1178   str = string_catn(str, US" ", 1);
1179   (*col)++;
1180   }
1181
1182 /* Call recursively with intro as payload: it gets the same, special treatment
1183 (that is, not split if < 78).  */
1184
1185 if (intro)
1186   str = pdkim_headcat(col, str, NULL, NULL, intro);
1187
1188 if (payload)
1189   for (len = Ustrlen(payload); len; len -= chomp)
1190     {
1191     if (*col >= 78)
1192       str = pdkim_hdr_cont(str, col);
1193     chomp = *col+len > 78 ? 78 - *col : len;
1194     str = string_catn(str, payload, chomp);
1195     *col += chomp;
1196     payload += chomp;
1197     }
1198
1199 return str;
1200 }
1201
1202
1203 /* -------------------------------------------------------------------------- */
1204
1205 /* Signing: create signature header
1206 */
1207 static uschar *
1208 pdkim_create_header(pdkim_signature * sig, BOOL final)
1209 {
1210 uschar * base64_bh;
1211 uschar * base64_b;
1212 int col = 0;
1213 gstring * hdr;
1214 gstring * canon_all;
1215
1216 canon_all = string_cat (NULL, pdkim_canons[sig->canon_headers]);
1217 canon_all = string_catn(canon_all, US"/", 1);
1218 canon_all = string_cat (canon_all, pdkim_canons[sig->canon_body]);
1219 (void) string_from_gstring(canon_all);
1220
1221 hdr = string_cat(NULL, US"DKIM-Signature: v="PDKIM_SIGNATURE_VERSION);
1222 col = hdr->ptr;
1223
1224 /* Required and static bits */
1225 hdr = pdkim_headcat(&col, hdr, US";", US"a=", dkim_sig_to_a_tag(sig));
1226 hdr = pdkim_headcat(&col, hdr, US";", US"q=", pdkim_querymethods[sig->querymethod]);
1227 hdr = pdkim_headcat(&col, hdr, US";", US"c=", canon_all->s);
1228 hdr = pdkim_headcat(&col, hdr, US";", US"d=", sig->domain);
1229 hdr = pdkim_headcat(&col, hdr, US";", US"s=", sig->selector);
1230
1231 /* list of header names can be split between items. */
1232   {
1233   uschar * n = string_copy(sig->headernames);
1234   uschar * i = US"h=";
1235   uschar * s = US";";
1236
1237   while (*n)
1238     {
1239     uschar * c = Ustrchr(n, ':');
1240
1241     if (c) *c ='\0';
1242
1243     if (!i)
1244       hdr = pdkim_headcat(&col, hdr, NULL, NULL, US":");
1245
1246     hdr = pdkim_headcat(&col, hdr, s, i, n);
1247
1248     if (!c)
1249       break;
1250
1251     n = c+1;
1252     s = NULL;
1253     i = NULL;
1254     }
1255   }
1256
1257 base64_bh = pdkim_encode_base64(&sig->calc_body_hash->bh);
1258 hdr = pdkim_headcat(&col, hdr, US";", US"bh=", base64_bh);
1259
1260 /* Optional bits */
1261 if (sig->identity)
1262   hdr = pdkim_headcat(&col, hdr, US";", US"i=", sig->identity);
1263
1264 if (sig->created > 0)
1265   {
1266   uschar minibuf[20];
1267
1268   snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->created);
1269   hdr = pdkim_headcat(&col, hdr, US";", US"t=", minibuf);
1270 }
1271
1272 if (sig->expires > 0)
1273   {
1274   uschar minibuf[20];
1275
1276   snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->expires);
1277   hdr = pdkim_headcat(&col, hdr, US";", US"x=", minibuf);
1278   }
1279
1280 if (sig->bodylength >= 0)
1281   {
1282   uschar minibuf[20];
1283
1284   snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->bodylength);
1285   hdr = pdkim_headcat(&col, hdr, US";", US"l=", minibuf);
1286   }
1287
1288 /* Preliminary or final version? */
1289 if (final)
1290   {
1291   base64_b = pdkim_encode_base64(&sig->sighash);
1292   hdr = pdkim_headcat(&col, hdr, US";", US"b=", base64_b);
1293
1294   /* add trailing semicolon: I'm not sure if this is actually needed */
1295   hdr = pdkim_headcat(&col, hdr, NULL, US";", US"");
1296   }
1297 else
1298   {
1299   /* To satisfy the rule "all surrounding whitespace [...] deleted"
1300   ( RFC 6376 section 3.7 ) we ensure there is no whitespace here.  Otherwise
1301   the headcat routine could insert a linebreak which the relaxer would reduce
1302   to a single space preceding the terminating semicolon, resulting in an
1303   incorrect header-hash. */
1304   hdr = pdkim_headcat(&col, hdr, US";", US"b=;", US"");
1305   }
1306
1307 return string_from_gstring(hdr);
1308 }
1309
1310
1311 /* -------------------------------------------------------------------------- */
1312
1313 /* According to draft-ietf-dcrup-dkim-crypto-07 "keys are 256 bits" (referring
1314 to DNS, hence the pubkey).  Check for more than 32 bytes; if so assume the
1315 alternate possible representation (still) being discussed: a
1316 SubjectPublickeyInfo wrapped key - and drop all but the trailing 32-bytes (it
1317 should be a DER, with exactly 12 leading bytes - but we could accept a BER also,
1318 which could be any size).  We still rely on the crypto library for checking for
1319 undersize.
1320
1321 When the RFC is published this should be re-addressed. */
1322
1323 static void
1324 check_bare_ed25519_pubkey(pdkim_pubkey * p)
1325 {
1326 int excess = p->key.len - 32;
1327 if (excess > 0)
1328   {
1329   DEBUG(D_acl)
1330     debug_printf("DKIM: unexpected pubkey len %lu\n", (unsigned long) p->key.len);
1331   p->key.data += excess; p->key.len = 32;
1332   }
1333 }
1334
1335
1336 static pdkim_pubkey *
1337 pdkim_key_from_dns(pdkim_ctx * ctx, pdkim_signature * sig, ev_ctx * vctx,
1338   const uschar ** errstr)
1339 {
1340 uschar * dns_txt_name, * dns_txt_reply;
1341 pdkim_pubkey * p;
1342
1343 /* Fetch public key for signing domain, from DNS */
1344
1345 dns_txt_name = string_sprintf("%s._domainkey.%s.", sig->selector, sig->domain);
1346
1347 if (  !(dns_txt_reply = ctx->dns_txt_callback(dns_txt_name))
1348    || dns_txt_reply[0] == '\0'
1349    )
1350   {
1351   sig->verify_status =      PDKIM_VERIFY_INVALID;
1352   sig->verify_ext_status =  PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE;
1353   return NULL;
1354   }
1355
1356 DEBUG(D_acl)
1357   {
1358   debug_printf(
1359     "DKIM >> Parsing public key record >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"
1360     " %s\n"
1361     " Raw record: ",
1362     dns_txt_name);
1363   pdkim_quoteprint(CUS dns_txt_reply, Ustrlen(dns_txt_reply));
1364   }
1365
1366 if (  !(p = pdkim_parse_pubkey_record(CUS dns_txt_reply))
1367    || (Ustrcmp(p->srvtype, "*") != 0 && Ustrcmp(p->srvtype, "email") != 0)
1368    )
1369   {
1370   sig->verify_status =      PDKIM_VERIFY_INVALID;
1371   sig->verify_ext_status =  PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD;
1372
1373   DEBUG(D_acl)
1374     {
1375     if (p)
1376       debug_printf(" Invalid public key service type '%s'\n", p->srvtype);
1377     else
1378       debug_printf(" Error while parsing public key record\n");
1379     debug_printf(
1380       "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1381     }
1382   return NULL;
1383   }
1384
1385 DEBUG(D_acl) debug_printf(
1386       "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1387
1388 /* Import public key */
1389
1390 /* Normally we use the signature a= tag to tell us the pubkey format.
1391 When signing under debug we do a test-import of the pubkey, and at that
1392 time we do not have a signature so we must interpret the pubkey k= tag
1393 instead.  Assume writing on the sig is ok in that case. */
1394
1395 if (sig->keytype < 0)
1396   if ((sig->keytype = pdkim_keyname_to_keytype(p->keytype)) < 0)
1397     {
1398     DEBUG(D_acl) debug_printf("verify_init: unhandled keytype %s\n", p->keytype);
1399     sig->verify_status =      PDKIM_VERIFY_INVALID;
1400     sig->verify_ext_status =  PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
1401     return NULL;
1402     }
1403
1404 if (sig->keytype == KEYTYPE_ED25519)
1405   check_bare_ed25519_pubkey(p);
1406
1407 if ((*errstr = exim_dkim_verify_init(&p->key,
1408             sig->keytype == KEYTYPE_ED25519 ? KEYFMT_ED25519_BARE : KEYFMT_DER,
1409             vctx, &sig->keybits)))
1410   {
1411   DEBUG(D_acl) debug_printf("verify_init: %s\n", *errstr);
1412   sig->verify_status =      PDKIM_VERIFY_INVALID;
1413   sig->verify_ext_status =  PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
1414   return NULL;
1415   }
1416
1417 vctx->keytype = sig->keytype;
1418 return p;
1419 }
1420
1421
1422 /* -------------------------------------------------------------------------- */
1423 /* Sort and filter the sigs developed from the message */
1424
1425 static pdkim_signature *
1426 sort_sig_methods(pdkim_signature * siglist)
1427 {
1428 pdkim_signature * yield, ** ss;
1429 const uschar * prefs;
1430 uschar * ele;
1431 int sep;
1432
1433 if (!siglist) return NULL;
1434
1435 /* first select in order of hashtypes */
1436 DEBUG(D_acl) debug_printf("DKIM: dkim_verify_hashes   '%s'\n", dkim_verify_hashes);
1437 for (prefs = dkim_verify_hashes, sep = 0, yield = NULL, ss = &yield;
1438      ele = string_nextinlist(&prefs, &sep, NULL, 0); )
1439   {
1440   int i = pdkim_hashname_to_hashtype(CUS ele, 0);
1441   for (pdkim_signature * s = siglist, * next, ** prev = &siglist; s;
1442        s = next)
1443     {
1444     next = s->next;
1445     if (s->hashtype == i)
1446       { *prev = next; s->next = NULL; *ss = s; ss = &s->next; }
1447     else
1448       prev = &s->next;
1449     }
1450   }
1451
1452 /* then in order of keytypes */
1453 siglist = yield;
1454 DEBUG(D_acl) debug_printf("DKIM: dkim_verify_keytypes '%s'\n", dkim_verify_keytypes);
1455 for (prefs = dkim_verify_keytypes, sep = 0, yield = NULL, ss = &yield;
1456      ele = string_nextinlist(&prefs, &sep, NULL, 0); )
1457   {
1458   int i = pdkim_keyname_to_keytype(CUS ele);
1459   for (pdkim_signature * s = siglist, * next, ** prev = &siglist; s;
1460        s = next)
1461     {
1462     next = s->next;
1463     if (s->keytype == i)
1464       { *prev = next; s->next = NULL; *ss = s; ss = &s->next; }
1465     else
1466       prev = &s->next;
1467     }
1468   }
1469
1470 DEBUG(D_acl) for (pdkim_signature * s = yield; s; s = s->next)
1471   debug_printf(" retain d=%s s=%s a=%s\n",
1472     s->domain, s->selector, dkim_sig_to_a_tag(s));
1473 return yield;
1474 }
1475
1476
1477 /* -------------------------------------------------------------------------- */
1478
1479 DLLEXPORT int
1480 pdkim_feed_finish(pdkim_ctx * ctx, pdkim_signature ** return_signatures,
1481   const uschar ** err)
1482 {
1483 BOOL verify_pass = FALSE;
1484
1485 /* Check if we must still flush a (partial) header. If that is the
1486    case, the message has no body, and we must compute a body hash
1487    out of '<CR><LF>' */
1488 if (ctx->cur_header && ctx->cur_header->ptr > 0)
1489   {
1490   blob * rnl = NULL;
1491   int rc;
1492
1493   if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1494     return rc;
1495
1496   for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
1497     rnl = pdkim_update_ctx_bodyhash(b, &lineending, rnl);
1498   if (rnl) store_free(rnl);
1499   }
1500 else
1501   DEBUG(D_acl) debug_printf(
1502       "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1503
1504 /* Build (and/or evaluate) body hash.  Do this even if no DKIM sigs, in case we
1505 have a hash to do for ARC. */
1506
1507 pdkim_finish_bodyhash(ctx);
1508
1509 /* Sort and filter the recived signatures */
1510
1511 if (!(ctx->flags & PDKIM_MODE_SIGN))
1512   ctx->sig = sort_sig_methods(ctx->sig);
1513
1514 if (!ctx->sig)
1515   {
1516   DEBUG(D_acl) debug_printf("DKIM: no signatures\n");
1517   *return_signatures = NULL;
1518   return PDKIM_OK;
1519   }
1520
1521 for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next)
1522   {
1523   hctx hhash_ctx;
1524   uschar * sig_hdr = US"";
1525   blob hhash;
1526   gstring * hdata = NULL;
1527   es_ctx sctx;
1528
1529   if (  !(ctx->flags & PDKIM_MODE_SIGN)
1530      && sig->verify_status == PDKIM_VERIFY_FAIL)
1531     {
1532     DEBUG(D_acl)
1533        debug_printf("DKIM: [%s] abandoning this signature\n", sig->domain);
1534     continue;
1535     }
1536
1537   /*XXX The hash of the headers is needed for GCrypt (for which we can do RSA
1538   signing only, as it happens) and for either GnuTLS and OpenSSL when we are
1539   signing with EC (specifically, Ed25519).  The former is because the GCrypt
1540   signing operation is pure (does not do its own hash) so we must hash.  The
1541   latter is because we (stupidly, but this is what the IETF draft is saying)
1542   must hash with the declared hash method, then pass the result to the library
1543   hash-and-sign routine (because that's all the libraries are providing.  And
1544   we're stuck with whatever that hidden hash method is, too).  We may as well
1545   do this hash incrementally.
1546   We don't need the hash we're calculating here for the GnuTLS and OpenSSL
1547   cases of RSA signing, since those library routines can do hash-and-sign.
1548
1549   Some time in the future we could easily avoid doing the hash here for those
1550   cases (which will be common for a long while.  We could also change from
1551   the current copy-all-the-headers-into-one-block, then call the hash-and-sign
1552   implementation  - to a proper incremental one.  Unfortunately, GnuTLS just
1553   cannot do incremental - either signing or verification.  Unsure about GCrypt.
1554   */
1555
1556   /*XXX The header hash is also used (so far) by the verify operation */
1557
1558   if (!exim_sha_init(&hhash_ctx, pdkim_hashes[sig->hashtype].exim_hashmethod))
1559     {
1560     log_write(0, LOG_MAIN|LOG_PANIC,
1561       "DKIM: hash setup error, possibly nonhandled hashtype");
1562     break;
1563     }
1564
1565   if (ctx->flags & PDKIM_MODE_SIGN)
1566     DEBUG(D_acl) debug_printf(
1567         "DKIM >> Headers to be signed:                            >>>>>>>>>>>>\n"
1568         " %s\n",
1569         sig->sign_headers);
1570
1571   DEBUG(D_acl) debug_printf(
1572       "DKIM >> Header data for hash, canonicalized (%-7s), in sequence >>\n",
1573         pdkim_canons[sig->canon_headers]);
1574
1575
1576   /* SIGNING ---------------------------------------------------------------- */
1577   /* When signing, walk through our header list and add them to the hash. As we
1578      go, construct a list of the header's names to use for the h= parameter.
1579      Then append to that list any remaining header names for which there was no
1580      header to sign. */
1581
1582   if (ctx->flags & PDKIM_MODE_SIGN)
1583     {
1584     gstring * g = NULL;
1585     const uschar * l;
1586     uschar * s;
1587     int sep = 0;
1588
1589     /* Import private key, including the keytype which we need for building
1590     the signature header  */
1591
1592     if ((*err = exim_dkim_signing_init(CUS sig->privkey, &sctx)))
1593       {
1594       log_write(0, LOG_MAIN|LOG_PANIC, "signing_init: %s", *err);
1595       return PDKIM_ERR_RSA_PRIVKEY;
1596       }
1597     sig->keytype = sctx.keytype;
1598
1599     sig->headernames = NULL;                    /* Collected signed header names */
1600     for (pdkim_stringlist * p = sig->headers; p; p = p->next)
1601       {
1602       uschar * rh = p->value;
1603
1604       if (header_name_match(rh, sig->sign_headers) == PDKIM_OK)
1605         {
1606         /* Collect header names (Note: colon presence is guaranteed here) */
1607         g = string_append_listele_n(g, ':', rh, Ustrchr(rh, ':') - rh);
1608
1609         if (sig->canon_headers == PDKIM_CANON_RELAXED)
1610           rh = pdkim_relax_header(rh, TRUE);    /* cook header for relaxed canon */
1611
1612         /* Feed header to the hash algorithm */
1613         exim_sha_update(&hhash_ctx, CUS rh, Ustrlen(rh));
1614
1615         /* Remember headers block for signing (when the library cannot do incremental)  */
1616         /*XXX we could avoid doing this for all but the GnuTLS/RSA case */
1617         hdata = exim_dkim_data_append(hdata, rh);
1618
1619         DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1620         }
1621       }
1622
1623     /* Any headers we wanted to sign but were not present must also be listed.
1624     Ignore elements that have been ticked-off or are marked as never-oversign. */
1625
1626     l = sig->sign_headers;
1627     while((s = string_nextinlist(&l, &sep, NULL, 0)))
1628       {
1629       if (*s == '+')                    /* skip oversigning marker */
1630         s++;
1631       if (*s != '_' && *s != '=')
1632         g = string_append_listele(g, ':', s);
1633       }
1634     sig->headernames = string_from_gstring(g);
1635
1636     /* Create signature header with b= omitted */
1637     sig_hdr = pdkim_create_header(sig, FALSE);
1638     }
1639
1640   /* VERIFICATION ----------------------------------------------------------- */
1641   /* When verifying, walk through the header name list in the h= parameter and
1642      add the headers to the hash in that order. */
1643   else
1644     {
1645     uschar * p = sig->headernames;
1646     uschar * q;
1647
1648     if (p)
1649       {
1650       /* clear tags */
1651       for (pdkim_stringlist * hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1652         hdrs->tag = 0;
1653
1654       p = string_copy(p);
1655       while(1)
1656         {
1657         if ((q = Ustrchr(p, ':')))
1658           *q = '\0';
1659
1660   /*XXX walk the list of headers in same order as received. */
1661         for (pdkim_stringlist * hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1662           if (  hdrs->tag == 0
1663              && strncasecmp(CCS hdrs->value, CCS p, Ustrlen(p)) == 0
1664              && (hdrs->value)[Ustrlen(p)] == ':'
1665              )
1666             {
1667             /* cook header for relaxed canon, or just copy it for simple  */
1668
1669             uschar * rh = sig->canon_headers == PDKIM_CANON_RELAXED
1670               ? pdkim_relax_header(hdrs->value, TRUE)
1671               : string_copy(CUS hdrs->value);
1672
1673             /* Feed header to the hash algorithm */
1674             exim_sha_update(&hhash_ctx, CUS rh, Ustrlen(rh));
1675
1676             DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1677             hdrs->tag = 1;
1678             break;
1679             }
1680
1681         if (!q) break;
1682         p = q+1;
1683         }
1684
1685       sig_hdr = string_copy(sig->rawsig_no_b_val);
1686       }
1687     }
1688
1689   DEBUG(D_acl) debug_printf(
1690             "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1691
1692   DEBUG(D_acl)
1693     {
1694     debug_printf(
1695             "DKIM >> Signed DKIM-Signature header, pre-canonicalized >>>>>>>>>>>>>\n");
1696     pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr));
1697     debug_printf(
1698             "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1699     }
1700
1701   /* Relax header if necessary */
1702   if (sig->canon_headers == PDKIM_CANON_RELAXED)
1703     sig_hdr = pdkim_relax_header(sig_hdr, FALSE);
1704
1705   DEBUG(D_acl)
1706     {
1707     debug_printf("DKIM >> Signed DKIM-Signature header, canonicalized (%-7s) >>>>>>>\n",
1708             pdkim_canons[sig->canon_headers]);
1709     pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr));
1710     debug_printf(
1711             "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1712     }
1713
1714   /* Finalize header hash */
1715   exim_sha_update(&hhash_ctx, CUS sig_hdr, Ustrlen(sig_hdr));
1716   exim_sha_finish(&hhash_ctx, &hhash);
1717
1718   DEBUG(D_acl)
1719     {
1720     debug_printf("DKIM [%s] Header %s computed: ",
1721       sig->domain, pdkim_hashes[sig->hashtype].dkim_hashname);
1722     pdkim_hexprint(hhash.data, hhash.len);
1723     }
1724
1725   /* Remember headers block for signing (when the signing library cannot do
1726   incremental)  */
1727   if (ctx->flags & PDKIM_MODE_SIGN)
1728     hdata = exim_dkim_data_append(hdata, US sig_hdr);
1729
1730   /* SIGNING ---------------------------------------------------------------- */
1731   if (ctx->flags & PDKIM_MODE_SIGN)
1732     {
1733     hashmethod hm = sig->keytype == KEYTYPE_ED25519
1734 #if defined(SIGN_OPENSSL)
1735       ? HASH_NULL
1736 #else
1737       ? HASH_SHA2_512
1738 #endif
1739       : pdkim_hashes[sig->hashtype].exim_hashmethod;
1740
1741 #ifdef SIGN_HAVE_ED25519
1742     /* For GCrypt, and for EC, we pass the hash-of-headers to the signing
1743     routine.  For anything else we just pass the headers. */
1744
1745     if (sig->keytype != KEYTYPE_ED25519)
1746 #endif
1747       {
1748       hhash.data = hdata->s;
1749       hhash.len = hdata->ptr;
1750       }
1751
1752     if ((*err = exim_dkim_sign(&sctx, hm, &hhash, &sig->sighash)))
1753       {
1754       log_write(0, LOG_MAIN|LOG_PANIC, "signing: %s", *err);
1755       return PDKIM_ERR_RSA_SIGNING;
1756       }
1757
1758     DEBUG(D_acl)
1759       {
1760       debug_printf( "DKIM [%s] b computed: ", sig->domain);
1761       pdkim_hexprint(sig->sighash.data, sig->sighash.len);
1762       }
1763
1764     sig->signature_header = pdkim_create_header(sig, TRUE);
1765     }
1766
1767   /* VERIFICATION ----------------------------------------------------------- */
1768   else
1769     {
1770     ev_ctx vctx;
1771     hashmethod hm;
1772
1773     /* Make sure we have all required signature tags */
1774     if (!(  sig->domain        && *sig->domain
1775          && sig->selector      && *sig->selector
1776          && sig->headernames   && *sig->headernames
1777          && sig->bodyhash.data
1778          && sig->sighash.data
1779          && sig->keytype >= 0
1780          && sig->hashtype >= 0
1781          && sig->version
1782        ) )
1783       {
1784       sig->verify_status     = PDKIM_VERIFY_INVALID;
1785       sig->verify_ext_status = PDKIM_VERIFY_INVALID_SIGNATURE_ERROR;
1786
1787       DEBUG(D_acl) debug_printf(
1788           " Error in DKIM-Signature header: tags missing or invalid (%s)\n"
1789           "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
1790           !(sig->domain && *sig->domain) ? "d="
1791           : !(sig->selector && *sig->selector) ? "s="
1792           : !(sig->headernames && *sig->headernames) ? "h="
1793           : !sig->bodyhash.data ? "bh="
1794           : !sig->sighash.data ? "b="
1795           : sig->keytype < 0 || sig->hashtype < 0 ? "a="
1796           : "v="
1797           );
1798       goto NEXT_VERIFY;
1799       }
1800
1801     /* Make sure sig uses supported DKIM version (only v1) */
1802     if (sig->version != 1)
1803       {
1804       sig->verify_status     = PDKIM_VERIFY_INVALID;
1805       sig->verify_ext_status = PDKIM_VERIFY_INVALID_DKIM_VERSION;
1806
1807       DEBUG(D_acl) debug_printf(
1808           " Error in DKIM-Signature header: unsupported DKIM version\n"
1809           "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1810       goto NEXT_VERIFY;
1811       }
1812
1813     DEBUG(D_acl)
1814       {
1815       debug_printf( "DKIM [%s] b from mail: ", sig->domain);
1816       pdkim_hexprint(sig->sighash.data, sig->sighash.len);
1817       }
1818
1819     if (!(sig->pubkey = pdkim_key_from_dns(ctx, sig, &vctx, err)))
1820       {
1821       log_write(0, LOG_MAIN, "DKIM: %s%s %s%s [failed key import]",
1822         sig->domain   ? "d=" : "", sig->domain   ? sig->domain   : US"",
1823         sig->selector ? "s=" : "", sig->selector ? sig->selector : US"");
1824       goto NEXT_VERIFY;
1825       }
1826
1827     /* If the pubkey limits to a list of specific hashes, ignore sigs that
1828     do not have the hash part of the sig algorithm matching */
1829
1830     if (sig->pubkey->hashes)
1831       {
1832       const uschar * list = sig->pubkey->hashes, * ele;
1833       int sep = ':';
1834       while ((ele = string_nextinlist(&list, &sep, NULL, 0)))
1835         if (Ustrcmp(ele, pdkim_hashes[sig->hashtype].dkim_hashname) == 0) break;
1836       if (!ele)
1837         {
1838         DEBUG(D_acl) debug_printf("pubkey h=%s vs. sig a=%s_%s\n",
1839           sig->pubkey->hashes,
1840           pdkim_keytypes[sig->keytype],
1841           pdkim_hashes[sig->hashtype].dkim_hashname);
1842         sig->verify_status =      PDKIM_VERIFY_FAIL;
1843         sig->verify_ext_status =  PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH;
1844         goto NEXT_VERIFY;
1845         }
1846       }
1847
1848     hm = sig->keytype == KEYTYPE_ED25519
1849 #if defined(SIGN_OPENSSL)
1850       ? HASH_NULL
1851 #else
1852       ? HASH_SHA2_512
1853 #endif
1854       : pdkim_hashes[sig->hashtype].exim_hashmethod;
1855
1856     /* Check the signature */
1857
1858     if ((*err = exim_dkim_verify(&vctx, hm, &hhash, &sig->sighash)))
1859       {
1860       DEBUG(D_acl) debug_printf("headers verify: %s\n", *err);
1861       sig->verify_status =      PDKIM_VERIFY_FAIL;
1862       sig->verify_ext_status =  PDKIM_VERIFY_FAIL_MESSAGE;
1863       goto NEXT_VERIFY;
1864       }
1865     if (*dkim_verify_min_keysizes)
1866       {
1867       unsigned minbits;
1868       uschar * ss = expand_getkeyed(US pdkim_keytypes[sig->keytype],
1869                                     dkim_verify_min_keysizes);
1870       if (ss &&  (minbits = atoi(CS ss)) > sig->keybits)
1871         {
1872         DEBUG(D_acl) debug_printf("Key too short: Actual: %s %u  Minima '%s'\n",
1873           pdkim_keytypes[sig->keytype], sig->keybits, dkim_verify_min_keysizes);
1874         sig->verify_status =      PDKIM_VERIFY_FAIL;
1875         sig->verify_ext_status =  PDKIM_VERIFY_INVALID_PUBKEY_KEYSIZE;
1876         }
1877       }
1878
1879
1880     /* We have a winner! (if bodyhash was correct earlier) */
1881     if (sig->verify_status == PDKIM_VERIFY_NONE)
1882       {
1883       sig->verify_status = PDKIM_VERIFY_PASS;
1884       verify_pass = TRUE;
1885       if (dkim_verify_minimal) break;
1886       }
1887
1888 NEXT_VERIFY:
1889
1890     DEBUG(D_acl)
1891       {
1892       debug_printf("DKIM [%s] %s signature status: %s",
1893               sig->domain, dkim_sig_to_a_tag(sig),
1894               pdkim_verify_status_str(sig->verify_status));
1895       if (sig->verify_ext_status > 0)
1896         debug_printf(" (%s)\n",
1897                 pdkim_verify_ext_status_str(sig->verify_ext_status));
1898       else
1899         debug_printf("\n");
1900       }
1901     }
1902   }
1903
1904 /* If requested, set return pointer to signature(s) */
1905 if (return_signatures)
1906   *return_signatures = ctx->sig;
1907
1908 return ctx->flags & PDKIM_MODE_SIGN  ||  verify_pass
1909   ? PDKIM_OK : PDKIM_FAIL;
1910 }
1911
1912
1913 /* -------------------------------------------------------------------------- */
1914
1915 DLLEXPORT pdkim_ctx *
1916 pdkim_init_verify(uschar * (*dns_txt_callback)(const uschar *), BOOL dot_stuffing)
1917 {
1918 pdkim_ctx * ctx;
1919
1920 ctx = store_get(sizeof(pdkim_ctx), FALSE);
1921 memset(ctx, 0, sizeof(pdkim_ctx));
1922
1923 if (dot_stuffing) ctx->flags = PDKIM_DOT_TERM;
1924 /* The line-buffer is for message data, hence tainted */
1925 ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN, TRUE);
1926 ctx->dns_txt_callback = dns_txt_callback;
1927 ctx->cur_header = string_get_tainted(36, TRUE);
1928
1929 return ctx;
1930 }
1931
1932
1933 /* -------------------------------------------------------------------------- */
1934
1935 DLLEXPORT pdkim_signature *
1936 pdkim_init_sign(pdkim_ctx * ctx,
1937   uschar * domain, uschar * selector, uschar * privkey,
1938   uschar * hashname, const uschar ** errstr)
1939 {
1940 int hashtype;
1941 pdkim_signature * sig;
1942
1943 if (!domain || !selector || !privkey)
1944   return NULL;
1945
1946 /* Allocate & init one signature struct */
1947
1948 sig = store_get(sizeof(pdkim_signature), FALSE);
1949 memset(sig, 0, sizeof(pdkim_signature));
1950
1951 sig->bodylength = -1;
1952
1953 sig->domain = string_copy(US domain);
1954 sig->selector = string_copy(US selector);
1955 sig->privkey = string_copy(US privkey);
1956 sig->keytype = -1;
1957
1958 for (hashtype = 0; hashtype < nelem(pdkim_hashes); hashtype++)
1959   if (Ustrcmp(hashname, pdkim_hashes[hashtype].dkim_hashname) == 0)
1960   { sig->hashtype = hashtype; break; }
1961 if (hashtype >= nelem(pdkim_hashes))
1962   {
1963   log_write(0, LOG_MAIN|LOG_PANIC,
1964     "DKIM: unrecognised hashname '%s'", hashname);
1965   return NULL;
1966   }
1967
1968 DEBUG(D_acl)
1969   {
1970   pdkim_signature s = *sig;
1971   ev_ctx vctx;
1972
1973   debug_printf("DKIM (checking verify key)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1974   if (!pdkim_key_from_dns(ctx, &s, &vctx, errstr))
1975     debug_printf("WARNING: bad dkim key in dns\n");
1976   debug_printf("DKIM (finished checking verify key)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1977   }
1978 return sig;
1979 }
1980
1981
1982 /* -------------------------------------------------------------------------- */
1983
1984 DLLEXPORT void
1985 pdkim_set_optional(pdkim_signature * sig,
1986                        char * sign_headers,
1987                        char * identity,
1988                        int canon_headers,
1989                        int canon_body,
1990                        long bodylength,
1991                        unsigned long created,
1992                        unsigned long expires)
1993 {
1994 if (identity)
1995   sig->identity = string_copy(US identity);
1996
1997 sig->sign_headers = string_copy(sign_headers
1998         ? US sign_headers : US PDKIM_DEFAULT_SIGN_HEADERS);
1999
2000 sig->canon_headers = canon_headers;
2001 sig->canon_body = canon_body;
2002 sig->bodylength = bodylength;
2003 sig->created = created;
2004 sig->expires = expires;
2005
2006 return;
2007 }
2008
2009
2010
2011 /* Set up a blob for calculating the bodyhash according to the
2012 given needs.  Use an existing one if possible, or create a new one.
2013
2014 Return: hashblob pointer, or NULL on error
2015 */
2016 pdkim_bodyhash *
2017 pdkim_set_bodyhash(pdkim_ctx * ctx, int hashtype, int canon_method,
2018         long bodylength)
2019 {
2020 pdkim_bodyhash * b;
2021
2022 if (hashtype == -1 || canon_method == -1) return NULL;
2023
2024 for (b = ctx->bodyhash; b; b = b->next)
2025   if (  hashtype == b->hashtype
2026      && canon_method == b->canon_method
2027      && bodylength == b->bodylength)
2028     {
2029     DEBUG(D_receive) debug_printf("DKIM: using existing bodyhash %d/%d/%ld\n",
2030                                   hashtype, canon_method, bodylength);
2031     return b;
2032     }
2033
2034 DEBUG(D_receive) debug_printf("DKIM: new bodyhash %d/%d/%ld\n",
2035                               hashtype, canon_method, bodylength);
2036 b = store_get(sizeof(pdkim_bodyhash), FALSE);
2037 b->next = ctx->bodyhash;
2038 b->hashtype = hashtype;
2039 b->canon_method = canon_method;
2040 b->bodylength = bodylength;
2041 if (!exim_sha_init(&b->body_hash_ctx,           /*XXX hash method: extend for sha512 */
2042                   pdkim_hashes[hashtype].exim_hashmethod))
2043   {
2044   DEBUG(D_acl)
2045     debug_printf("DKIM: hash init error, possibly nonhandled hashtype\n");
2046   return NULL;
2047   }
2048 b->signed_body_bytes = 0;
2049 b->num_buffered_blanklines = 0;
2050 ctx->bodyhash = b;
2051 return b;
2052 }
2053
2054
2055 /* Set up a blob for calculating the bodyhash according to the
2056 needs of this signature.  Use an existing one if possible, or
2057 create a new one.
2058
2059 Return: hashblob pointer, or NULL on error (only used as a boolean).
2060 */
2061 pdkim_bodyhash *
2062 pdkim_set_sig_bodyhash(pdkim_ctx * ctx, pdkim_signature * sig)
2063 {
2064 pdkim_bodyhash * b = pdkim_set_bodyhash(ctx,
2065                         sig->hashtype, sig->canon_body, sig->bodylength);
2066 sig->calc_body_hash = b;
2067 return b;
2068 }
2069
2070
2071 /* -------------------------------------------------------------------------- */
2072
2073
2074 void
2075 pdkim_init_context(pdkim_ctx * ctx, BOOL dot_stuffed,
2076   uschar * (*dns_txt_callback)(const uschar *))
2077 {
2078 memset(ctx, 0, sizeof(pdkim_ctx));
2079 ctx->flags = dot_stuffed ? PDKIM_MODE_SIGN | PDKIM_DOT_TERM : PDKIM_MODE_SIGN;
2080 /* The line buffer is for message data, hence tainted */
2081 ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN, TRUE);
2082 DEBUG(D_acl) ctx->dns_txt_callback = dns_txt_callback;
2083 }
2084
2085
2086 void
2087 pdkim_init(void)
2088 {
2089 exim_dkim_init();
2090 }
2091
2092
2093
2094 #endif  /*DISABLE_DKIM*/