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 const blob lineending = {.data = US"\r\n", .len = 2};
111 
112 /* -------------------------------------------------------------------------- */
113 uschar *
dkim_sig_to_a_tag(const pdkim_signature * sig)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
pdkim_keyname_to_keytype(const uschar * s)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
pdkim_hashname_to_hashtype(const uschar * s,unsigned len)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
pdkim_cstring_to_canons(const uschar * s,unsigned len,int * canon_head,int * canon_body)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 *
pdkim_verify_status_str(int status)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 *
pdkim_verify_ext_status_str(int ext_status)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 *
pdkim_errstr(int status)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
pdkim_quoteprint(const uschar * data,int len)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
pdkim_hexprint(const uschar * data,int len)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 *
pdkim_prepend_stringlist(pdkim_stringlist * base,const uschar * str)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
pdkim_strtrim(gstring * str)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
pdkim_free_ctx(pdkim_ctx * ctx)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
header_name_match(const uschar * header,uschar * tick)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 *
pdkim_relax_header_n(const uschar * header,int len,BOOL append_crlf)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 *
pdkim_relax_header(const uschar * header,BOOL append_crlf)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 *
pdkim_decode_qp_char(const uschar * qp_p,int * c)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 *
pdkim_decode_qp(const uschar * str)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
pdkim_decode_base64(const uschar * str,blob * b)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 *
pdkim_encode_base64(blob * b)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 *
pdkim_parse_sig_header(pdkim_ctx * ctx,uschar * raw_hdr)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 *
pdkim_parse_pubkey_record(const uschar * raw_record)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 *
pdkim_update_ctx_bodyhash(pdkim_bodyhash * b,const blob * orig_data,blob * relaxed_data)723 pdkim_update_ctx_bodyhash(pdkim_bodyhash * b, const blob * orig_data, blob * relaxed_data)
724 {
725 const blob * canon_data = orig_data;
726 size_t left;
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 left = canon_data->len;
773 if (  b->bodylength >= 0
774    && left > (unsigned long)b->bodylength - b->signed_body_bytes
775    )
776   left = (unsigned long)b->bodylength - b->signed_body_bytes;
777 
778 if (left > 0)
779   {
780   exim_sha_update(&b->body_hash_ctx, CUS canon_data->data, left);
781   b->signed_body_bytes += left;
782   DEBUG(D_acl) pdkim_quoteprint(canon_data->data, left);
783   }
784 
785 return relaxed_data;
786 }
787 
788 
789 /* -------------------------------------------------------------------------- */
790 
791 static void
pdkim_finish_bodyhash(pdkim_ctx * ctx)792 pdkim_finish_bodyhash(pdkim_ctx * ctx)
793 {
794 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)     /* Finish hashes */
795   {
796   DEBUG(D_acl) debug_printf("DKIM: finish bodyhash %d/%d/%ld len %ld\n",
797 	    b->hashtype, b->canon_method, b->bodylength, b->signed_body_bytes);
798   exim_sha_finish(&b->body_hash_ctx, &b->bh);
799   }
800 
801 /* Traverse all signatures */
802 for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next)
803   {
804   pdkim_bodyhash * b = sig->calc_body_hash;
805 
806   DEBUG(D_acl)
807     {
808     debug_printf("DKIM [%s] Body bytes (%s) hashed: %lu\n"
809 		 "DKIM [%s] Body %s computed: ",
810 	sig->domain, pdkim_canons[b->canon_method], b->signed_body_bytes,
811 	sig->domain, pdkim_hashes[b->hashtype].dkim_hashname);
812     pdkim_hexprint(CUS b->bh.data, b->bh.len);
813     }
814 
815   /* SIGNING -------------------------------------------------------------- */
816   if (ctx->flags & PDKIM_MODE_SIGN)
817     {
818     /* If bodylength limit is set, and we have received less bytes
819        than the requested amount, effectively remove the limit tag. */
820     if (b->signed_body_bytes < sig->bodylength)
821       sig->bodylength = -1;
822     }
823 
824   else
825   /* VERIFICATION --------------------------------------------------------- */
826   /* Be careful that the header sig included a bodyash */
827 
828     if (sig->bodyhash.data && sig->bodyhash.len == b->bh.len
829        && memcmp(b->bh.data, sig->bodyhash.data, b->bh.len) == 0)
830       {
831       DEBUG(D_acl) debug_printf("DKIM [%s] Body hash compared OK\n", sig->domain);
832       }
833     else
834       {
835       DEBUG(D_acl)
836         {
837 	debug_printf("DKIM [%s] Body hash signature from headers: ", sig->domain);
838 	pdkim_hexprint(sig->bodyhash.data, sig->bodyhash.len);
839 	debug_printf("DKIM [%s] Body hash did NOT verify\n", sig->domain);
840 	}
841       sig->verify_status     = PDKIM_VERIFY_FAIL;
842       sig->verify_ext_status = PDKIM_VERIFY_FAIL_BODY;
843       }
844   }
845 }
846 
847 
848 
849 static void
pdkim_body_complete(pdkim_ctx * ctx)850 pdkim_body_complete(pdkim_ctx * ctx)
851 {
852 /* In simple body mode, if any empty lines were buffered,
853 replace with one. rfc 4871 3.4.3 */
854 /*XXX checking the signed-body-bytes is a gross hack; I think
855 it indicates that all linebreaks should be buffered, including
856 the one terminating a text line */
857 
858 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
859   if (  b->canon_method == PDKIM_CANON_SIMPLE
860      && b->signed_body_bytes == 0
861      && b->num_buffered_blanklines > 0
862      )
863     (void) pdkim_update_ctx_bodyhash(b, &lineending, NULL);
864 
865 ctx->flags |= PDKIM_SEEN_EOD;
866 ctx->linebuf_offset = 0;
867 }
868 
869 
870 
871 /* -------------------------------------------------------------------------- */
872 /* Call from pdkim_feed below for processing complete body lines */
873 /* NOTE: the line is not NUL-terminated; but we have a count */
874 
875 static void
pdkim_bodyline_complete(pdkim_ctx * ctx)876 pdkim_bodyline_complete(pdkim_ctx * ctx)
877 {
878 blob line = {.data = ctx->linebuf, .len = ctx->linebuf_offset};
879 blob * rnl = NULL;
880 blob * rline = NULL;
881 
882 /* Ignore extra data if we've seen the end-of-data marker */
883 if (ctx->flags & PDKIM_SEEN_EOD) goto all_skip;
884 
885 /* We've always got one extra byte to stuff a zero ... */
886 ctx->linebuf[line.len] = '\0';
887 
888 /* Terminate on EOD marker */
889 if (ctx->flags & PDKIM_DOT_TERM)
890   {
891   if (memcmp(line.data, ".\r\n", 3) == 0)
892     { pdkim_body_complete(ctx); return; }
893 
894   /* Unstuff dots */
895   if (memcmp(line.data, "..", 2) == 0)
896     { line.data++; line.len--; }
897   }
898 
899 /* Empty lines need to be buffered until we find a non-empty line */
900 if (memcmp(line.data, "\r\n", 2) == 0)
901   {
902   for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
903     b->num_buffered_blanklines++;
904   goto all_skip;
905   }
906 
907 /* Process line for each bodyhash separately */
908 for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
909   {
910   if (b->canon_method == PDKIM_CANON_RELAXED)
911     {
912     /* Lines with just spaces need to be buffered too */
913     uschar * cp = line.data;
914     char c;
915 
916     while ((c = *cp))
917       {
918       if (c == '\r' && cp[1] == '\n') break;
919       if (c != ' ' && c != '\t') goto hash_process;
920       cp++;
921       }
922 
923     b->num_buffered_blanklines++;
924     goto hash_skip;
925     }
926 
927 hash_process:
928   /* At this point, we have a non-empty line, so release the buffered ones. */
929 
930   while (b->num_buffered_blanklines)
931     {
932     rnl = pdkim_update_ctx_bodyhash(b, &lineending, rnl);
933     b->num_buffered_blanklines--;
934     }
935 
936   rline = pdkim_update_ctx_bodyhash(b, &line, rline);
937 hash_skip: ;
938   }
939 
940 if (rnl) store_free(rnl);
941 if (rline) store_free(rline);
942 
943 all_skip:
944 
945 ctx->linebuf_offset = 0;
946 return;
947 }
948 
949 
950 /* -------------------------------------------------------------------------- */
951 /* Callback from pdkim_feed below for processing complete headers */
952 #define DKIM_SIGNATURE_HEADERNAME "DKIM-Signature:"
953 
954 static int
pdkim_header_complete(pdkim_ctx * ctx)955 pdkim_header_complete(pdkim_ctx * ctx)
956 {
957 if ( (ctx->cur_header->ptr > 1) &&
958      (ctx->cur_header->s[ctx->cur_header->ptr-1] == '\r') )
959   --ctx->cur_header->ptr;
960 (void) string_from_gstring(ctx->cur_header);
961 
962 #ifdef EXPERIMENTAL_ARC
963 /* Feed the header line to ARC processing */
964 (void) arc_header_feed(ctx->cur_header, !(ctx->flags & PDKIM_MODE_SIGN));
965 #endif
966 
967 if (++ctx->num_headers > PDKIM_MAX_HEADERS) goto BAIL;
968 
969 /* SIGNING -------------------------------------------------------------- */
970 if (ctx->flags & PDKIM_MODE_SIGN)
971   for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next)  /* Traverse all signatures */
972 
973     /* Add header to the signed headers list (in reverse order) */
974     sig->headers = pdkim_prepend_stringlist(sig->headers, ctx->cur_header->s);
975 
976 /* VERIFICATION ----------------------------------------------------------- */
977 /* DKIM-Signature: headers are added to the verification list */
978 else
979   {
980 #ifdef notdef
981   DEBUG(D_acl)
982     {
983     debug_printf("DKIM >> raw hdr: ");
984     pdkim_quoteprint(CUS ctx->cur_header->s, ctx->cur_header->ptr);
985     }
986 #endif
987   if (strncasecmp(CCS ctx->cur_header->s,
988 		  DKIM_SIGNATURE_HEADERNAME,
989 		  Ustrlen(DKIM_SIGNATURE_HEADERNAME)) == 0)
990     {
991     pdkim_signature * sig, * last_sig;
992     /* Create and chain new signature block.  We could error-check for all
993     required tags here, but prefer to create the internal sig and expicitly
994     fail verification of it later. */
995 
996     DEBUG(D_acl) debug_printf(
997 	"DKIM >> Found sig, trying to parse >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
998 
999     sig = pdkim_parse_sig_header(ctx, ctx->cur_header->s);
1000 
1001     if (!(last_sig = ctx->sig))
1002       ctx->sig = sig;
1003     else
1004       {
1005       while (last_sig->next) last_sig = last_sig->next;
1006       last_sig->next = sig;
1007       }
1008 
1009     if (dkim_collect_input && --dkim_collect_input == 0)
1010       {
1011       ctx->headers = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->s);
1012       ctx->cur_header->s[ctx->cur_header->ptr = 0] = '\0';
1013       return PDKIM_ERR_EXCESS_SIGS;
1014       }
1015     }
1016 
1017   /* all headers are stored for signature verification */
1018   ctx->headers = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->s);
1019   }
1020 
1021 BAIL:
1022 ctx->cur_header->s[ctx->cur_header->ptr = 0] = '\0';	/* leave buffer for reuse */
1023 return PDKIM_OK;
1024 }
1025 
1026 
1027 
1028 /* -------------------------------------------------------------------------- */
1029 #define HEADER_BUFFER_FRAG_SIZE 256
1030 
1031 DLLEXPORT int
pdkim_feed(pdkim_ctx * ctx,uschar * data,int len)1032 pdkim_feed(pdkim_ctx * ctx, uschar * data, int len)
1033 {
1034 /* Alternate EOD signal, used in non-dotstuffing mode */
1035 if (!data)
1036   pdkim_body_complete(ctx);
1037 
1038 else for (int p = 0; p < len; p++)
1039   {
1040   uschar c = data[p];
1041   int rc;
1042 
1043   if (ctx->flags & PDKIM_PAST_HDRS)
1044     {
1045     if (c == '\n' && !(ctx->flags & PDKIM_SEEN_CR))	/* emulate the CR */
1046       {
1047       ctx->linebuf[ctx->linebuf_offset++] = '\r';
1048       if (ctx->linebuf_offset == PDKIM_MAX_BODY_LINE_LEN-1)
1049 	return PDKIM_ERR_LONG_LINE;
1050       }
1051 
1052     /* Processing body byte */
1053     ctx->linebuf[ctx->linebuf_offset++] = c;
1054     if (c == '\r')
1055       ctx->flags |= PDKIM_SEEN_CR;
1056     else if (c == '\n')
1057       {
1058       ctx->flags &= ~PDKIM_SEEN_CR;
1059       pdkim_bodyline_complete(ctx);
1060       }
1061 
1062     if (ctx->linebuf_offset == PDKIM_MAX_BODY_LINE_LEN-1)
1063       return PDKIM_ERR_LONG_LINE;
1064     }
1065   else
1066     {
1067     /* Processing header byte */
1068     if (c == '\r')
1069       ctx->flags |= PDKIM_SEEN_CR;
1070     else if (c == '\n')
1071       {
1072       if (!(ctx->flags & PDKIM_SEEN_CR))		/* emulate the CR */
1073 	ctx->cur_header = string_catn(ctx->cur_header, CUS "\r", 1);
1074 
1075       if (ctx->flags & PDKIM_SEEN_LF)		/* Seen last header line */
1076 	{
1077 	if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1078 	  return rc;
1079 
1080 	ctx->flags = (ctx->flags & ~(PDKIM_SEEN_LF|PDKIM_SEEN_CR)) | PDKIM_PAST_HDRS;
1081 	DEBUG(D_acl) debug_printf(
1082 	    "DKIM >> Body data for hash, canonicalized >>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1083 	continue;
1084 	}
1085       else
1086 	ctx->flags = (ctx->flags & ~PDKIM_SEEN_CR) | PDKIM_SEEN_LF;
1087       }
1088     else if (ctx->flags & PDKIM_SEEN_LF)
1089       {
1090       if (!(c == '\t' || c == ' '))			/* End of header */
1091 	if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1092 	  return rc;
1093       ctx->flags &= ~PDKIM_SEEN_LF;
1094       }
1095 
1096     if (!ctx->cur_header || ctx->cur_header->ptr < PDKIM_MAX_HEADER_LEN)
1097       ctx->cur_header = string_catn(ctx->cur_header, CUS &data[p], 1);
1098     }
1099   }
1100 return PDKIM_OK;
1101 }
1102 
1103 
1104 
1105 /* Extend a growing header with a continuation-linebreak */
1106 static gstring *
pdkim_hdr_cont(gstring * str,int * col)1107 pdkim_hdr_cont(gstring * str, int * col)
1108 {
1109 *col = 1;
1110 return string_catn(str, US"\r\n\t", 3);
1111 }
1112 
1113 
1114 
1115 /*
1116  * RFC 5322 specifies that header line length SHOULD be no more than 78
1117  *  pdkim_headcat
1118  *
1119  * Returns gstring (not nul-terminated) appending to one supplied
1120  *
1121  * col: this int holds and receives column number (octets since last '\n')
1122  * str: partial string to append to
1123  * pad: padding, split line or space after before or after eg: ";".
1124  *               Only the initial charater is used.
1125  * intro: - must join to payload eg "h=", usually the tag name
1126  * payload: eg base64 data - long data can be split arbitrarily.
1127  *
1128  * this code doesn't fold the header in some of the places that RFC4871
1129  * allows: As per RFC5322(2.2.3) it only folds before or after tag-value
1130  * pairs and inside long values. it also always spaces or breaks after the
1131  * "pad"
1132  *
1133  * No guarantees are made for output given out-of range input. like tag
1134  * names longer than 78, or bogus col. Input is assumed to be free of line breaks.
1135  */
1136 
1137 static gstring *
pdkim_headcat(int * col,gstring * str,const uschar * pad,const uschar * intro,const uschar * payload)1138 pdkim_headcat(int * col, gstring * str,
1139   const uschar * pad, const uschar * intro, const uschar * payload)
1140 {
1141 int len, chomp, padded = 0;
1142 
1143 /* If we can fit at least the pad at the end of current line, do it now.
1144 Otherwise, wrap if there is a pad. */
1145 
1146 if (pad)
1147   if (*col + 1 <= 78)
1148     {
1149     str = string_catn(str, pad, 1);
1150     (*col)++;
1151     pad = NULL;
1152     padded = 1;
1153     }
1154   else
1155     str = pdkim_hdr_cont(str, col);
1156 
1157 /* Special case: if the whole addition does not fit at the end of the current
1158 line, but could fit on a new line, wrap to give it its full, dedicated line.  */
1159 
1160 len = (pad ? 2 : padded)
1161     + (intro ? Ustrlen(intro) : 0)
1162     + (payload ? Ustrlen(payload) : 0);
1163 if (len <= 77 && *col+len > 78)
1164   {
1165   str = pdkim_hdr_cont(str, col);
1166   padded = 0;
1167   }
1168 
1169 /* Either we already dealt with the pad or we know there is room */
1170 
1171 if (pad)
1172   {
1173   str = string_catn(str, pad, 1);
1174   str = string_catn(str, US" ", 1);
1175   *col += 2;
1176   }
1177 else if (padded && *col < 78)
1178   {
1179   str = string_catn(str, US" ", 1);
1180   (*col)++;
1181   }
1182 
1183 /* Call recursively with intro as payload: it gets the same, special treatment
1184 (that is, not split if < 78).  */
1185 
1186 if (intro)
1187   str = pdkim_headcat(col, str, NULL, NULL, intro);
1188 
1189 if (payload)
1190   for (len = Ustrlen(payload); len; len -= chomp)
1191     {
1192     if (*col >= 78)
1193       str = pdkim_hdr_cont(str, col);
1194     chomp = *col+len > 78 ? 78 - *col : len;
1195     str = string_catn(str, payload, chomp);
1196     *col += chomp;
1197     payload += chomp;
1198     }
1199 
1200 return str;
1201 }
1202 
1203 
1204 /* -------------------------------------------------------------------------- */
1205 
1206 /* Signing: create signature header
1207 */
1208 static uschar *
pdkim_create_header(pdkim_signature * sig,BOOL final)1209 pdkim_create_header(pdkim_signature * sig, BOOL final)
1210 {
1211 uschar * base64_bh;
1212 uschar * base64_b;
1213 int col = 0;
1214 gstring * hdr;
1215 gstring * canon_all;
1216 
1217 canon_all = string_cat (NULL, pdkim_canons[sig->canon_headers]);
1218 canon_all = string_catn(canon_all, US"/", 1);
1219 canon_all = string_cat (canon_all, pdkim_canons[sig->canon_body]);
1220 (void) string_from_gstring(canon_all);
1221 
1222 hdr = string_cat(NULL, US"DKIM-Signature: v="PDKIM_SIGNATURE_VERSION);
1223 col = hdr->ptr;
1224 
1225 /* Required and static bits */
1226 hdr = pdkim_headcat(&col, hdr, US";", US"a=", dkim_sig_to_a_tag(sig));
1227 hdr = pdkim_headcat(&col, hdr, US";", US"q=", pdkim_querymethods[sig->querymethod]);
1228 hdr = pdkim_headcat(&col, hdr, US";", US"c=", canon_all->s);
1229 hdr = pdkim_headcat(&col, hdr, US";", US"d=", sig->domain);
1230 hdr = pdkim_headcat(&col, hdr, US";", US"s=", sig->selector);
1231 
1232 /* list of header names can be split between items. */
1233   {
1234   uschar * n = string_copy(sig->headernames);
1235   uschar * i = US"h=";
1236   uschar * s = US";";
1237 
1238   while (*n)
1239     {
1240     uschar * c = Ustrchr(n, ':');
1241 
1242     if (c) *c ='\0';
1243 
1244     if (!i)
1245       hdr = pdkim_headcat(&col, hdr, NULL, NULL, US":");
1246 
1247     hdr = pdkim_headcat(&col, hdr, s, i, n);
1248 
1249     if (!c)
1250       break;
1251 
1252     n = c+1;
1253     s = NULL;
1254     i = NULL;
1255     }
1256   }
1257 
1258 base64_bh = pdkim_encode_base64(&sig->calc_body_hash->bh);
1259 hdr = pdkim_headcat(&col, hdr, US";", US"bh=", base64_bh);
1260 
1261 /* Optional bits */
1262 if (sig->identity)
1263   hdr = pdkim_headcat(&col, hdr, US";", US"i=", sig->identity);
1264 
1265 if (sig->created > 0)
1266   {
1267   uschar minibuf[20];
1268 
1269   snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->created);
1270   hdr = pdkim_headcat(&col, hdr, US";", US"t=", minibuf);
1271 }
1272 
1273 if (sig->expires > 0)
1274   {
1275   uschar minibuf[20];
1276 
1277   snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->expires);
1278   hdr = pdkim_headcat(&col, hdr, US";", US"x=", minibuf);
1279   }
1280 
1281 if (sig->bodylength >= 0)
1282   {
1283   uschar minibuf[20];
1284 
1285   snprintf(CS minibuf, sizeof(minibuf), "%lu", sig->bodylength);
1286   hdr = pdkim_headcat(&col, hdr, US";", US"l=", minibuf);
1287   }
1288 
1289 /* Preliminary or final version? */
1290 if (final)
1291   {
1292   base64_b = pdkim_encode_base64(&sig->sighash);
1293   hdr = pdkim_headcat(&col, hdr, US";", US"b=", base64_b);
1294 
1295   /* add trailing semicolon: I'm not sure if this is actually needed */
1296   hdr = pdkim_headcat(&col, hdr, NULL, US";", US"");
1297   }
1298 else
1299   {
1300   /* To satisfy the rule "all surrounding whitespace [...] deleted"
1301   ( RFC 6376 section 3.7 ) we ensure there is no whitespace here.  Otherwise
1302   the headcat routine could insert a linebreak which the relaxer would reduce
1303   to a single space preceding the terminating semicolon, resulting in an
1304   incorrect header-hash. */
1305   hdr = pdkim_headcat(&col, hdr, US";", US"b=;", US"");
1306   }
1307 
1308 return string_from_gstring(hdr);
1309 }
1310 
1311 
1312 /* -------------------------------------------------------------------------- */
1313 
1314 /* According to draft-ietf-dcrup-dkim-crypto-07 "keys are 256 bits" (referring
1315 to DNS, hence the pubkey).  Check for more than 32 bytes; if so assume the
1316 alternate possible representation (still) being discussed: a
1317 SubjectPublickeyInfo wrapped key - and drop all but the trailing 32-bytes (it
1318 should be a DER, with exactly 12 leading bytes - but we could accept a BER also,
1319 which could be any size).  We still rely on the crypto library for checking for
1320 undersize.
1321 
1322 When the RFC is published this should be re-addressed. */
1323 
1324 static void
check_bare_ed25519_pubkey(pdkim_pubkey * p)1325 check_bare_ed25519_pubkey(pdkim_pubkey * p)
1326 {
1327 int excess = p->key.len - 32;
1328 if (excess > 0)
1329   {
1330   DEBUG(D_acl)
1331     debug_printf("DKIM: unexpected pubkey len %lu\n", (unsigned long) p->key.len);
1332   p->key.data += excess; p->key.len = 32;
1333   }
1334 }
1335 
1336 
1337 static pdkim_pubkey *
pdkim_key_from_dns(pdkim_ctx * ctx,pdkim_signature * sig,ev_ctx * vctx,const uschar ** errstr)1338 pdkim_key_from_dns(pdkim_ctx * ctx, pdkim_signature * sig, ev_ctx * vctx,
1339   const uschar ** errstr)
1340 {
1341 uschar * dns_txt_name, * dns_txt_reply;
1342 pdkim_pubkey * p;
1343 
1344 /* Fetch public key for signing domain, from DNS */
1345 
1346 dns_txt_name = string_sprintf("%s._domainkey.%s.", sig->selector, sig->domain);
1347 
1348 if (  !(dns_txt_reply = ctx->dns_txt_callback(dns_txt_name))
1349    || dns_txt_reply[0] == '\0'
1350    )
1351   {
1352   sig->verify_status =      PDKIM_VERIFY_INVALID;
1353   sig->verify_ext_status =  PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE;
1354   return NULL;
1355   }
1356 
1357 DEBUG(D_acl)
1358   {
1359   debug_printf(
1360     "DKIM >> Parsing public key record >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"
1361     " %s\n"
1362     " Raw record: ",
1363     dns_txt_name);
1364   pdkim_quoteprint(CUS dns_txt_reply, Ustrlen(dns_txt_reply));
1365   }
1366 
1367 if (  !(p = pdkim_parse_pubkey_record(CUS dns_txt_reply))
1368    || (Ustrcmp(p->srvtype, "*") != 0 && Ustrcmp(p->srvtype, "email") != 0)
1369    )
1370   {
1371   sig->verify_status =      PDKIM_VERIFY_INVALID;
1372   sig->verify_ext_status =  PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD;
1373 
1374   DEBUG(D_acl)
1375     {
1376     if (p)
1377       debug_printf(" Invalid public key service type '%s'\n", p->srvtype);
1378     else
1379       debug_printf(" Error while parsing public key record\n");
1380     debug_printf(
1381       "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1382     }
1383   return NULL;
1384   }
1385 
1386 DEBUG(D_acl) debug_printf(
1387       "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1388 
1389 /* Import public key */
1390 
1391 /* Normally we use the signature a= tag to tell us the pubkey format.
1392 When signing under debug we do a test-import of the pubkey, and at that
1393 time we do not have a signature so we must interpret the pubkey k= tag
1394 instead.  Assume writing on the sig is ok in that case. */
1395 
1396 if (sig->keytype < 0)
1397   if ((sig->keytype = pdkim_keyname_to_keytype(p->keytype)) < 0)
1398     {
1399     DEBUG(D_acl) debug_printf("verify_init: unhandled keytype %s\n", p->keytype);
1400     sig->verify_status =      PDKIM_VERIFY_INVALID;
1401     sig->verify_ext_status =  PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
1402     return NULL;
1403     }
1404 
1405 if (sig->keytype == KEYTYPE_ED25519)
1406   check_bare_ed25519_pubkey(p);
1407 
1408 if ((*errstr = exim_dkim_verify_init(&p->key,
1409 	    sig->keytype == KEYTYPE_ED25519 ? KEYFMT_ED25519_BARE : KEYFMT_DER,
1410 	    vctx, &sig->keybits)))
1411   {
1412   DEBUG(D_acl) debug_printf("verify_init: %s\n", *errstr);
1413   sig->verify_status =      PDKIM_VERIFY_INVALID;
1414   sig->verify_ext_status =  PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
1415   return NULL;
1416   }
1417 
1418 vctx->keytype = sig->keytype;
1419 return p;
1420 }
1421 
1422 
1423 /* -------------------------------------------------------------------------- */
1424 /* Sort and filter the sigs developed from the message */
1425 
1426 static pdkim_signature *
sort_sig_methods(pdkim_signature * siglist)1427 sort_sig_methods(pdkim_signature * siglist)
1428 {
1429 pdkim_signature * yield, ** ss;
1430 const uschar * prefs;
1431 uschar * ele;
1432 int sep;
1433 
1434 if (!siglist) return NULL;
1435 
1436 /* first select in order of hashtypes */
1437 DEBUG(D_acl) debug_printf("DKIM: dkim_verify_hashes   '%s'\n", dkim_verify_hashes);
1438 for (prefs = dkim_verify_hashes, sep = 0, yield = NULL, ss = &yield;
1439      ele = string_nextinlist(&prefs, &sep, NULL, 0); )
1440   {
1441   int i = pdkim_hashname_to_hashtype(CUS ele, 0);
1442   for (pdkim_signature * s = siglist, * next, ** prev = &siglist; s;
1443        s = next)
1444     {
1445     next = s->next;
1446     if (s->hashtype == i)
1447       { *prev = next; s->next = NULL; *ss = s; ss = &s->next; }
1448     else
1449       prev = &s->next;
1450     }
1451   }
1452 
1453 /* then in order of keytypes */
1454 siglist = yield;
1455 DEBUG(D_acl) debug_printf("DKIM: dkim_verify_keytypes '%s'\n", dkim_verify_keytypes);
1456 for (prefs = dkim_verify_keytypes, sep = 0, yield = NULL, ss = &yield;
1457      ele = string_nextinlist(&prefs, &sep, NULL, 0); )
1458   {
1459   int i = pdkim_keyname_to_keytype(CUS ele);
1460   for (pdkim_signature * s = siglist, * next, ** prev = &siglist; s;
1461        s = next)
1462     {
1463     next = s->next;
1464     if (s->keytype == i)
1465       { *prev = next; s->next = NULL; *ss = s; ss = &s->next; }
1466     else
1467       prev = &s->next;
1468     }
1469   }
1470 
1471 DEBUG(D_acl) for (pdkim_signature * s = yield; s; s = s->next)
1472   debug_printf(" retain d=%s s=%s a=%s\n",
1473     s->domain, s->selector, dkim_sig_to_a_tag(s));
1474 return yield;
1475 }
1476 
1477 
1478 /* -------------------------------------------------------------------------- */
1479 
1480 DLLEXPORT int
pdkim_feed_finish(pdkim_ctx * ctx,pdkim_signature ** return_signatures,const uschar ** err)1481 pdkim_feed_finish(pdkim_ctx * ctx, pdkim_signature ** return_signatures,
1482   const uschar ** err)
1483 {
1484 BOOL verify_pass = FALSE;
1485 
1486 /* Check if we must still flush a (partial) header. If that is the
1487    case, the message has no body, and we must compute a body hash
1488    out of '<CR><LF>' */
1489 if (ctx->cur_header && ctx->cur_header->ptr > 0)
1490   {
1491   blob * rnl = NULL;
1492   int rc;
1493 
1494   if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK)
1495     return rc;
1496 
1497   for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next)
1498     rnl = pdkim_update_ctx_bodyhash(b, &lineending, rnl);
1499   if (rnl) store_free(rnl);
1500   }
1501 else
1502   DEBUG(D_acl) debug_printf(
1503       "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1504 
1505 /* Build (and/or evaluate) body hash.  Do this even if no DKIM sigs, in case we
1506 have a hash to do for ARC. */
1507 
1508 pdkim_finish_bodyhash(ctx);
1509 
1510 /* Sort and filter the recived signatures */
1511 
1512 if (!(ctx->flags & PDKIM_MODE_SIGN))
1513   ctx->sig = sort_sig_methods(ctx->sig);
1514 
1515 if (!ctx->sig)
1516   {
1517   DEBUG(D_acl) debug_printf("DKIM: no signatures\n");
1518   *return_signatures = NULL;
1519   return PDKIM_OK;
1520   }
1521 
1522 for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next)
1523   {
1524   hctx hhash_ctx;
1525   uschar * sig_hdr = US"";
1526   blob hhash;
1527   gstring * hdata = NULL;
1528   es_ctx sctx;
1529 
1530   if (  !(ctx->flags & PDKIM_MODE_SIGN)
1531      && sig->verify_status == PDKIM_VERIFY_FAIL)
1532     {
1533     DEBUG(D_acl)
1534        debug_printf("DKIM: [%s] abandoning this signature\n", sig->domain);
1535     continue;
1536     }
1537 
1538   /*XXX The hash of the headers is needed for GCrypt (for which we can do RSA
1539   signing only, as it happens) and for either GnuTLS and OpenSSL when we are
1540   signing with EC (specifically, Ed25519).  The former is because the GCrypt
1541   signing operation is pure (does not do its own hash) so we must hash.  The
1542   latter is because we (stupidly, but this is what the IETF draft is saying)
1543   must hash with the declared hash method, then pass the result to the library
1544   hash-and-sign routine (because that's all the libraries are providing.  And
1545   we're stuck with whatever that hidden hash method is, too).  We may as well
1546   do this hash incrementally.
1547   We don't need the hash we're calculating here for the GnuTLS and OpenSSL
1548   cases of RSA signing, since those library routines can do hash-and-sign.
1549 
1550   Some time in the future we could easily avoid doing the hash here for those
1551   cases (which will be common for a long while.  We could also change from
1552   the current copy-all-the-headers-into-one-block, then call the hash-and-sign
1553   implementation  - to a proper incremental one.  Unfortunately, GnuTLS just
1554   cannot do incremental - either signing or verification.  Unsure about GCrypt.
1555   */
1556 
1557   /*XXX The header hash is also used (so far) by the verify operation */
1558 
1559   if (!exim_sha_init(&hhash_ctx, pdkim_hashes[sig->hashtype].exim_hashmethod))
1560     {
1561     log_write(0, LOG_MAIN|LOG_PANIC,
1562       "DKIM: hash setup error, possibly nonhandled hashtype");
1563     break;
1564     }
1565 
1566   if (ctx->flags & PDKIM_MODE_SIGN)
1567     DEBUG(D_acl) debug_printf(
1568 	"DKIM >> Headers to be signed:                            >>>>>>>>>>>>\n"
1569 	" %s\n",
1570 	sig->sign_headers);
1571 
1572   DEBUG(D_acl) debug_printf(
1573       "DKIM >> Header data for hash, canonicalized (%-7s), in sequence >>\n",
1574 	pdkim_canons[sig->canon_headers]);
1575 
1576 
1577   /* SIGNING ---------------------------------------------------------------- */
1578   /* When signing, walk through our header list and add them to the hash. As we
1579      go, construct a list of the header's names to use for the h= parameter.
1580      Then append to that list any remaining header names for which there was no
1581      header to sign. */
1582 
1583   if (ctx->flags & PDKIM_MODE_SIGN)
1584     {
1585     gstring * g = NULL;
1586     const uschar * l;
1587     uschar * s;
1588     int sep = 0;
1589 
1590     /* Import private key, including the keytype which we need for building
1591     the signature header  */
1592 
1593     if ((*err = exim_dkim_signing_init(CUS sig->privkey, &sctx)))
1594       {
1595       log_write(0, LOG_MAIN|LOG_PANIC, "signing_init: %s", *err);
1596       return PDKIM_ERR_RSA_PRIVKEY;
1597       }
1598     sig->keytype = sctx.keytype;
1599 
1600     sig->headernames = NULL;			/* Collected signed header names */
1601     for (pdkim_stringlist * p = sig->headers; p; p = p->next)
1602       {
1603       uschar * rh = p->value;
1604 
1605       if (header_name_match(rh, sig->sign_headers) == PDKIM_OK)
1606 	{
1607 	/* Collect header names (Note: colon presence is guaranteed here) */
1608 	g = string_append_listele_n(g, ':', rh, Ustrchr(rh, ':') - rh);
1609 
1610 	if (sig->canon_headers == PDKIM_CANON_RELAXED)
1611 	  rh = pdkim_relax_header(rh, TRUE);	/* cook header for relaxed canon */
1612 
1613 	/* Feed header to the hash algorithm */
1614 	exim_sha_update(&hhash_ctx, CUS rh, Ustrlen(rh));
1615 
1616 	/* Remember headers block for signing (when the library cannot do incremental)  */
1617 	/*XXX we could avoid doing this for all but the GnuTLS/RSA case */
1618 	hdata = exim_dkim_data_append(hdata, rh);
1619 
1620 	DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1621 	}
1622       }
1623 
1624     /* Any headers we wanted to sign but were not present must also be listed.
1625     Ignore elements that have been ticked-off or are marked as never-oversign. */
1626 
1627     l = sig->sign_headers;
1628     while((s = string_nextinlist(&l, &sep, NULL, 0)))
1629       {
1630       if (*s == '+')			/* skip oversigning marker */
1631         s++;
1632       if (*s != '_' && *s != '=')
1633 	g = string_append_listele(g, ':', s);
1634       }
1635     sig->headernames = string_from_gstring(g);
1636 
1637     /* Create signature header with b= omitted */
1638     sig_hdr = pdkim_create_header(sig, FALSE);
1639     }
1640 
1641   /* VERIFICATION ----------------------------------------------------------- */
1642   /* When verifying, walk through the header name list in the h= parameter and
1643      add the headers to the hash in that order. */
1644   else
1645     {
1646     uschar * p = sig->headernames;
1647     uschar * q;
1648 
1649     if (p)
1650       {
1651       /* clear tags */
1652       for (pdkim_stringlist * hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1653 	hdrs->tag = 0;
1654 
1655       p = string_copy(p);
1656       while(1)
1657 	{
1658 	if ((q = Ustrchr(p, ':')))
1659 	  *q = '\0';
1660 
1661   /*XXX walk the list of headers in same order as received. */
1662 	for (pdkim_stringlist * hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1663 	  if (  hdrs->tag == 0
1664 	     && strncasecmp(CCS hdrs->value, CCS p, Ustrlen(p)) == 0
1665 	     && (hdrs->value)[Ustrlen(p)] == ':'
1666 	     )
1667 	    {
1668 	    /* cook header for relaxed canon, or just copy it for simple  */
1669 
1670 	    uschar * rh = sig->canon_headers == PDKIM_CANON_RELAXED
1671 	      ? pdkim_relax_header(hdrs->value, TRUE)
1672 	      : string_copy(CUS hdrs->value);
1673 
1674 	    /* Feed header to the hash algorithm */
1675 	    exim_sha_update(&hhash_ctx, CUS rh, Ustrlen(rh));
1676 
1677 	    DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1678 	    hdrs->tag = 1;
1679 	    break;
1680 	    }
1681 
1682 	if (!q) break;
1683 	p = q+1;
1684 	}
1685 
1686       sig_hdr = string_copy(sig->rawsig_no_b_val);
1687       }
1688     }
1689 
1690   DEBUG(D_acl) debug_printf(
1691 	    "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1692 
1693   DEBUG(D_acl)
1694     {
1695     debug_printf(
1696 	    "DKIM >> Signed DKIM-Signature header, pre-canonicalized >>>>>>>>>>>>>\n");
1697     pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr));
1698     debug_printf(
1699 	    "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1700     }
1701 
1702   /* Relax header if necessary */
1703   if (sig->canon_headers == PDKIM_CANON_RELAXED)
1704     sig_hdr = pdkim_relax_header(sig_hdr, FALSE);
1705 
1706   DEBUG(D_acl)
1707     {
1708     debug_printf("DKIM >> Signed DKIM-Signature header, canonicalized (%-7s) >>>>>>>\n",
1709 	    pdkim_canons[sig->canon_headers]);
1710     pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr));
1711     debug_printf(
1712 	    "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1713     }
1714 
1715   /* Finalize header hash */
1716   exim_sha_update(&hhash_ctx, CUS sig_hdr, Ustrlen(sig_hdr));
1717   exim_sha_finish(&hhash_ctx, &hhash);
1718 
1719   DEBUG(D_acl)
1720     {
1721     debug_printf("DKIM [%s] Header %s computed: ",
1722       sig->domain, pdkim_hashes[sig->hashtype].dkim_hashname);
1723     pdkim_hexprint(hhash.data, hhash.len);
1724     }
1725 
1726   /* Remember headers block for signing (when the signing library cannot do
1727   incremental)  */
1728   if (ctx->flags & PDKIM_MODE_SIGN)
1729     hdata = exim_dkim_data_append(hdata, US sig_hdr);
1730 
1731   /* SIGNING ---------------------------------------------------------------- */
1732   if (ctx->flags & PDKIM_MODE_SIGN)
1733     {
1734     hashmethod hm = sig->keytype == KEYTYPE_ED25519
1735 #if defined(SIGN_OPENSSL)
1736       ? HASH_NULL
1737 #else
1738       ? HASH_SHA2_512
1739 #endif
1740       : pdkim_hashes[sig->hashtype].exim_hashmethod;
1741 
1742 #ifdef SIGN_HAVE_ED25519
1743     /* For GCrypt, and for EC, we pass the hash-of-headers to the signing
1744     routine.  For anything else we just pass the headers. */
1745 
1746     if (sig->keytype != KEYTYPE_ED25519)
1747 #endif
1748       {
1749       hhash.data = hdata->s;
1750       hhash.len = hdata->ptr;
1751       }
1752 
1753     if ((*err = exim_dkim_sign(&sctx, hm, &hhash, &sig->sighash)))
1754       {
1755       log_write(0, LOG_MAIN|LOG_PANIC, "signing: %s", *err);
1756       return PDKIM_ERR_RSA_SIGNING;
1757       }
1758 
1759     DEBUG(D_acl)
1760       {
1761       debug_printf( "DKIM [%s] b computed: ", sig->domain);
1762       pdkim_hexprint(sig->sighash.data, sig->sighash.len);
1763       }
1764 
1765     sig->signature_header = pdkim_create_header(sig, TRUE);
1766     }
1767 
1768   /* VERIFICATION ----------------------------------------------------------- */
1769   else
1770     {
1771     ev_ctx vctx;
1772     hashmethod hm;
1773 
1774     /* Make sure we have all required signature tags */
1775     if (!(  sig->domain        && *sig->domain
1776 	 && sig->selector      && *sig->selector
1777 	 && sig->headernames   && *sig->headernames
1778 	 && sig->bodyhash.data
1779 	 && sig->sighash.data
1780 	 && sig->keytype >= 0
1781 	 && sig->hashtype >= 0
1782 	 && sig->version
1783        ) )
1784       {
1785       sig->verify_status     = PDKIM_VERIFY_INVALID;
1786       sig->verify_ext_status = PDKIM_VERIFY_INVALID_SIGNATURE_ERROR;
1787 
1788       DEBUG(D_acl) debug_printf(
1789 	  " Error in DKIM-Signature header: tags missing or invalid (%s)\n"
1790 	  "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
1791 	  !(sig->domain && *sig->domain) ? "d="
1792 	  : !(sig->selector && *sig->selector) ? "s="
1793 	  : !(sig->headernames && *sig->headernames) ? "h="
1794 	  : !sig->bodyhash.data ? "bh="
1795 	  : !sig->sighash.data ? "b="
1796 	  : sig->keytype < 0 || sig->hashtype < 0 ? "a="
1797 	  : "v="
1798 	  );
1799       goto NEXT_VERIFY;
1800       }
1801 
1802     /* Make sure sig uses supported DKIM version (only v1) */
1803     if (sig->version != 1)
1804       {
1805       sig->verify_status     = PDKIM_VERIFY_INVALID;
1806       sig->verify_ext_status = PDKIM_VERIFY_INVALID_DKIM_VERSION;
1807 
1808       DEBUG(D_acl) debug_printf(
1809           " Error in DKIM-Signature header: unsupported DKIM version\n"
1810           "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1811       goto NEXT_VERIFY;
1812       }
1813 
1814     DEBUG(D_acl)
1815       {
1816       debug_printf( "DKIM [%s] b from mail: ", sig->domain);
1817       pdkim_hexprint(sig->sighash.data, sig->sighash.len);
1818       }
1819 
1820     if (!(sig->pubkey = pdkim_key_from_dns(ctx, sig, &vctx, err)))
1821       {
1822       log_write(0, LOG_MAIN, "DKIM: %s%s %s%s [failed key import]",
1823 	sig->domain   ? "d=" : "", sig->domain   ? sig->domain   : US"",
1824 	sig->selector ? "s=" : "", sig->selector ? sig->selector : US"");
1825       goto NEXT_VERIFY;
1826       }
1827 
1828     /* If the pubkey limits to a list of specific hashes, ignore sigs that
1829     do not have the hash part of the sig algorithm matching */
1830 
1831     if (sig->pubkey->hashes)
1832       {
1833       const uschar * list = sig->pubkey->hashes, * ele;
1834       int sep = ':';
1835       while ((ele = string_nextinlist(&list, &sep, NULL, 0)))
1836 	if (Ustrcmp(ele, pdkim_hashes[sig->hashtype].dkim_hashname) == 0) break;
1837       if (!ele)
1838 	{
1839 	DEBUG(D_acl) debug_printf("pubkey h=%s vs. sig a=%s_%s\n",
1840 	  sig->pubkey->hashes,
1841 	  pdkim_keytypes[sig->keytype],
1842 	  pdkim_hashes[sig->hashtype].dkim_hashname);
1843 	sig->verify_status =      PDKIM_VERIFY_FAIL;
1844 	sig->verify_ext_status =  PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH;
1845 	goto NEXT_VERIFY;
1846 	}
1847       }
1848 
1849     hm = sig->keytype == KEYTYPE_ED25519
1850 #if defined(SIGN_OPENSSL)
1851       ? HASH_NULL
1852 #else
1853       ? HASH_SHA2_512
1854 #endif
1855       : pdkim_hashes[sig->hashtype].exim_hashmethod;
1856 
1857     /* Check the signature */
1858 
1859     if ((*err = exim_dkim_verify(&vctx, hm, &hhash, &sig->sighash)))
1860       {
1861       DEBUG(D_acl) debug_printf("headers verify: %s\n", *err);
1862       sig->verify_status =      PDKIM_VERIFY_FAIL;
1863       sig->verify_ext_status =  PDKIM_VERIFY_FAIL_MESSAGE;
1864       goto NEXT_VERIFY;
1865       }
1866     if (*dkim_verify_min_keysizes)
1867       {
1868       unsigned minbits;
1869       uschar * ss = expand_getkeyed(US pdkim_keytypes[sig->keytype],
1870 				    dkim_verify_min_keysizes);
1871       if (ss &&  (minbits = atoi(CS ss)) > sig->keybits)
1872 	{
1873 	DEBUG(D_acl) debug_printf("Key too short: Actual: %s %u  Minima '%s'\n",
1874 	  pdkim_keytypes[sig->keytype], sig->keybits, dkim_verify_min_keysizes);
1875 	sig->verify_status =      PDKIM_VERIFY_FAIL;
1876 	sig->verify_ext_status =  PDKIM_VERIFY_INVALID_PUBKEY_KEYSIZE;
1877 	}
1878       }
1879 
1880 
1881     /* We have a winner! (if bodyhash was correct earlier) */
1882     if (sig->verify_status == PDKIM_VERIFY_NONE)
1883       {
1884       sig->verify_status = PDKIM_VERIFY_PASS;
1885       verify_pass = TRUE;
1886       if (dkim_verify_minimal) break;
1887       }
1888 
1889 NEXT_VERIFY:
1890 
1891     DEBUG(D_acl)
1892       {
1893       debug_printf("DKIM [%s] %s signature status: %s",
1894 	      sig->domain, dkim_sig_to_a_tag(sig),
1895 	      pdkim_verify_status_str(sig->verify_status));
1896       if (sig->verify_ext_status > 0)
1897 	debug_printf(" (%s)\n",
1898 		pdkim_verify_ext_status_str(sig->verify_ext_status));
1899       else
1900 	debug_printf("\n");
1901       }
1902     }
1903   }
1904 
1905 /* If requested, set return pointer to signature(s) */
1906 if (return_signatures)
1907   *return_signatures = ctx->sig;
1908 
1909 return ctx->flags & PDKIM_MODE_SIGN  ||  verify_pass
1910   ? PDKIM_OK : PDKIM_FAIL;
1911 }
1912 
1913 
1914 /* -------------------------------------------------------------------------- */
1915 
1916 DLLEXPORT pdkim_ctx *
pdkim_init_verify(uschar * (* dns_txt_callback)(const uschar *),BOOL dot_stuffing)1917 pdkim_init_verify(uschar * (*dns_txt_callback)(const uschar *), BOOL dot_stuffing)
1918 {
1919 pdkim_ctx * ctx;
1920 
1921 ctx = store_get(sizeof(pdkim_ctx), FALSE);
1922 memset(ctx, 0, sizeof(pdkim_ctx));
1923 
1924 if (dot_stuffing) ctx->flags = PDKIM_DOT_TERM;
1925 /* The line-buffer is for message data, hence tainted */
1926 ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN, TRUE);
1927 ctx->dns_txt_callback = dns_txt_callback;
1928 ctx->cur_header = string_get_tainted(36, TRUE);
1929 
1930 return ctx;
1931 }
1932 
1933 
1934 /* -------------------------------------------------------------------------- */
1935 
1936 DLLEXPORT pdkim_signature *
pdkim_init_sign(pdkim_ctx * ctx,uschar * domain,uschar * selector,uschar * privkey,uschar * hashname,const uschar ** errstr)1937 pdkim_init_sign(pdkim_ctx * ctx,
1938   uschar * domain, uschar * selector, uschar * privkey,
1939   uschar * hashname, const uschar ** errstr)
1940 {
1941 int hashtype;
1942 pdkim_signature * sig;
1943 
1944 if (!domain || !selector || !privkey)
1945   return NULL;
1946 
1947 /* Allocate & init one signature struct */
1948 
1949 sig = store_get(sizeof(pdkim_signature), FALSE);
1950 memset(sig, 0, sizeof(pdkim_signature));
1951 
1952 sig->bodylength = -1;
1953 
1954 sig->domain = string_copy(US domain);
1955 sig->selector = string_copy(US selector);
1956 sig->privkey = string_copy(US privkey);
1957 sig->keytype = -1;
1958 
1959 for (hashtype = 0; hashtype < nelem(pdkim_hashes); hashtype++)
1960   if (Ustrcmp(hashname, pdkim_hashes[hashtype].dkim_hashname) == 0)
1961   { sig->hashtype = hashtype; break; }
1962 if (hashtype >= nelem(pdkim_hashes))
1963   {
1964   log_write(0, LOG_MAIN|LOG_PANIC,
1965     "DKIM: unrecognised hashname '%s'", hashname);
1966   return NULL;
1967   }
1968 
1969 DEBUG(D_acl)
1970   {
1971   pdkim_signature s = *sig;
1972   ev_ctx vctx;
1973 
1974   debug_printf("DKIM (checking verify key)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1975   if (!pdkim_key_from_dns(ctx, &s, &vctx, errstr))
1976     debug_printf("WARNING: bad dkim key in dns\n");
1977   debug_printf("DKIM (finished checking verify key)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1978   }
1979 return sig;
1980 }
1981 
1982 
1983 /* -------------------------------------------------------------------------- */
1984 
1985 DLLEXPORT void
pdkim_set_optional(pdkim_signature * sig,char * sign_headers,char * identity,int canon_headers,int canon_body,long bodylength,unsigned long created,unsigned long expires)1986 pdkim_set_optional(pdkim_signature * sig,
1987                        char * sign_headers,
1988                        char * identity,
1989                        int canon_headers,
1990                        int canon_body,
1991                        long bodylength,
1992                        unsigned long created,
1993                        unsigned long expires)
1994 {
1995 if (identity)
1996   sig->identity = string_copy(US identity);
1997 
1998 sig->sign_headers = string_copy(sign_headers
1999 	? US sign_headers : US PDKIM_DEFAULT_SIGN_HEADERS);
2000 
2001 sig->canon_headers = canon_headers;
2002 sig->canon_body = canon_body;
2003 sig->bodylength = bodylength;
2004 sig->created = created;
2005 sig->expires = expires;
2006 
2007 return;
2008 }
2009 
2010 
2011 
2012 /* Set up a blob for calculating the bodyhash according to the
2013 given needs.  Use an existing one if possible, or create a new one.
2014 
2015 Return: hashblob pointer, or NULL on error
2016 */
2017 pdkim_bodyhash *
pdkim_set_bodyhash(pdkim_ctx * ctx,int hashtype,int canon_method,long bodylength)2018 pdkim_set_bodyhash(pdkim_ctx * ctx, int hashtype, int canon_method,
2019 	long bodylength)
2020 {
2021 pdkim_bodyhash * b;
2022 
2023 if (hashtype == -1 || canon_method == -1) return NULL;
2024 
2025 for (b = ctx->bodyhash; b; b = b->next)
2026   if (  hashtype == b->hashtype
2027      && canon_method == b->canon_method
2028      && bodylength == b->bodylength)
2029     {
2030     DEBUG(D_receive) debug_printf("DKIM: using existing bodyhash %d/%d/%ld\n",
2031 				  hashtype, canon_method, bodylength);
2032     return b;
2033     }
2034 
2035 DEBUG(D_receive) debug_printf("DKIM: new bodyhash %d/%d/%ld\n",
2036 			      hashtype, canon_method, bodylength);
2037 b = store_get(sizeof(pdkim_bodyhash), FALSE);
2038 b->next = ctx->bodyhash;
2039 b->hashtype = hashtype;
2040 b->canon_method = canon_method;
2041 b->bodylength = bodylength;
2042 if (!exim_sha_init(&b->body_hash_ctx,		/*XXX hash method: extend for sha512 */
2043 		  pdkim_hashes[hashtype].exim_hashmethod))
2044   {
2045   DEBUG(D_acl)
2046     debug_printf("DKIM: hash init error, possibly nonhandled hashtype\n");
2047   return NULL;
2048   }
2049 b->signed_body_bytes = 0;
2050 b->num_buffered_blanklines = 0;
2051 ctx->bodyhash = b;
2052 return b;
2053 }
2054 
2055 
2056 /* Set up a blob for calculating the bodyhash according to the
2057 needs of this signature.  Use an existing one if possible, or
2058 create a new one.
2059 
2060 Return: hashblob pointer, or NULL on error (only used as a boolean).
2061 */
2062 pdkim_bodyhash *
pdkim_set_sig_bodyhash(pdkim_ctx * ctx,pdkim_signature * sig)2063 pdkim_set_sig_bodyhash(pdkim_ctx * ctx, pdkim_signature * sig)
2064 {
2065 pdkim_bodyhash * b = pdkim_set_bodyhash(ctx,
2066 			sig->hashtype, sig->canon_body, sig->bodylength);
2067 sig->calc_body_hash = b;
2068 return b;
2069 }
2070 
2071 
2072 /* -------------------------------------------------------------------------- */
2073 
2074 
2075 void
pdkim_init_context(pdkim_ctx * ctx,BOOL dot_stuffed,uschar * (* dns_txt_callback)(const uschar *))2076 pdkim_init_context(pdkim_ctx * ctx, BOOL dot_stuffed,
2077   uschar * (*dns_txt_callback)(const uschar *))
2078 {
2079 memset(ctx, 0, sizeof(pdkim_ctx));
2080 ctx->flags = dot_stuffed ? PDKIM_MODE_SIGN | PDKIM_DOT_TERM : PDKIM_MODE_SIGN;
2081 /* The line buffer is for message data, hence tainted */
2082 ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN, TRUE);
2083 DEBUG(D_acl) ctx->dns_txt_callback = dns_txt_callback;
2084 }
2085 
2086 
2087 void
pdkim_init(void)2088 pdkim_init(void)
2089 {
2090 exim_dkim_init();
2091 }
2092 
2093 
2094 
2095 #endif	/*DISABLE_DKIM*/
2096