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