DKIM: fix selection of header for signing/verification given several. Bug 1792
[users/jgh/exim.git] / src / src / pdkim / pdkim.c
1 /*
2  *  PDKIM - a RFC4871 (DKIM) implementation
3  *
4  *  Copyright (C) 2009 - 2016  Tom Kistner <tom@duncanthrax.net>
5  *  Copyright (C) 2016  Jeremy Harris <jgh@exim.org>
6  *
7  *  http://duncanthrax.net/pdkim/
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License along
20  *  with this program; if not, write to the Free Software Foundation, Inc.,
21  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23
24 #include "../exim.h"
25
26
27 #ifndef DISABLE_DKIM    /* entire file */
28
29 #ifndef SUPPORT_TLS
30 # error Need SUPPORT_TLS for DKIM
31 #endif
32
33 #include "crypt_ver.h"
34
35 #ifdef RSA_OPENSSL
36 # include <openssl/rsa.h>
37 # include <openssl/ssl.h>
38 # include <openssl/err.h>
39 #elif defined(RSA_GNUTLS)
40 # include <gnutls/gnutls.h>
41 # include <gnutls/x509.h>
42 #endif
43
44 #include "pdkim.h"
45 #include "rsa.h"
46
47 #define PDKIM_SIGNATURE_VERSION     "1"
48 #define PDKIM_PUB_RECORD_VERSION    "DKIM1"
49
50 #define PDKIM_MAX_HEADER_LEN        65536
51 #define PDKIM_MAX_HEADERS           512
52 #define PDKIM_MAX_BODY_LINE_LEN     16384
53 #define PDKIM_DNS_TXT_MAX_NAMELEN   1024
54 #define PDKIM_DEFAULT_SIGN_HEADERS "From:Sender:Reply-To:Subject:Date:"\
55                              "Message-ID:To:Cc:MIME-Version:Content-Type:"\
56                              "Content-Transfer-Encoding:Content-ID:"\
57                              "Content-Description:Resent-Date:Resent-From:"\
58                              "Resent-Sender:Resent-To:Resent-Cc:"\
59                              "Resent-Message-ID:In-Reply-To:References:"\
60                              "List-Id:List-Help:List-Unsubscribe:"\
61                              "List-Subscribe:List-Post:List-Owner:List-Archive"
62
63 /* -------------------------------------------------------------------------- */
64 struct pdkim_stringlist {
65   char *value;
66   int  tag;
67   void *next;
68 };
69
70 #define PDKIM_STR_ALLOC_FRAG 256
71 struct pdkim_str {
72   char         *str;
73   unsigned int  len;
74   unsigned int  allocated;
75 };
76
77 /* -------------------------------------------------------------------------- */
78 /* A bunch of list constants */
79 const char *pdkim_querymethods[] = {
80   "dns/txt",
81   NULL
82 };
83 const char *pdkim_algos[] = {
84   "rsa-sha256",
85   "rsa-sha1",
86   NULL
87 };
88 const char *pdkim_canons[] = {
89   "simple",
90   "relaxed",
91   NULL
92 };
93 const char *pdkim_hashes[] = {
94   "sha256",
95   "sha1",
96   NULL
97 };
98 const char *pdkim_keytypes[] = {
99   "rsa",
100   NULL
101 };
102
103 typedef struct pdkim_combined_canon_entry {
104   const char *str;
105   int canon_headers;
106   int canon_body;
107 } pdkim_combined_canon_entry;
108
109 pdkim_combined_canon_entry pdkim_combined_canons[] = {
110   { "simple/simple",    PDKIM_CANON_SIMPLE,   PDKIM_CANON_SIMPLE },
111   { "simple/relaxed",   PDKIM_CANON_SIMPLE,   PDKIM_CANON_RELAXED },
112   { "relaxed/simple",   PDKIM_CANON_RELAXED,  PDKIM_CANON_SIMPLE },
113   { "relaxed/relaxed",  PDKIM_CANON_RELAXED,  PDKIM_CANON_RELAXED },
114   { "simple",           PDKIM_CANON_SIMPLE,   PDKIM_CANON_SIMPLE },
115   { "relaxed",          PDKIM_CANON_RELAXED,  PDKIM_CANON_SIMPLE },
116   { NULL,               0,                    0 }
117 };
118
119
120 /* -------------------------------------------------------------------------- */
121
122 const char *
123 pdkim_verify_status_str(int status)
124 {
125   switch(status) {
126     case PDKIM_VERIFY_NONE:    return "PDKIM_VERIFY_NONE";
127     case PDKIM_VERIFY_INVALID: return "PDKIM_VERIFY_INVALID";
128     case PDKIM_VERIFY_FAIL:    return "PDKIM_VERIFY_FAIL";
129     case PDKIM_VERIFY_PASS:    return "PDKIM_VERIFY_PASS";
130     default:                   return "PDKIM_VERIFY_UNKNOWN";
131   }
132 }
133
134 const char *
135 pdkim_verify_ext_status_str(int ext_status)
136 {
137   switch(ext_status) {
138     case PDKIM_VERIFY_FAIL_BODY: return "PDKIM_VERIFY_FAIL_BODY";
139     case PDKIM_VERIFY_FAIL_MESSAGE: return "PDKIM_VERIFY_FAIL_MESSAGE";
140     case PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE: return "PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE";
141     case PDKIM_VERIFY_INVALID_BUFFER_SIZE: return "PDKIM_VERIFY_INVALID_BUFFER_SIZE";
142     case PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD: return "PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD";
143     case PDKIM_VERIFY_INVALID_PUBKEY_IMPORT: return "PDKIM_VERIFY_INVALID_PUBKEY_IMPORT";
144     default: return "PDKIM_VERIFY_UNKNOWN";
145   }
146 }
147
148
149 /* -------------------------------------------------------------------------- */
150 /* Print debugging functions */
151 static void
152 pdkim_quoteprint(const char *data, int len)
153 {
154 int i;
155 const unsigned char *p = (const unsigned char *)data;
156
157 for (i = 0; i < len; i++)
158   {
159   const int c = p[i];
160   switch (c)
161     {
162     case ' ' : debug_printf("{SP}"); break;
163     case '\t': debug_printf("{TB}"); break;
164     case '\r': debug_printf("{CR}"); break;
165     case '\n': debug_printf("{LF}"); break;
166     case '{' : debug_printf("{BO}"); break;
167     case '}' : debug_printf("{BC}"); break;
168     default:
169       if ( (c < 32) || (c > 127) )
170         debug_printf("{%02x}", c);
171       else
172         debug_printf("%c", c);
173       break;
174     }
175   }
176 debug_printf("\n");
177 }
178
179 static void
180 pdkim_hexprint(const char *data, int len)
181 {
182 int i;
183 const unsigned char *p = (const unsigned char *)data;
184
185 for (i = 0 ; i < len; i++)
186   debug_printf("%02x", p[i]);
187 debug_printf("\n");
188 }
189
190
191
192 /* SSS probably want to keep the "stringlist" notion */
193
194 static pdkim_stringlist *
195 pdkim_prepend_stringlist(pdkim_stringlist *base, char *str)
196 {
197 pdkim_stringlist *new_entry = malloc(sizeof(pdkim_stringlist));
198
199 if (!new_entry) return NULL;
200 memset(new_entry, 0, sizeof(pdkim_stringlist));
201 if (!(new_entry->value = strdup(str))) return NULL;
202 if (base) new_entry->next = base;
203 return new_entry;
204 }
205
206
207 /* -------------------------------------------------------------------------- */
208 /* A small "growing string" implementation to escape malloc/realloc hell */
209 /* String package: should be replaced by Exim standard ones */
210 /* SSS Ustrcpy */
211
212 static pdkim_str *
213 pdkim_strnew (const char *cstr)
214 {
215 unsigned int len = cstr ? strlen(cstr) : 0;
216 pdkim_str *p = malloc(sizeof(pdkim_str));
217
218 if (!p) return NULL;
219 memset(p, 0, sizeof(pdkim_str));
220 if (!(p->str = malloc(len+1)))
221   {
222   free(p);
223   return NULL;
224   }
225 p->allocated = len+1;
226 p->len = len;
227 if (cstr)
228   strcpy(p->str, cstr);
229 else
230   p->str[p->len] = '\0';
231 return p;
232 }
233
234
235 /*SSS Ustrncat */
236
237 static char *
238 pdkim_strncat(pdkim_str *str, const char *data, int len)
239 {
240 if ((str->allocated - str->len) < (len+1))
241   {
242   /* Extend the buffer */
243   int num_frags = ((len+1)/PDKIM_STR_ALLOC_FRAG)+1;
244   char *n = realloc(str->str,
245                     (str->allocated+(num_frags*PDKIM_STR_ALLOC_FRAG)));
246   if (n == NULL) return NULL;
247   str->str = n;
248   str->allocated += (num_frags*PDKIM_STR_ALLOC_FRAG);
249   }
250 strncpy(&(str->str[str->len]), data, len);
251 str->len += len;
252 str->str[str->len] = '\0';
253 return str->str;
254 }
255
256
257 /* SSS Ustrcat */
258
259 static char *
260 pdkim_strcat(pdkim_str *str, const char *cstr)
261 {
262 return pdkim_strncat(str, cstr, strlen(cstr));
263 }
264
265
266
267 /* Trim whitespace fore & aft */
268
269 static char *
270 pdkim_strtrim(pdkim_str *str)
271 {
272 char *p = str->str;
273 char *q = str->str;
274 while (*p == '\t' || *p == ' ') p++;            /* skip whitespace */
275 while (*p) {*q = *p; q++; p++;}                 /* dump the leading whitespace */
276 *q = '\0';
277 while (q != str->str && ( (*q == '\0') || (*q == '\t') || (*q == ' ') ) )
278   {                                             /* dump trailing whitespace */
279   *q = '\0';
280   q--;
281   }
282 str->len = strlen(str->str);
283 return str->str;
284 }
285
286
287
288 static char *
289 pdkim_strclear(pdkim_str *str)
290 {
291 str->str[0] = '\0';
292 str->len = 0;
293 return str->str;
294 }
295
296
297
298 static void
299 pdkim_strfree(pdkim_str *str)
300 {
301 if (!str) return;
302 if (str->str) free(str->str);
303 free(str);
304 }
305
306
307 static void
308 pdkim_stringlist_free(pdkim_stringlist * e)
309 {
310 while(e)
311   {
312   pdkim_stringlist * c = e;
313   if (e->value) free(e->value);
314   e = e->next;
315   free(c);
316   }
317 }
318
319
320
321 /* -------------------------------------------------------------------------- */
322
323 static void
324 pdkim_free_pubkey(pdkim_pubkey *pub)
325 {
326 if (pub)
327   {
328   if (pub->version    ) free(pub->version);
329   if (pub->granularity) free(pub->granularity);
330   if (pub->hashes     ) free(pub->hashes);
331   if (pub->keytype    ) free(pub->keytype);
332   if (pub->srvtype    ) free(pub->srvtype);
333   if (pub->notes      ) free(pub->notes);
334   free(pub);
335   }
336 }
337
338
339 /* -------------------------------------------------------------------------- */
340
341 static void
342 pdkim_free_sig(pdkim_signature *sig)
343 {
344 if (sig)
345   {
346   pdkim_signature *next = (pdkim_signature *)sig->next;
347
348   pdkim_stringlist_free(sig->headers);
349   if (sig->selector        ) free(sig->selector);
350   if (sig->domain          ) free(sig->domain);
351   if (sig->identity        ) free(sig->identity);
352   if (sig->copiedheaders   ) free(sig->copiedheaders);
353   if (sig->rsa_privkey     ) free(sig->rsa_privkey);
354   if (sig->sign_headers    ) free(sig->sign_headers);
355   if (sig->signature_header) free(sig->signature_header);
356
357   if (sig->pubkey) pdkim_free_pubkey(sig->pubkey);
358
359   free(sig);
360   if (next) pdkim_free_sig(next);
361   }
362 }
363
364
365 /* -------------------------------------------------------------------------- */
366
367 DLLEXPORT void
368 pdkim_free_ctx(pdkim_ctx *ctx)
369 {
370 if (ctx)
371   {
372   pdkim_stringlist_free(ctx->headers);
373   pdkim_free_sig(ctx->sig);
374   pdkim_strfree(ctx->cur_header);
375   free(ctx);
376   }
377 }
378
379
380 /* -------------------------------------------------------------------------- */
381 /* Matches the name of the passed raw "header" against
382    the passed colon-separated "tick", and invalidates
383    the entry in tick. Returns OK or fail-code */
384 /*XXX might be safer done using a pdkim_stringlist for "tick" */
385
386 static int
387 header_name_match(const char * header, char * tick)
388 {
389 char *hname;
390 char *lcopy;
391 char *p;
392 char *q;
393 int rc = PDKIM_FAIL;
394
395 /* Get header name */
396 char *hcolon = strchr(header, ':');
397
398 if (!hcolon) return rc; /* This isn't a header */
399
400 if (!(hname = malloc((hcolon-header)+1)))
401   return PDKIM_ERR_OOM;
402 memset(hname, 0, (hcolon-header)+1);
403 strncpy(hname, header, (hcolon-header));
404
405 /* Copy tick-off list locally, so we can punch zeroes into it */
406 if (!(lcopy = strdup(tick)))
407   {
408   free(hname);
409   return PDKIM_ERR_OOM;
410   }
411 p = lcopy;
412 q = strchr(p, ':');
413 while (q)
414   {
415   *q = '\0';
416
417   if (strcasecmp(p, hname) == 0)
418     {
419     rc = PDKIM_OK;
420     /* Invalidate header name instance in tick-off list */
421     tick[p-lcopy] = '_';
422     goto BAIL;
423     }
424
425   p = q+1;
426   q = strchr(p, ':');
427   }
428
429 if (strcasecmp(p, hname) == 0)
430   {
431   rc = PDKIM_OK;
432   /* Invalidate header name instance in tick-off list */
433   tick[p-lcopy] = '_';
434   }
435
436 BAIL:
437 free(hname);
438 free(lcopy);
439 return rc;
440 }
441
442
443 /* -------------------------------------------------------------------------- */
444 /* Performs "relaxed" canonicalization of a header. The returned pointer needs
445    to be free()d. */
446
447 static char *
448 pdkim_relax_header (char *header, int crlf)
449 {
450 BOOL past_field_name = FALSE;
451 BOOL seen_wsp = FALSE;
452 char *p;
453 char *q;
454 char *relaxed = malloc(strlen(header)+3);
455
456 if (!relaxed) return NULL;
457
458 q = relaxed;
459 for (p = header; *p != '\0'; p++)
460   {
461   int c = *p;
462   /* Ignore CR & LF */
463   if (c == '\r' || c == '\n')
464     continue;
465   if (c == '\t' || c == ' ')
466     {
467     if (seen_wsp)
468       continue;
469     c = ' ';                    /* Turns WSP into SP */
470     seen_wsp = TRUE;
471     }
472   else
473     if (!past_field_name && c == ':')
474       {
475       if (seen_wsp) q--;        /* This removes WSP before the colon */
476       seen_wsp = TRUE;          /* This removes WSP after the colon */
477       past_field_name = TRUE;
478       }
479     else
480       seen_wsp = FALSE;
481
482   /* Lowercase header name */
483   if (!past_field_name) c = tolower(c);
484   *q++ = c;
485   }
486
487 if (q > relaxed && q[-1] == ' ') q--; /* Squash eventual trailing SP */
488 *q = '\0';
489
490 if (crlf) strcat(relaxed, "\r\n");
491 return relaxed;
492 }
493
494
495 /* -------------------------------------------------------------------------- */
496 #define PDKIM_QP_ERROR_DECODE -1
497
498 static char *
499 pdkim_decode_qp_char(char *qp_p, int *c)
500 {
501 char *initial_pos = qp_p;
502
503 /* Advance one char */
504 qp_p++;
505
506 /* Check for two hex digits and decode them */
507 if (isxdigit(*qp_p) && isxdigit(qp_p[1]))
508   {
509   /* Do hex conversion */
510   *c = (isdigit(*qp_p) ? *qp_p - '0' : toupper(*qp_p) - 'A' + 10) << 4;
511   *c |= isdigit(qp_p[1]) ? qp_p[1] - '0' : toupper(qp_p[1]) - 'A' + 10;
512   return qp_p + 2;
513   }
514
515 /* Illegal char here */
516 *c = PDKIM_QP_ERROR_DECODE;
517 return initial_pos;
518 }
519
520
521 /* -------------------------------------------------------------------------- */
522
523 static char *
524 pdkim_decode_qp(char *str)
525 {
526 int nchar = 0;
527 char *q;
528 char *p = str;
529 char *n = malloc(strlen(p)+1);
530
531 if (!n) return NULL;
532
533 *n = '\0';
534 q = n;
535 while (*p != '\0')
536   {
537   if (*p == '=')
538     {
539     p = pdkim_decode_qp_char(p, &nchar);
540     if (nchar >= 0)
541       {
542       *q++ = nchar;
543       continue;
544       }
545     }
546   else
547     *q++ = *p;
548   p++;
549   }
550 *q = '\0';
551 return n;
552 }
553
554
555 /* -------------------------------------------------------------------------- */
556
557 static void
558 pdkim_decode_base64(uschar *str, blob * b)
559 {
560 int dlen;
561 char *res;
562 dlen = b64decode(str, &b->data);
563 if (dlen < 0) b->data = NULL;
564 b->len = dlen;
565 }
566
567 /* -------------------------------------------------------------------------- */
568
569 static char *
570 pdkim_encode_base64(blob * b)
571 {
572 char * ret;
573 int old_pool = store_pool;
574
575 store_pool = POOL_PERM;
576 ret = CS b64encode(b->data, b->len);
577 store_pool = old_pool;
578 return ret;
579 }
580
581
582 /* -------------------------------------------------------------------------- */
583 #define PDKIM_HDR_LIMBO 0
584 #define PDKIM_HDR_TAG   1
585 #define PDKIM_HDR_VALUE 2
586
587 static pdkim_signature *
588 pdkim_parse_sig_header(pdkim_ctx *ctx, char *raw_hdr)
589 {
590 pdkim_signature *sig ;
591 char *p, *q;
592 pdkim_str *cur_tag = NULL;
593 pdkim_str *cur_val = NULL;
594 BOOL past_hname = FALSE;
595 BOOL in_b_val = FALSE;
596 int where = PDKIM_HDR_LIMBO;
597 int i;
598 int old_pool = store_pool;
599
600 /* There is a store-reset between header & body reception
601 so cannot use the main pool. Any allocs done by Exim
602 memory-handling must use the perm pool. */
603
604 store_pool = POOL_PERM;
605
606 if (!(sig = malloc(sizeof(pdkim_signature)))) return NULL;
607 memset(sig, 0, sizeof(pdkim_signature));
608 sig->bodylength = -1;
609
610 if (!(sig->rawsig_no_b_val = malloc(strlen(raw_hdr)+1)))
611   {
612   free(sig);
613   return NULL;
614   }
615
616 q = sig->rawsig_no_b_val;
617
618 for (p = raw_hdr; ; p++)
619   {
620   char c = *p;
621
622   /* Ignore FWS */
623   if (c == '\r' || c == '\n')
624     goto NEXT_CHAR;
625
626   /* Fast-forward through header name */
627   if (!past_hname)
628     {
629     if (c == ':') past_hname = TRUE;
630     goto NEXT_CHAR;
631     }
632
633   if (where == PDKIM_HDR_LIMBO)
634     {
635     /* In limbo, just wait for a tag-char to appear */
636     if (!(c >= 'a' && c <= 'z'))
637       goto NEXT_CHAR;
638
639     where = PDKIM_HDR_TAG;
640     }
641
642   if (where == PDKIM_HDR_TAG)
643     {
644     if (!cur_tag)
645       cur_tag = pdkim_strnew(NULL);
646
647     if (c >= 'a' && c <= 'z')
648       pdkim_strncat(cur_tag, p, 1);
649
650     if (c == '=')
651       {
652       if (strcmp(cur_tag->str, "b") == 0)
653         {
654         *q = '='; q++;
655         in_b_val = TRUE;
656         }
657       where = PDKIM_HDR_VALUE;
658       goto NEXT_CHAR;
659       }
660     }
661
662   if (where == PDKIM_HDR_VALUE)
663     {
664     if (!cur_val)
665       cur_val = pdkim_strnew(NULL);
666
667     if (c == '\r' || c == '\n' || c == ' ' || c == '\t')
668       goto NEXT_CHAR;
669
670     if (c == ';' || c == '\0')
671       {
672       if (cur_tag->len > 0)
673         {
674         pdkim_strtrim(cur_val);
675
676         DEBUG(D_acl) debug_printf(" %s=%s\n", cur_tag->str, cur_val->str);
677
678         switch (cur_tag->str[0])
679           {
680           case 'b':
681             if (cur_tag->str[1] == 'h')
682               pdkim_decode_base64(US cur_val->str, &sig->bodyhash);
683             else
684               pdkim_decode_base64(US cur_val->str, &sig->sigdata);
685             break;
686           case 'v':
687               /* We only support version 1, and that is currently the
688                  only version there is. */
689             if (strcmp(cur_val->str, PDKIM_SIGNATURE_VERSION) == 0)
690               sig->version = 1;
691             break;
692           case 'a':
693             for (i = 0; pdkim_algos[i]; i++)
694               if (strcmp(cur_val->str, pdkim_algos[i]) == 0)
695                 {
696                 sig->algo = i;
697                 break;
698                 }
699             break;
700           case 'c':
701             for (i = 0; pdkim_combined_canons[i].str; i++)
702               if (strcmp(cur_val->str, pdkim_combined_canons[i].str) == 0)
703                 {
704                 sig->canon_headers = pdkim_combined_canons[i].canon_headers;
705                 sig->canon_body    = pdkim_combined_canons[i].canon_body;
706                 break;
707                 }
708             break;
709           case 'q':
710             for (i = 0; pdkim_querymethods[i]; i++)
711               if (strcmp(cur_val->str, pdkim_querymethods[i]) == 0)
712                 {
713                 sig->querymethod = i;
714                 break;
715                 }
716             break;
717           case 's':
718             sig->selector = strdup(cur_val->str); break;
719           case 'd':
720             sig->domain = strdup(cur_val->str); break;
721           case 'i':
722             sig->identity = pdkim_decode_qp(cur_val->str); break;
723           case 't':
724             sig->created = strtoul(cur_val->str, NULL, 10); break;
725           case 'x':
726             sig->expires = strtoul(cur_val->str, NULL, 10); break;
727           case 'l':
728             sig->bodylength = strtol(cur_val->str, NULL, 10); break;
729           case 'h':
730             sig->headernames = string_copy(cur_val->str); break;
731           case 'z':
732             sig->copiedheaders = pdkim_decode_qp(cur_val->str); break;
733           default:
734             DEBUG(D_acl) debug_printf(" Unknown tag encountered\n");
735             break;
736           }
737         }
738       pdkim_strclear(cur_tag);
739       pdkim_strclear(cur_val);
740       in_b_val = FALSE;
741       where = PDKIM_HDR_LIMBO;
742       }
743     else
744       pdkim_strncat(cur_val, p, 1);
745     }
746
747 NEXT_CHAR:
748   if (c == '\0')
749     break;
750
751   if (!in_b_val)
752     *q++ = c;
753   }
754
755 store_pool = old_pool;
756
757 /* Make sure the most important bits are there. */
758 if (!(sig->domain      && (*(sig->domain)      != '\0') &&
759       sig->selector    && (*(sig->selector)    != '\0') &&
760       sig->headernames && (*(sig->headernames) != '\0') &&
761       sig->version))
762   {
763   pdkim_free_sig(sig);
764   return NULL;
765   }
766
767 *q = '\0';
768 /* Chomp raw header. The final newline must not be added to the signature. */
769 q--;
770 while (q > sig->rawsig_no_b_val  && (*q == '\r' || *q == '\n'))
771   *q = '\0'; q--;       /*XXX questionable code layout; possible bug */
772
773 DEBUG(D_acl)
774   {
775   debug_printf(
776           "PDKIM >> Raw signature w/o b= tag value >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
777   pdkim_quoteprint(sig->rawsig_no_b_val, strlen(sig->rawsig_no_b_val));
778   debug_printf(
779           "PDKIM >> Sig size: %4d bits\n", sig->sigdata.len*8);
780   debug_printf(
781           "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
782   }
783
784 exim_sha_init(&sig->body_hash, sig->algo == PDKIM_ALGO_RSA_SHA1);
785 return sig;
786 }
787
788
789 /* -------------------------------------------------------------------------- */
790
791 static pdkim_pubkey *
792 pdkim_parse_pubkey_record(pdkim_ctx *ctx, char *raw_record)
793 {
794 pdkim_pubkey *pub;
795 char *p;
796 pdkim_str *cur_tag = NULL;
797 pdkim_str *cur_val = NULL;
798 int where = PDKIM_HDR_LIMBO;
799
800 if (!(pub = malloc(sizeof(pdkim_pubkey)))) return NULL;
801 memset(pub, 0, sizeof(pdkim_pubkey));
802
803 for (p = raw_record; ; p++)
804   {
805   char c = *p;
806
807   /* Ignore FWS */
808   if (c == '\r' || c == '\n')
809     goto NEXT_CHAR;
810
811   if (where == PDKIM_HDR_LIMBO)
812     {
813     /* In limbo, just wait for a tag-char to appear */
814     if (!(c >= 'a' && c <= 'z'))
815       goto NEXT_CHAR;
816
817     where = PDKIM_HDR_TAG;
818     }
819
820   if (where == PDKIM_HDR_TAG)
821     {
822     if (!cur_tag)
823       cur_tag = pdkim_strnew(NULL);
824
825     if (c >= 'a' && c <= 'z')
826       pdkim_strncat(cur_tag, p, 1);
827
828     if (c == '=')
829       {
830       where = PDKIM_HDR_VALUE;
831       goto NEXT_CHAR;
832       }
833     }
834
835   if (where == PDKIM_HDR_VALUE)
836     {
837     if (!cur_val)
838       cur_val = pdkim_strnew(NULL);
839
840     if (c == '\r' || c == '\n')
841       goto NEXT_CHAR;
842
843     if (c == ';' || c == '\0')
844       {
845       if (cur_tag->len > 0)
846         {
847         pdkim_strtrim(cur_val);
848         DEBUG(D_acl) debug_printf(" %s=%s\n", cur_tag->str, cur_val->str);
849
850         switch (cur_tag->str[0])
851           {
852           case 'v':
853             /* This tag isn't evaluated because:
854                - We only support version DKIM1.
855                - Which is the default for this value (set below)
856                - Other versions are currently not specified.      */
857             break;
858           case 'h':
859             pub->hashes = strdup(cur_val->str); break;
860           case 'g':
861             pub->granularity = strdup(cur_val->str); break;
862           case 'n':
863             pub->notes = pdkim_decode_qp(cur_val->str); break;
864           case 'p':
865             pdkim_decode_base64(US cur_val->str, &pub->key);
866             break;
867           case 'k':
868             pub->hashes = strdup(cur_val->str); break;
869           case 's':
870             pub->srvtype = strdup(cur_val->str); break;
871           case 't':
872             if (strchr(cur_val->str, 'y') != NULL) pub->testing = 1;
873             if (strchr(cur_val->str, 's') != NULL) pub->no_subdomaining = 1;
874             break;
875           default:
876             DEBUG(D_acl) debug_printf(" Unknown tag encountered\n");
877             break;
878           }
879         }
880       pdkim_strclear(cur_tag);
881       pdkim_strclear(cur_val);
882       where = PDKIM_HDR_LIMBO;
883       }
884     else
885       pdkim_strncat(cur_val, p, 1);
886     }
887
888 NEXT_CHAR:
889   if (c == '\0') break;
890   }
891
892 /* Set fallback defaults */
893 if (!pub->version    ) pub->version     = strdup(PDKIM_PUB_RECORD_VERSION);
894 if (!pub->granularity) pub->granularity = strdup("*");
895 if (!pub->keytype    ) pub->keytype     = strdup("rsa");
896 if (!pub->srvtype    ) pub->srvtype     = strdup("*");
897
898 /* p= is required */
899 if (pub->key.data)
900   return pub;
901
902 pdkim_free_pubkey(pub);
903 return NULL;
904 }
905
906
907 /* -------------------------------------------------------------------------- */
908
909 static int
910 pdkim_update_bodyhash(pdkim_ctx *ctx, const char *data, int len)
911 {
912 pdkim_signature *sig = ctx->sig;
913 /* Cache relaxed version of data */
914 char *relaxed_data = NULL;
915 int   relaxed_len  = 0;
916
917 /* Traverse all signatures, updating their hashes. */
918 while (sig)
919   {
920   /* Defaults to simple canon (no further treatment necessary) */
921   const char *canon_data = data;
922   int         canon_len = len;
923
924   if (sig->canon_body == PDKIM_CANON_RELAXED)
925     {
926     /* Relax the line if not done already */
927     if (!relaxed_data)
928       {
929       BOOL seen_wsp = FALSE;
930       const char *p;
931       int q = 0;
932
933       if (!(relaxed_data = malloc(len+1)))
934         return PDKIM_ERR_OOM;
935
936       for (p = data; *p; p++)
937         {
938         char c = *p;
939         if (c == '\r')
940           {
941           if (q > 0 && relaxed_data[q-1] == ' ')
942             q--;
943           }
944         else if (c == '\t' || c == ' ')
945           {
946           c = ' '; /* Turns WSP into SP */
947           if (seen_wsp)
948             continue;
949           seen_wsp = TRUE;
950           }
951         else
952           seen_wsp = FALSE;
953         relaxed_data[q++] = c;
954         }
955       relaxed_data[q] = '\0';
956       relaxed_len = q;
957       }
958     canon_data = relaxed_data;
959     canon_len  = relaxed_len;
960     }
961
962   /* Make sure we don't exceed the to-be-signed body length */
963   if (  sig->bodylength >= 0
964      && sig->signed_body_bytes + (unsigned long)canon_len > sig->bodylength
965      )
966     canon_len = sig->bodylength - sig->signed_body_bytes;
967
968   if (canon_len > 0)
969     {
970     exim_sha_update(&sig->body_hash, canon_data, canon_len);
971     sig->signed_body_bytes += canon_len;
972     DEBUG(D_acl) pdkim_quoteprint(canon_data, canon_len);
973     }
974
975   sig = sig->next;
976   }
977
978 if (relaxed_data) free(relaxed_data);
979 return PDKIM_OK;
980 }
981
982
983 /* -------------------------------------------------------------------------- */
984
985 static int
986 pdkim_finish_bodyhash(pdkim_ctx *ctx)
987 {
988 pdkim_signature *sig;
989
990 /* Traverse all signatures */
991 for (sig = ctx->sig; sig; sig = sig->next)
992   {                                     /* Finish hashes */
993   blob bh;
994
995   exim_sha_finish(&sig->body_hash, &bh);
996
997   DEBUG(D_acl)
998     {
999     debug_printf("PDKIM [%s] Body bytes hashed: %lu\n"
1000                  "PDKIM [%s] bh  computed: ",
1001                 sig->domain, sig->signed_body_bytes, sig->domain);
1002     pdkim_hexprint(CS bh.data, bh.len);
1003     }
1004
1005   /* SIGNING -------------------------------------------------------------- */
1006   if (ctx->mode == PDKIM_MODE_SIGN)
1007     {
1008     sig->bodyhash = bh;
1009
1010     /* If bodylength limit is set, and we have received less bytes
1011        than the requested amount, effectively remove the limit tag. */
1012     if (sig->signed_body_bytes < sig->bodylength)
1013       sig->bodylength = -1;
1014     }
1015
1016   /* VERIFICATION --------------------------------------------------------- */
1017   else
1018     {
1019     /* Compare bodyhash */
1020     if (memcmp(bh.data, sig->bodyhash.data, bh.len) == 0)
1021       {
1022       DEBUG(D_acl) debug_printf("PDKIM [%s] Body hash verified OK\n", sig->domain);
1023       }
1024     else
1025       {
1026       DEBUG(D_acl)
1027         {
1028         debug_printf("PDKIM [%s] bh signature: ", sig->domain);
1029         pdkim_hexprint(sig->bodyhash.data,
1030                          exim_sha_hashlen(&sig->body_hash));
1031         debug_printf("PDKIM [%s] Body hash did NOT verify\n", sig->domain);
1032         }
1033       sig->verify_status     = PDKIM_VERIFY_FAIL;
1034       sig->verify_ext_status = PDKIM_VERIFY_FAIL_BODY;
1035       }
1036     }
1037   }
1038
1039 return PDKIM_OK;
1040 }
1041
1042
1043
1044 /* -------------------------------------------------------------------------- */
1045 /* Callback from pdkim_feed below for processing complete body lines */
1046
1047 static int
1048 pdkim_bodyline_complete(pdkim_ctx *ctx)
1049 {
1050 char *p = ctx->linebuf;
1051 int   n = ctx->linebuf_offset;
1052 pdkim_signature *sig = ctx->sig;        /*XXX assumes only one sig */
1053
1054 /* Ignore extra data if we've seen the end-of-data marker */
1055 if (ctx->seen_eod) goto BAIL;
1056
1057 /* We've always got one extra byte to stuff a zero ... */
1058 ctx->linebuf[ctx->linebuf_offset] = '\0';
1059
1060 /* Terminate on EOD marker */
1061 if (memcmp(p, ".\r\n", 3) == 0)
1062   {
1063   /* In simple body mode, if any empty lines were buffered,
1064   replace with one. rfc 4871 3.4.3 */
1065   /*XXX checking the signed-body-bytes is a gross hack; I think
1066   it indicates that all linebreaks should be buffered, including
1067   the one terminating a text line */
1068   if (  sig && sig->canon_body == PDKIM_CANON_SIMPLE
1069      && sig->signed_body_bytes == 0
1070      && ctx->num_buffered_crlf > 0
1071      )
1072     pdkim_update_bodyhash(ctx, "\r\n", 2);
1073
1074   ctx->seen_eod = TRUE;
1075   goto BAIL;
1076   }
1077 /* Unstuff dots */
1078 if (memcmp(p, "..", 2) == 0)
1079   {
1080   p++;
1081   n--;
1082   }
1083
1084 /* Empty lines need to be buffered until we find a non-empty line */
1085 if (memcmp(p, "\r\n", 2) == 0)
1086   {
1087   ctx->num_buffered_crlf++;
1088   goto BAIL;
1089   }
1090
1091 if (sig && sig->canon_body == PDKIM_CANON_RELAXED)
1092   {
1093   /* Lines with just spaces need to be buffered too */
1094   char *check = p;
1095   while (memcmp(check, "\r\n", 2) != 0)
1096     {
1097     char c = *check;
1098
1099     if (c != '\t' && c != ' ')
1100       goto PROCESS;
1101     check++;
1102     }
1103
1104   ctx->num_buffered_crlf++;
1105   goto BAIL;
1106 }
1107
1108 PROCESS:
1109 /* At this point, we have a non-empty line, so release the buffered ones. */
1110 while (ctx->num_buffered_crlf)
1111   {
1112   pdkim_update_bodyhash(ctx, "\r\n", 2);
1113   ctx->num_buffered_crlf--;
1114   }
1115
1116 pdkim_update_bodyhash(ctx, p, n);
1117
1118 BAIL:
1119 ctx->linebuf_offset = 0;
1120 return PDKIM_OK;
1121 }
1122
1123
1124 /* -------------------------------------------------------------------------- */
1125 /* Callback from pdkim_feed below for processing complete headers */
1126 #define DKIM_SIGNATURE_HEADERNAME "DKIM-Signature:"
1127
1128 static int
1129 pdkim_header_complete(pdkim_ctx *ctx)
1130 {
1131 /* Special case: The last header can have an extra \r appended */
1132 if ( (ctx->cur_header->len > 1) &&
1133      (ctx->cur_header->str[(ctx->cur_header->len)-1] == '\r') )
1134   {
1135   ctx->cur_header->str[(ctx->cur_header->len)-1] = '\0';
1136   ctx->cur_header->len--;
1137   }
1138
1139 ctx->num_headers++;
1140 if (ctx->num_headers > PDKIM_MAX_HEADERS) goto BAIL;
1141
1142 /* SIGNING -------------------------------------------------------------- */
1143 if (ctx->mode == PDKIM_MODE_SIGN)
1144   {
1145   pdkim_signature *sig;
1146
1147   for (sig = ctx->sig; sig; sig = sig->next)                    /* Traverse all signatures */
1148     {
1149     pdkim_stringlist *list;
1150
1151     /* Add header to the signed headers list (in reverse order) */
1152     if (!(list = pdkim_prepend_stringlist(sig->headers,
1153                                   ctx->cur_header->str)))
1154       return PDKIM_ERR_OOM;
1155     sig->headers = list;
1156     }
1157   }
1158
1159 /* VERIFICATION ----------------------------------------------------------- */
1160 /* DKIM-Signature: headers are added to the verification list */
1161 if (ctx->mode == PDKIM_MODE_VERIFY)
1162   {
1163   if (strncasecmp(ctx->cur_header->str,
1164                   DKIM_SIGNATURE_HEADERNAME,
1165                   strlen(DKIM_SIGNATURE_HEADERNAME)) == 0)
1166     {
1167     pdkim_signature *new_sig;
1168
1169     /* Create and chain new signature block */
1170     DEBUG(D_acl) debug_printf(
1171         "PDKIM >> Found sig, trying to parse >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1172
1173     if ((new_sig = pdkim_parse_sig_header(ctx, ctx->cur_header->str)))
1174       {
1175       pdkim_signature *last_sig = ctx->sig;
1176       if (!last_sig)
1177         ctx->sig = new_sig;
1178       else
1179         {
1180         while (last_sig->next) last_sig = last_sig->next;
1181         last_sig->next = new_sig;
1182         }
1183       }
1184     else
1185       DEBUG(D_acl) debug_printf(
1186           "Error while parsing signature header\n"
1187           "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1188     }
1189
1190   /* every other header is stored for signature verification */
1191   else
1192     {
1193     pdkim_stringlist *list;
1194
1195     if (!(list = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->str)))
1196       return PDKIM_ERR_OOM;
1197     ctx->headers = list;
1198     }
1199   }
1200
1201 BAIL:
1202 pdkim_strclear(ctx->cur_header); /* Re-use existing pdkim_str */
1203 return PDKIM_OK;
1204 }
1205
1206
1207
1208 /* -------------------------------------------------------------------------- */
1209 #define HEADER_BUFFER_FRAG_SIZE 256
1210
1211 DLLEXPORT int
1212 pdkim_feed (pdkim_ctx *ctx, char *data, int len)
1213 {
1214 int p;
1215
1216 for (p = 0; p<len; p++)
1217   {
1218   char c = data[p];
1219
1220   if (ctx->past_headers)
1221     {
1222     /* Processing body byte */
1223     ctx->linebuf[ctx->linebuf_offset++] = c;
1224     if (c == '\n')
1225       {
1226       int rc = pdkim_bodyline_complete(ctx); /* End of line */
1227       if (rc != PDKIM_OK) return rc;
1228       }
1229     if (ctx->linebuf_offset == (PDKIM_MAX_BODY_LINE_LEN-1))
1230       return PDKIM_ERR_LONG_LINE;
1231     }
1232   else
1233     {
1234     /* Processing header byte */
1235     if (c != '\r')
1236       {
1237       if (c == '\n')
1238         {
1239         if (ctx->seen_lf)
1240           {
1241           int rc = pdkim_header_complete(ctx); /* Seen last header line */
1242           if (rc != PDKIM_OK) return rc;
1243
1244           ctx->past_headers = TRUE;
1245           ctx->seen_lf = 0;
1246           DEBUG(D_acl) debug_printf(
1247               "PDKIM >> Body data for hash, canonicalized >>>>>>>>>>>>>>>>>>>>>>\n");
1248           continue;
1249           }
1250         else
1251           ctx->seen_lf = TRUE;
1252         }
1253       else if (ctx->seen_lf)
1254         {
1255         if (!(c == '\t' || c == ' '))
1256           {
1257           int rc = pdkim_header_complete(ctx); /* End of header */
1258           if (rc != PDKIM_OK) return rc;
1259           }
1260         ctx->seen_lf = FALSE;
1261         }
1262       }
1263
1264     if (!ctx->cur_header)
1265       if (!(ctx->cur_header = pdkim_strnew(NULL)))
1266         return PDKIM_ERR_OOM;
1267
1268     if (ctx->cur_header->len < PDKIM_MAX_HEADER_LEN)
1269       if (!pdkim_strncat(ctx->cur_header, &data[p], 1))
1270         return PDKIM_ERR_OOM;
1271     }
1272   }
1273 return PDKIM_OK;
1274 }
1275
1276 /*
1277  * RFC 5322 specifies that header line length SHOULD be no more than 78
1278  * lets make it so!
1279  *  pdkim_headcat
1280  * returns char*
1281  *
1282  * col: this int holds and receives column number (octets since last '\n')
1283  * str: partial string to append to
1284  * pad: padding, split line or space after before or after eg: ";"
1285  * intro: - must join to payload eg "h=", usually the tag name
1286  * payload: eg base64 data - long data can be split arbitrarily.
1287  *
1288  * this code doesn't fold the header in some of the places that RFC4871
1289  * allows: As per RFC5322(2.2.3) it only folds before or after tag-value
1290  * pairs and inside long values. it also always spaces or breaks after the
1291  * "pad"
1292  *
1293  * no guarantees are made for output given out-of range input. like tag
1294  * names longer than 78, or bogus col. Input is assumed to be free of line breaks.
1295  */
1296
1297 static char *
1298 pdkim_headcat(int *col, pdkim_str *str, const char * pad,
1299   const char *intro, const char *payload)
1300 {
1301 size_t l;
1302
1303 if (pad)
1304   {
1305   l = strlen(pad);
1306   if (*col + l > 78)
1307     {
1308     pdkim_strcat(str, "\r\n\t");
1309     *col = 1;
1310     }
1311   pdkim_strncat(str, pad, l);
1312   *col += l;
1313   }
1314
1315 l = (pad?1:0) + (intro?strlen(intro):0);
1316
1317 if (*col + l > 78)
1318   { /*can't fit intro - start a new line to make room.*/
1319   pdkim_strcat(str, "\r\n\t");
1320   *col = 1;
1321   l = intro?strlen(intro):0;
1322   }
1323
1324 l += payload ? strlen(payload):0 ;
1325
1326 while (l>77)
1327   { /* this fragment will not fit on a single line */
1328   if (pad)
1329     {
1330     pdkim_strcat(str, " ");
1331     *col += 1;
1332     pad = NULL; /* only want this once */
1333     l--;
1334     }
1335
1336   if (intro)
1337     {
1338     size_t sl = strlen(intro);
1339
1340     pdkim_strncat(str, intro, sl);
1341     *col += sl;
1342     l -= sl;
1343     intro = NULL; /* only want this once */
1344     }
1345
1346   if (payload)
1347     {
1348     size_t sl = strlen(payload);
1349     size_t chomp = *col+sl < 77 ? sl : 78-*col;
1350
1351     pdkim_strncat(str, payload, chomp);
1352     *col += chomp;
1353     payload += chomp;
1354     l -= chomp-1;
1355     }
1356
1357   /* the while precondition tells us it didn't fit. */
1358   pdkim_strcat(str, "\r\n\t");
1359   *col = 1;
1360   }
1361
1362 if (*col + l > 78)
1363   {
1364   pdkim_strcat(str, "\r\n\t");
1365   *col = 1;
1366   pad = NULL;
1367   }
1368
1369 if (pad)
1370   {
1371   pdkim_strcat(str, " ");
1372   *col += 1;
1373   pad = NULL;
1374   }
1375
1376 if (intro)
1377   {
1378   size_t sl = strlen(intro);
1379
1380   pdkim_strncat(str, intro, sl);
1381   *col += sl;
1382   l -= sl;
1383   intro = NULL;
1384   }
1385
1386 if (payload)
1387   {
1388   size_t sl = strlen(payload);
1389
1390   pdkim_strncat(str, payload, sl);
1391   *col += sl;
1392   }
1393
1394 return str->str;
1395 }
1396
1397
1398 /* -------------------------------------------------------------------------- */
1399
1400 static char *
1401 pdkim_create_header(pdkim_signature *sig, BOOL final)
1402 {
1403 char *rc = NULL;
1404 char *base64_bh = NULL;
1405 char *base64_b  = NULL;
1406 int col = 0;
1407 pdkim_str *hdr;
1408 pdkim_str *canon_all;
1409
1410 if (!(hdr = pdkim_strnew("DKIM-Signature: v="PDKIM_SIGNATURE_VERSION)))
1411   return NULL;
1412
1413 if (!(canon_all = pdkim_strnew(pdkim_canons[sig->canon_headers])))
1414   goto BAIL;
1415
1416 if (!(base64_bh = pdkim_encode_base64(&sig->bodyhash)))
1417   goto BAIL;
1418
1419 col = strlen(hdr->str);
1420
1421 /* Required and static bits */
1422 if (  pdkim_headcat(&col, hdr, ";", "a=", pdkim_algos[sig->algo])
1423    && pdkim_headcat(&col, hdr, ";", "q=", pdkim_querymethods[sig->querymethod])
1424    && pdkim_strcat(canon_all, "/")
1425    && pdkim_strcat(canon_all, pdkim_canons[sig->canon_body])
1426    && pdkim_headcat(&col, hdr, ";", "c=", canon_all->str)
1427    && pdkim_headcat(&col, hdr, ";", "d=", sig->domain)
1428    && pdkim_headcat(&col, hdr, ";", "s=", sig->selector)
1429    )
1430   {
1431   /* list of header names can be split between items. */
1432     {
1433     char *n = CS string_copy(sig->headernames);
1434     char *f = n;
1435     char *i = "h=";
1436     char *s = ";";
1437
1438     if (!n) goto BAIL;
1439     while (*n)
1440       {
1441       char *c = strchr(n, ':');
1442
1443       if (c) *c ='\0';
1444
1445       if (!i)
1446         if (!pdkim_headcat(&col, hdr, NULL, NULL, ":"))
1447           {
1448           goto BAIL;
1449           }
1450
1451       if (!pdkim_headcat(&col, hdr, s, i, n))
1452         {
1453         goto BAIL;
1454         }
1455
1456       if (!c)
1457         break;
1458
1459       n = c+1;
1460       s = NULL;
1461       i = NULL;
1462       }
1463     }
1464
1465   if(!pdkim_headcat(&col, hdr, ";", "bh=", base64_bh))
1466     goto BAIL;
1467
1468   /* Optional bits */
1469   if (sig->identity)
1470     if(!pdkim_headcat(&col, hdr, ";", "i=", sig->identity))
1471       goto BAIL;
1472
1473   if (sig->created > 0)
1474     {
1475     char minibuf[20];
1476
1477     snprintf(minibuf, 20, "%lu", sig->created);
1478     if(!pdkim_headcat(&col, hdr, ";", "t=", minibuf))
1479       goto BAIL;
1480   }
1481
1482   if (sig->expires > 0)
1483     {
1484     char minibuf[20];
1485
1486     snprintf(minibuf, 20, "%lu", sig->expires);
1487     if(!pdkim_headcat(&col, hdr, ";", "x=", minibuf))
1488       goto BAIL;
1489     }
1490
1491   if (sig->bodylength >= 0)
1492     {
1493     char minibuf[20];
1494
1495     snprintf(minibuf, 20, "%lu", sig->bodylength);
1496     if(!pdkim_headcat(&col, hdr, ";", "l=", minibuf))
1497       goto BAIL;
1498     }
1499
1500   /* Preliminary or final version? */
1501   if (final)
1502     {
1503     if (!(base64_b = pdkim_encode_base64(&sig->sigdata)))
1504       goto BAIL;
1505     if (!pdkim_headcat(&col, hdr, ";", "b=", base64_b))
1506       goto BAIL;
1507   }
1508   else 
1509     if(!pdkim_headcat(&col, hdr, ";", "b=", ""))
1510       goto BAIL;
1511
1512   /* add trailing semicolon: I'm not sure if this is actually needed */
1513   if (!pdkim_headcat(&col, hdr, NULL, ";", ""))
1514     goto BAIL;
1515   }
1516
1517 rc = strdup(hdr->str);
1518
1519 BAIL:
1520 pdkim_strfree(hdr);
1521 if (canon_all) pdkim_strfree(canon_all);
1522 return rc;
1523 }
1524
1525
1526 /* -------------------------------------------------------------------------- */
1527
1528 DLLEXPORT int
1529 pdkim_feed_finish(pdkim_ctx *ctx, pdkim_signature **return_signatures)
1530 {
1531 pdkim_signature *sig = ctx->sig;
1532 pdkim_str *headernames = NULL;             /* Collected signed header names */
1533
1534 /* Check if we must still flush a (partial) header. If that is the
1535    case, the message has no body, and we must compute a body hash
1536    out of '<CR><LF>' */
1537 if (ctx->cur_header && ctx->cur_header->len)
1538   {
1539   int rc = pdkim_header_complete(ctx);
1540   if (rc != PDKIM_OK) return rc;
1541   pdkim_update_bodyhash(ctx, "\r\n", 2);
1542   }
1543 else
1544   DEBUG(D_acl) debug_printf(
1545       "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1546
1547 /* Build (and/or evaluate) body hash */
1548 if (pdkim_finish_bodyhash(ctx) != PDKIM_OK)
1549   return PDKIM_ERR_OOM;
1550
1551 /* SIGNING -------------------------------------------------------------- */
1552 if (ctx->mode == PDKIM_MODE_SIGN)
1553   if (!(headernames = pdkim_strnew(NULL)))
1554     return PDKIM_ERR_OOM;
1555 /* ---------------------------------------------------------------------- */
1556
1557 while (sig)
1558   {
1559   BOOL is_sha1 = sig->algo == PDKIM_ALGO_RSA_SHA1;
1560   hctx hhash_ctx;
1561   char * sig_hdr;
1562   blob hhash;
1563   blob hdata;
1564   int hdata_alloc = 0;
1565
1566   hdata.data = NULL;
1567   hdata.len = 0;
1568
1569   exim_sha_init(&hhash_ctx, is_sha1);
1570
1571   DEBUG(D_acl) debug_printf(
1572       "PDKIM >> Hashed header data, canonicalized, in sequence >>>>>>>>>>>>>>\n");
1573
1574   /* SIGNING ---------------------------------------------------------------- */
1575   /* When signing, walk through our header list and add them to the hash. As we
1576      go, construct a list of the header's names to use for the h= parameter.
1577      Then append to that list any remaining header names for which there was no
1578      header to sign. */
1579
1580   if (ctx->mode == PDKIM_MODE_SIGN)
1581     {
1582     pdkim_stringlist *p;
1583     const uschar * l;
1584     uschar * s;
1585     int sep = 0;
1586
1587     for (p = sig->headers; p; p = p->next)
1588       if (header_name_match(p->value, sig->sign_headers) == PDKIM_OK)
1589         {
1590         uschar * rh;
1591         /* Collect header names (Note: colon presence is guaranteed here) */
1592         uschar * q = Ustrchr(p->value, ':');
1593
1594         if (!(pdkim_strncat(headernames, p->value,
1595                           (q - US p->value) + (p->next ? 1 : 0))))
1596           return PDKIM_ERR_OOM;
1597
1598         rh = sig->canon_headers == PDKIM_CANON_RELAXED
1599           ? US pdkim_relax_header(p->value, 1) /* cook header for relaxed canon */
1600           : string_copy(p->value);             /* just copy it for simple canon */
1601         if (!rh)
1602           return PDKIM_ERR_OOM;
1603
1604         /* Feed header to the hash algorithm */
1605         exim_sha_update(&hhash_ctx, rh, strlen(rh));
1606
1607         /* Remember headers block for signing (when the library cannot do incremental)  */
1608         (void) exim_rsa_data_append(&hdata, &hdata_alloc, rh);
1609
1610         DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1611         }
1612
1613     l = US sig->sign_headers;
1614     while((s = string_nextinlist(&l, &sep, NULL, 0)))
1615       if (*s != '_')
1616         {                       /*SSS string_append_listele() */
1617         if (headernames->len > 0 && headernames->str[headernames->len-1] != ':')
1618           if (!(pdkim_strncat(headernames, ":", 1)))
1619             return PDKIM_ERR_OOM;
1620         if (!(pdkim_strncat(headernames, CS s, Ustrlen(s))))
1621           return PDKIM_ERR_OOM;
1622         }
1623     }
1624
1625   /* VERIFICATION ----------------------------------------------------------- */
1626   /* When verifying, walk through the header name list in the h= parameter and
1627      add the headers to the hash in that order. */
1628   else
1629     {
1630     uschar * b = string_copy(sig->headernames);
1631     uschar * p = b;
1632     uschar * q;
1633     pdkim_stringlist * hdrs;
1634
1635     if (!b) return PDKIM_ERR_OOM;
1636
1637     /* clear tags */
1638     for (hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1639       hdrs->tag = 0;
1640
1641     while(1)
1642       {
1643       if ((q = Ustrchr(p, ':')))
1644         *q = '\0';
1645
1646 /*XXX walk the list of headers in same order as received. */
1647       for (hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1648         if (  hdrs->tag == 0
1649            && strncasecmp(hdrs->value, CS p, Ustrlen(p)) == 0
1650            && (hdrs->value)[Ustrlen(p)] == ':'
1651            )
1652           {
1653           uschar * rh = sig->canon_headers == PDKIM_CANON_RELAXED
1654             ? US pdkim_relax_header(hdrs->value, 1) /* cook header for relaxed canon */
1655             : string_copy(hdrs->value);             /* just copy it for simple canon */
1656           if (!rh)
1657             return PDKIM_ERR_OOM;
1658
1659           /* Feed header to the hash algorithm */
1660           exim_sha_update(&hhash_ctx, rh, strlen(rh));
1661
1662           DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1663           hdrs->tag = 1;
1664           break;
1665           }
1666
1667       if (!q) break;
1668       p = q+1;
1669       }
1670     }
1671
1672   DEBUG(D_acl) debug_printf(
1673             "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1674
1675   /* SIGNING ---------------------------------------------------------------- */
1676   if (ctx->mode == PDKIM_MODE_SIGN)
1677     {
1678     /* Copy headernames to signature struct */
1679     sig->headernames = string_copy(US headernames->str);
1680     pdkim_strfree(headernames);
1681
1682     /* Create signature header with b= omitted */
1683     sig_hdr = pdkim_create_header(sig, FALSE);
1684     }
1685
1686   /* VERIFICATION ----------------------------------------------------------- */
1687   else
1688     sig_hdr = strdup(sig->rawsig_no_b_val);
1689   /* ------------------------------------------------------------------------ */
1690
1691   if (!sig_hdr)
1692     return PDKIM_ERR_OOM;
1693
1694   /* Relax header if necessary */
1695   if (sig->canon_headers == PDKIM_CANON_RELAXED)
1696     {
1697     char *relaxed_hdr = pdkim_relax_header(sig_hdr, 0);
1698
1699     free(sig_hdr);
1700     if (!relaxed_hdr)
1701       return PDKIM_ERR_OOM;
1702     sig_hdr = relaxed_hdr;
1703     }
1704
1705   DEBUG(D_acl)
1706     {
1707     debug_printf(
1708             "PDKIM >> Signed DKIM-Signature header, canonicalized >>>>>>>>>>>>>>>>>\n");
1709     pdkim_quoteprint(sig_hdr, strlen(sig_hdr));
1710     debug_printf(
1711             "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1712     }
1713
1714   /* Finalize header hash */
1715   exim_sha_update(&hhash_ctx, sig_hdr, strlen(sig_hdr));
1716   exim_sha_finish(&hhash_ctx, &hhash);
1717
1718   DEBUG(D_acl)
1719     {
1720     debug_printf("PDKIM [%s] hh computed: ", sig->domain);
1721     pdkim_hexprint(hhash.data, hhash.len);
1722     }
1723
1724   /* Remember headers block for signing (when the library cannot do incremental)  */
1725   if (ctx->mode == PDKIM_MODE_SIGN)
1726     (void) exim_rsa_data_append(&hdata, &hdata_alloc, sig_hdr);
1727
1728   free(sig_hdr);
1729
1730   /* SIGNING ---------------------------------------------------------------- */
1731   if (ctx->mode == PDKIM_MODE_SIGN)
1732     {
1733     es_ctx sctx;
1734     const uschar * errstr;
1735
1736     /* Import private key */
1737     if ((errstr = exim_rsa_signing_init(sig->rsa_privkey, &sctx)))
1738       {
1739       DEBUG(D_acl) debug_printf("signing_init: %s\n", errstr);
1740       return PDKIM_ERR_RSA_PRIVKEY;
1741       }
1742
1743     /* Do signing.  With OpenSSL we are signing the hash of headers just
1744     calculated, with GnuTLS we have to sign an entire block of headers
1745     (due to available interfaces) and it recalculates the hash internally. */
1746
1747 #if defined(RSA_OPENSSL) || defined(RSA_GCRYPT)
1748     hdata = hhash;
1749 #endif
1750
1751     if ((errstr = exim_rsa_sign(&sctx, is_sha1, &hdata, &sig->sigdata)))
1752       {
1753       DEBUG(D_acl) debug_printf("signing: %s\n", errstr);
1754       return PDKIM_ERR_RSA_SIGNING;
1755       }
1756
1757     DEBUG(D_acl)
1758       {
1759       debug_printf( "PDKIM [%s] b computed: ", sig->domain);
1760       pdkim_hexprint(sig->sigdata.data, sig->sigdata.len);
1761       }
1762
1763     if (!(sig->signature_header = pdkim_create_header(sig, TRUE)))
1764       return PDKIM_ERR_OOM;
1765     }
1766
1767   /* VERIFICATION ----------------------------------------------------------- */
1768   else
1769     {
1770     ev_ctx vctx;
1771     const uschar * errstr;
1772
1773     char *dns_txt_name, *dns_txt_reply;
1774
1775     /* Fetch public key for signing domain, from DNS */
1776
1777     if (!(dns_txt_name  = malloc(PDKIM_DNS_TXT_MAX_NAMELEN)))
1778       return PDKIM_ERR_OOM;
1779
1780     if (!(dns_txt_reply = malloc(PDKIM_DNS_TXT_MAX_RECLEN)))
1781       {
1782       free(dns_txt_name);
1783       return PDKIM_ERR_OOM;
1784       }
1785
1786     memset(dns_txt_reply, 0, PDKIM_DNS_TXT_MAX_RECLEN);
1787     memset(dns_txt_name , 0, PDKIM_DNS_TXT_MAX_NAMELEN);
1788
1789     if (snprintf(dns_txt_name, PDKIM_DNS_TXT_MAX_NAMELEN,
1790                  "%s._domainkey.%s.",
1791                  sig->selector, sig->domain) >= PDKIM_DNS_TXT_MAX_NAMELEN)
1792       {
1793       sig->verify_status =      PDKIM_VERIFY_INVALID;
1794       sig->verify_ext_status =  PDKIM_VERIFY_INVALID_BUFFER_SIZE;
1795       goto NEXT_VERIFY;
1796       }
1797
1798     if (  ctx->dns_txt_callback(dns_txt_name, dns_txt_reply) != PDKIM_OK 
1799        || dns_txt_reply[0] == '\0')
1800       {
1801       sig->verify_status =      PDKIM_VERIFY_INVALID;
1802       sig->verify_ext_status =  PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE;
1803       goto NEXT_VERIFY;
1804       }
1805
1806     DEBUG(D_acl)
1807       {
1808       debug_printf(
1809           "PDKIM >> Parsing public key record >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"
1810           " Raw record: ");
1811       pdkim_quoteprint(dns_txt_reply, strlen(dns_txt_reply));
1812       }
1813
1814     if (!(sig->pubkey = pdkim_parse_pubkey_record(ctx, dns_txt_reply)))
1815       {
1816       sig->verify_status =      PDKIM_VERIFY_INVALID;
1817       sig->verify_ext_status =  PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD;
1818
1819       DEBUG(D_acl) debug_printf(
1820           " Error while parsing public key record\n"
1821           "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1822       goto NEXT_VERIFY;
1823       }
1824
1825     DEBUG(D_acl) debug_printf(
1826           "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1827
1828     /* Import public key */
1829     if ((errstr = exim_rsa_verify_init(&sig->pubkey->key, &vctx)))
1830       {
1831       DEBUG(D_acl) debug_printf("verify_init: %s\n", errstr);
1832       sig->verify_status =      PDKIM_VERIFY_INVALID;
1833       sig->verify_ext_status =  PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
1834       goto NEXT_VERIFY;
1835       }
1836
1837     /* Check the signature */
1838     if ((errstr = exim_rsa_verify(&vctx, is_sha1, &hhash, &sig->sigdata)))
1839       {
1840       DEBUG(D_acl) debug_printf("headers verify: %s\n", errstr);
1841       sig->verify_status =      PDKIM_VERIFY_FAIL;
1842       sig->verify_ext_status =  PDKIM_VERIFY_FAIL_MESSAGE;
1843       goto NEXT_VERIFY;
1844       }
1845
1846
1847     /* We have a winner! (if bodydhash was correct earlier) */
1848     if (sig->verify_status == PDKIM_VERIFY_NONE)
1849       sig->verify_status = PDKIM_VERIFY_PASS;
1850
1851 NEXT_VERIFY:
1852
1853     DEBUG(D_acl)
1854       {
1855       debug_printf("PDKIM [%s] signature status: %s",
1856               sig->domain, pdkim_verify_status_str(sig->verify_status));
1857       if (sig->verify_ext_status > 0)
1858         debug_printf(" (%s)\n",
1859                 pdkim_verify_ext_status_str(sig->verify_ext_status));
1860       else
1861         debug_printf("\n");
1862       }
1863
1864     free(dns_txt_name);
1865     free(dns_txt_reply);
1866     }
1867
1868   sig = sig->next;
1869   }
1870
1871 /* If requested, set return pointer to signature(s) */
1872 if (return_signatures)
1873   *return_signatures = ctx->sig;
1874
1875 return PDKIM_OK;
1876 }
1877
1878
1879 /* -------------------------------------------------------------------------- */
1880
1881 DLLEXPORT pdkim_ctx *
1882 pdkim_init_verify(int(*dns_txt_callback)(char *, char *))
1883 {
1884 pdkim_ctx *ctx = malloc(sizeof(pdkim_ctx));
1885
1886 if (!ctx)
1887   return NULL;
1888 memset(ctx, 0, sizeof(pdkim_ctx));
1889
1890 if (!(ctx->linebuf = malloc(PDKIM_MAX_BODY_LINE_LEN)))
1891   {
1892   free(ctx);
1893   return NULL;
1894   }
1895
1896 ctx->mode = PDKIM_MODE_VERIFY;
1897 ctx->dns_txt_callback = dns_txt_callback;
1898
1899 return ctx;
1900 }
1901
1902
1903 /* -------------------------------------------------------------------------- */
1904
1905 DLLEXPORT pdkim_ctx *
1906 pdkim_init_sign(char *domain, char *selector, char *rsa_privkey, int algo)
1907 {
1908 pdkim_ctx *ctx;
1909 pdkim_signature *sig;
1910
1911 if (!domain || !selector || !rsa_privkey)
1912   return NULL;
1913
1914 if (!(ctx = malloc(sizeof(pdkim_ctx))))
1915   return NULL;
1916 memset(ctx, 0, sizeof(pdkim_ctx));
1917
1918 if (!(ctx->linebuf = malloc(PDKIM_MAX_BODY_LINE_LEN)))
1919   {
1920   free(ctx);
1921   return NULL;
1922   }
1923
1924 if (!(sig = malloc(sizeof(pdkim_signature))))
1925   {
1926   free(ctx->linebuf);
1927   free(ctx);
1928   return NULL;
1929   }
1930 memset(sig, 0, sizeof(pdkim_signature));
1931
1932 sig->bodylength = -1;
1933
1934 ctx->mode = PDKIM_MODE_SIGN;
1935 ctx->sig = sig;
1936
1937 sig->domain = strdup(domain);
1938 sig->selector = strdup(selector);
1939 sig->rsa_privkey = strdup(rsa_privkey);
1940 sig->algo = algo;
1941
1942 if (!sig->domain || !sig->selector || !sig->rsa_privkey)
1943   goto BAIL;
1944
1945 exim_sha_init(&sig->body_hash, algo == PDKIM_ALGO_RSA_SHA1);
1946 return ctx;
1947
1948 BAIL:
1949   pdkim_free_ctx(ctx);
1950   return NULL;
1951 }
1952
1953
1954 /* -------------------------------------------------------------------------- */
1955
1956 DLLEXPORT int
1957 pdkim_set_optional(pdkim_ctx *ctx,
1958                        char *sign_headers,
1959                        char *identity,
1960                        int canon_headers,
1961                        int canon_body,
1962                        long bodylength,
1963                        unsigned long created,
1964                        unsigned long expires)
1965 {
1966 pdkim_signature * sig = ctx->sig;
1967
1968 if (identity)
1969   if (!(sig->identity = strdup(identity)))
1970     return PDKIM_ERR_OOM;
1971
1972 if (!(sig->sign_headers = strdup(sign_headers
1973         ? sign_headers : PDKIM_DEFAULT_SIGN_HEADERS)))
1974   return PDKIM_ERR_OOM;
1975
1976 sig->canon_headers = canon_headers;
1977 sig->canon_body = canon_body;
1978 sig->bodylength = bodylength;
1979 sig->created = created;
1980 sig->expires = expires;
1981
1982 return PDKIM_OK;
1983 }
1984
1985
1986 void
1987 pdkim_init(void)
1988 {
1989 exim_rsa_init();
1990 }
1991
1992
1993
1994 #endif  /*DISABLE_DKIM*/