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