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