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