c701b98543753bcb340034e5de500d698a064017
[users/jgh/exim.git] / src / src / pdkim / pdkim.c
1 /* $Cambridge: exim/src/src/pdkim/pdkim.c,v 1.1.2.4 2009/02/26 16:07:36 tom Exp $ */
2 /* pdkim.c */
3
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <strings.h>
8 #include <ctype.h>
9 #include <unistd.h>
10 #include "pdkim.h"
11
12
13 /* -------------------------------------------------------------------------- */
14 /* A bunch of list constants */
15 char *pdkim_querymethods[] = {
16   "dns/txt",
17   NULL
18 };
19 char *pdkim_algos[] = {
20   "rsa-sha256",
21   "rsa-sha1",
22   NULL
23 };
24 char *pdkim_canons[] = {
25   "simple",
26   "relaxed",
27   NULL
28 };
29
30 typedef struct pdkim_combined_canon_entry {
31   char *str;
32   int canon_headers;
33   int canon_body;
34 } pdkim_combined_canon_entry;
35 pdkim_combined_canon_entry pdkim_combined_canons[] = {
36   { "simple/simple",    PDKIM_CANON_SIMPLE,   PDKIM_CANON_SIMPLE },
37   { "simple/relaxed",   PDKIM_CANON_SIMPLE,   PDKIM_CANON_RELAXED },
38   { "relaxed/simple",   PDKIM_CANON_RELAXED,  PDKIM_CANON_SIMPLE },
39   { "relaxed/relaxed",  PDKIM_CANON_RELAXED,  PDKIM_CANON_RELAXED },
40   { "simple",           PDKIM_CANON_SIMPLE,   PDKIM_CANON_SIMPLE },
41   { "relaxed",          PDKIM_CANON_RELAXED,  PDKIM_CANON_SIMPLE },
42   { NULL,               0,                    0 }
43 };
44
45
46 /* -------------------------------------------------------------------------- */
47 /* Various debugging functions */
48 #ifdef PDKIM_DEBUG
49 void pdkim_quoteprint(FILE *stream, char *data, int len, int lf) {
50   int i;
51   unsigned char *p = (unsigned char *)data;
52
53   for (i=0;i<len;i++) {
54     int c = p[i];
55     switch (c) {
56       case ' ' : fprintf(stream,"{SP}"); break;
57       case '\t': fprintf(stream,"{TB}"); break;
58       case '\r': fprintf(stream,"{CR}"); break;
59       case '\n': fprintf(stream,"{LF}"); break;
60       case '{' : fprintf(stream,"{BO}"); break;
61       case '}' : fprintf(stream,"{BC}"); break;
62       default:
63         if ( (c < 32) || (c > 127) )
64           fprintf(stream,"{%02x}",c);
65         else
66           fputc(c,stream);
67       break;
68     }
69   }
70   if (lf)
71     fputc('\n',stream);
72 }
73 #endif
74
75
76 /* -------------------------------------------------------------------------- */
77 /* Simple string list implementation for convinience */
78 pdkim_stringlist *pdkim_append_stringlist(pdkim_stringlist *base, char *str) {
79   pdkim_stringlist *new_entry = malloc(sizeof(pdkim_stringlist));
80   if (new_entry == NULL) return NULL;
81   memset(new_entry,0,sizeof(pdkim_stringlist));
82   new_entry->value = malloc(strlen(str)+1);
83   if (new_entry->value == NULL) return NULL;
84   strcpy(new_entry->value,str);
85   if (base != NULL) {
86     pdkim_stringlist *last = base;
87     while (last->next != NULL) { last = last->next; };
88     last->next = new_entry;
89     return base;
90   }
91   else return new_entry;
92 };
93
94
95 /* -------------------------------------------------------------------------- */
96 /* A small "growing string" implementation to escape malloc/realloc hell */
97 pdkim_str *pdkim_strnew (char *cstr) {
98   unsigned int len = cstr?strlen(cstr):0;
99   pdkim_str *p = malloc(sizeof(pdkim_str));
100   if (p == NULL) return NULL;
101   memset(p,0,sizeof(pdkim_str));
102   p->str = malloc(len+1);
103   if (p->str == NULL) {
104     free(p);
105     return NULL;
106   }
107   p->allocated=(len+1);
108   p->len=len;
109   if (cstr) strcpy(p->str,cstr);
110   return p;
111 };
112 char *pdkim_strcat(pdkim_str *str, char *cstr) {
113   return pdkim_strncat(str, cstr, strlen(cstr));
114 };
115 char *pdkim_strncat(pdkim_str *str, char *data, int len) {
116   if ((str->allocated - str->len) < (len+1)) {
117     /* Extend the buffer */
118     int num_frags = ((len+1)/PDKIM_STR_ALLOC_FRAG)+1;
119     char *n = realloc(str->str,
120                       (str->allocated+(num_frags*PDKIM_STR_ALLOC_FRAG)));
121     if (n == NULL) return NULL;
122     str->str = n;
123     str->allocated += (num_frags*PDKIM_STR_ALLOC_FRAG);
124   }
125   strncpy(&(str->str[str->len]),data,len);
126   str->len+=len;
127   str->str[str->len] = '\0';
128   return str->str;
129 };
130 char *pdkim_numcat(pdkim_str *str, unsigned long num) {
131   char minibuf[20];
132   snprintf(minibuf,20,"%lu",num);
133   return pdkim_strcat(str,minibuf);
134 };
135 char *pdkim_strtrim(pdkim_str *str) {
136   char *p = str->str;
137   char *q = str->str;
138   while ( (*p != '\0') && ((*p == '\t') || (*p == ' ')) ) p++;
139   while (*p != '\0') {*q = *p; q++; p++;};
140   *q = '\0';
141   while ( (q != str->str) && ( (*q == '\0') || (*q == '\t') || (*q == ' ') ) ) {
142     *q = '\0';
143     q--;
144   }
145   str->len = strlen(str->str);
146   return str->str;
147 };
148 char *pdkim_strclear(pdkim_str *str) {
149   str->str[0] = '\0';
150   str->len = 0;
151   return str->str;
152 };
153 void pdkim_strfree(pdkim_str *str) {
154   if (str == NULL) return;
155   if (str->str != NULL) free(str->str);
156   free(str);
157 };
158
159
160 /* -------------------------------------------------------------------------- */
161 /* Matches the name of the passed raw "header" against
162    the passed colon-separated "list". Case-insensitive.
163    Returns '0' for a match. */
164 int header_name_match(char *header,
165                       char *list) {
166   char *hname;
167   char *lcopy;
168   char *p;
169   char *q;
170   int rc = PDKIM_FAIL;
171   char *hcolon = strchr(header,':');
172   if (hcolon == NULL) return rc; /* This isn't a header */
173   hname = malloc((hcolon-header)+1);
174   if (hname == NULL) return PDKIM_ERR_OOM;
175   memset(hname,0,(hcolon-header)+1);
176   strncpy(hname,header,(hcolon-header));
177   lcopy = malloc(strlen(list)+1);
178   if (lcopy == NULL) {
179     free(hname);
180     return PDKIM_ERR_OOM;
181   }
182   strcpy(lcopy,list);
183   p = lcopy;
184   q = strchr(p,':');
185   while (q != NULL) {
186     *q = '\0';
187     if (strcasecmp(p,hname) == 0) {
188       rc = PDKIM_OK;
189       goto BAIL;
190     }
191     p = q+1;
192     q = strchr(p,':');
193   }
194   if (strcasecmp(p,hname) == 0) rc = PDKIM_OK;
195   BAIL:
196   free(hname);
197   free(lcopy);
198   return rc;
199 }
200
201
202 /* -------------------------------------------------------------------------- */
203 /* Performs "relaxed" canonicalization of a header. The returned pointer needs
204    to be free()d. */
205 char *pdkim_relax_header (char *header, int crlf) {
206   int past_field_name = 0;
207   int seen_wsp = 0;
208   char *p = header;
209   char *q;
210   char *relaxed = malloc(strlen(header));
211   if (relaxed == NULL) return NULL;
212   q = relaxed;
213   while (*p != '\0') {
214     int c = *p;
215     /* Ignore CR & LF */
216     if ( (c == '\r') || (c == '\n') ) {
217       p++;
218       continue;
219     }
220     if ( (c == '\t') || (c == ' ') ) {
221       c = ' '; /* Turns WSP into SP */
222       if (seen_wsp) {
223         p++;
224         continue;
225       }
226       else seen_wsp = 1;
227     }
228     else {
229       if ( (!past_field_name) && (c == ':') ) {
230         if (seen_wsp) q--;   /* This removes WSP before the colon */
231         seen_wsp = 1;        /* This removes WSP after the colon */
232         past_field_name = 1;
233       }
234       else seen_wsp = 0;
235     }
236     /* Lowercase header name */
237     if (!past_field_name) c = tolower(c);
238     *q = c;
239     p++;
240     q++;
241   }
242   *q = '\0';
243   if (crlf) strcat(relaxed,"\r\n");
244   return relaxed;
245 };
246
247
248 /* -------------------------------------------------------------------------- */
249 #define PDKIM_QP_ERROR_DECODE -1
250 char *pdkim_decode_qp_char(char *qp_p, int *c) {
251   char *initial_pos = qp_p;
252
253   /* Advance one char */
254   qp_p++;
255
256   /* Check for two hex digits and decode them */
257   if (isxdigit(*qp_p) && isxdigit(qp_p[1])) {
258     /* Do hex conversion */
259     if (isdigit(*qp_p)) {*c = *qp_p - '0';}
260     else {*c = toupper(*qp_p) - 'A' + 10;};
261     *c <<= 4;
262     if (isdigit(qp_p[1])) {*c |= qp_p[1] - '0';}
263     else {*c |= toupper(qp_p[1]) - 'A' + 10;};
264     return qp_p + 2;
265   };
266
267   /* Illegal char here */
268   *c = PDKIM_QP_ERROR_DECODE;
269   return initial_pos;
270 }
271
272
273 /* -------------------------------------------------------------------------- */
274 char *pdkim_decode_qp(char *str) {
275   int nchar = 0;
276   char *q;
277   char *p = str;
278   char *n = malloc(strlen(p)+1);
279   if (n == NULL) return NULL;
280   *n = '\0';
281   q = n;
282   while (*p != '\0') {
283     if (*p == '=') {
284       p = pdkim_decode_qp_char(p,&nchar);
285       if (nchar >= 0) {
286         *q = nchar;
287         q++;
288         continue;
289       }
290     }
291     else {
292       *q = *p;
293       q++;
294     }
295     p++;
296   }
297   return n;
298 }
299
300
301 /* -------------------------------------------------------------------------- */
302 char *pdkim_decode_base64(char *str) {
303   int dlen = 0;
304   char *res;
305
306   base64_decode(NULL, &dlen, str, strlen(str));
307   res = malloc(dlen+1);
308   if (res == NULL) return NULL;
309   if (base64_decode(res,&dlen,str,strlen(str)) != 0) {
310     free(res);
311     return NULL;
312   }
313   return res;
314 }
315
316
317 /* -------------------------------------------------------------------------- */
318 #define PDKIM_HDR_LIMBO 0
319 #define PDKIM_HDR_TAG   1
320 #define PDKIM_HDR_VALUE 2
321 pdkim_signature *pdkim_parse_sig_header(pdkim_ctx *ctx, char *raw_hdr) {
322   pdkim_signature *sig ;
323   char *rawsig_no_b_val;
324   char *p,*q;
325   pdkim_str *cur_tag = NULL;
326   pdkim_str *cur_val = NULL;
327   int past_hname = 0;
328   int in_b_val = 0;
329   int where = PDKIM_HDR_LIMBO;
330   int i;
331
332   sig = malloc(sizeof(pdkim_signature));
333   if (sig == NULL) return NULL;
334   memset(sig,0,sizeof(pdkim_signature));
335
336   sig->rawsig_no_b_val = malloc(strlen(raw_hdr)+1);
337   if (sig->rawsig_no_b_val == NULL) {
338     free(sig);
339     return NULL;
340   }
341
342   p = raw_hdr;
343   q = sig->rawsig_no_b_val;
344
345   while (*p != '\0') {
346
347     /* Ignore FWS */
348     if ( (*p == '\r') || (*p == '\n') )
349       goto NEXT_CHAR;
350
351     /* Fast-forward through header name */
352     if (!past_hname) {
353       if (*p == ':') past_hname = 1;
354       goto NEXT_CHAR;
355     }
356
357     if (where == PDKIM_HDR_LIMBO) {
358       /* In limbo, just wait for a tag-char to appear */
359       if (!((*p >= 'a') && (*p <= 'z')))
360         goto NEXT_CHAR;
361
362       where = PDKIM_HDR_TAG;
363     }
364
365     if (where == PDKIM_HDR_TAG) {
366       if (cur_tag == NULL)
367         cur_tag = pdkim_strnew(NULL);
368
369       if ((*p >= 'a') && (*p <= 'z'))
370         pdkim_strncat(cur_tag,p,1);
371
372       if (*p == '=') {
373         if (strcmp(cur_tag->str,"b") == 0) {
374           *q = '='; q++;
375           in_b_val = 1;
376         }
377         where = PDKIM_HDR_VALUE;
378         goto NEXT_CHAR;
379       }
380     }
381
382     if (where == PDKIM_HDR_VALUE) {
383       if (cur_val == NULL)
384         cur_val = pdkim_strnew(NULL);
385
386       if ( (*p == '\r') || (*p == '\n') )
387         goto NEXT_CHAR;
388
389       if (*p == ';') {
390         if (cur_tag->len > 0) {
391           pdkim_strtrim(cur_val);
392           #ifdef PDKIM_DEBUG
393           if (ctx->debug_stream)
394             fprintf(ctx->debug_stream, "%s=%s\n", cur_tag->str, cur_val->str);
395           #endif
396           switch (cur_tag->str[0]) {
397             case 'b':
398               switch (cur_tag->str[1]) {
399                 case 'h':
400                   sig->bodyhash = pdkim_decode_base64(cur_val->str);
401                 break;
402                 default:
403                   sig->sigdata = pdkim_decode_base64(cur_val->str);
404                 break;
405               }
406             break;
407             case 'v':
408               if (strcmp(cur_val->str,PDKIM_SIGNATURE_VERSION) == 0) {
409                 /* We only support version 1, and that is currently the
410                    only version there is. */
411                 sig->version = 1;
412               }
413             break;
414             case 'a':
415               i = 0;
416               while (pdkim_algos[i] != NULL) {
417                 if (strcmp(cur_val->str,pdkim_algos[i]) == 0 ) {
418                   sig->algo = i;
419                   break;
420                 }
421                 i++;
422               }
423             break;
424             case 'c':
425               i = 0;
426               while (pdkim_combined_canons[i].str != NULL) {
427                 if (strcmp(cur_val->str,pdkim_combined_canons[i].str) == 0 ) {
428                   sig->canon_headers = pdkim_combined_canons[i].canon_headers;
429                   sig->canon_body    = pdkim_combined_canons[i].canon_body;
430                   break;
431                 }
432                 i++;
433               }
434             break;
435             case 'q':
436               i = 0;
437               while (pdkim_querymethods[i] != NULL) {
438                 if (strcmp(cur_val->str,pdkim_querymethods[i]) == 0 ) {
439                   sig->querymethod = i;
440                   break;
441                 }
442                 i++;
443               }
444             break;
445             case 's':
446               sig->selector = malloc(strlen(cur_val->str)+1);
447               if (sig->selector == NULL) break;
448               strcpy(sig->selector, cur_val->str);
449             break;
450             case 'd':
451               sig->domain = malloc(strlen(cur_val->str)+1);
452               if (sig->domain == NULL) break;
453               strcpy(sig->domain, cur_val->str);
454             break;
455             case 'i':
456               sig->identity = pdkim_decode_qp(cur_val->str);
457             break;
458             case 't':
459               sig->created = strtoul(cur_val->str,NULL,10);
460             break;
461             case 'x':
462               sig->expires = strtoul(cur_val->str,NULL,10);
463             break;
464             case 'l':
465               sig->bodylength = strtoul(cur_val->str,NULL,10);
466             break;
467             case 'h':
468               sig->headernames = malloc(strlen(cur_val->str)+1);
469               if (sig->headernames == NULL) break;
470               strcpy(sig->headernames, cur_val->str);
471             break;
472             case 'z':
473               sig->copiedheaders = pdkim_decode_qp(cur_val->str);
474             break;
475             default:
476               #ifdef PDKIM_DEBUG
477               if (ctx->debug_stream)
478                 fprintf(ctx->debug_stream, "Unknown tag encountered\n");
479               #endif
480             break;
481           }
482         }
483         pdkim_strclear(cur_tag);
484         pdkim_strclear(cur_val);
485         in_b_val = 0;
486         where = PDKIM_HDR_LIMBO;
487         goto NEXT_CHAR;
488       }
489       else pdkim_strncat(cur_val,p,1);
490     }
491
492     NEXT_CHAR:
493
494     if (!in_b_val) {
495       *q = *p;
496       q++;
497     }
498     p++;
499   }
500
501   /* Make sure the most important bits are there. */
502   if (!(sig->domain      && (*(sig->domain)      != '\0') &&
503         sig->selector    && (*(sig->selector)    != '\0') &&
504         sig->headernames && (*(sig->headernames) != '\0') &&
505         sig->version)) {
506     pdkim_free_signature(sig);
507     return NULL;
508   }
509
510   *q = '\0';
511   #ifdef PDKIM_DEBUG
512   if (ctx->debug_stream) {
513     fprintf(ctx->debug_stream,
514             "PDKIM >> Raw signature w/o b= tag value >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
515     pdkim_quoteprint(ctx->debug_stream,
516                      sig->rawsig_no_b_val,
517                      strlen(sig->rawsig_no_b_val), 1);
518     fprintf(ctx->debug_stream,
519             "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
520   }
521   #endif
522   return sig;
523 }
524
525
526
527 /* -------------------------------------------------------------------------- */
528 int pdkim_update_bodyhash(pdkim_ctx *ctx, char *data, int len) {
529   pdkim_signature *sig = ctx->sig;
530   /* Cache relaxed version of data */
531   char *relaxed_data = NULL;
532   int   relaxed_len  = 0;
533
534   /* Traverse all signatures, updating their hashes. */
535   while (sig != NULL) {
536     /* Defaults to simple canon (no further treatment necessary) */
537     char *canon_data = data;
538     int   canon_len = len;
539
540     if (sig->canon_body == PDKIM_CANON_RELAXED) {
541       /* Relax the line if not done already */
542       if (relaxed_data == NULL) {
543         int seen_wsp = 0;
544         char *p = data;
545         int q = 0;
546         relaxed_data = malloc(len+1);
547         if (relaxed_data == NULL) return PDKIM_ERR_OOM;
548         while (*p != '\0') {
549           char c = *p;
550           if ( (c == '\t') || (c == ' ') ) {
551             c = ' '; /* Turns WSP into SP */
552             if (seen_wsp) {
553               p++;
554               continue;
555             }
556             else seen_wsp = 1;
557           }
558           else seen_wsp = 0;
559           relaxed_data[q++] = c;
560           p++;
561         }
562         relaxed_data[q] = '\0';
563         relaxed_len = q;
564       }
565       canon_data = relaxed_data;
566       canon_len  = relaxed_len;
567     }
568
569     /* Make sure we don't exceed the to-be-signed body length */
570     if (sig->bodylength &&
571         ((sig->signed_body_bytes+(unsigned long)canon_len) > sig->bodylength))
572       canon_len = (sig->bodylength - sig->signed_body_bytes);
573
574     if (canon_len > 0) {
575       if (sig->algo == PDKIM_ALGO_RSA_SHA1)
576         sha1_update(&(sig->sha1_body),(unsigned char *)canon_data,canon_len);
577       else
578         sha2_update(&(sig->sha2_body),(unsigned char *)canon_data,canon_len);
579       sig->signed_body_bytes += canon_len;
580 #ifdef PDKIM_DEBUG
581       if (ctx->debug_stream!=NULL)
582         pdkim_quoteprint(ctx->debug_stream,canon_data,canon_len,0);
583 #endif
584     }
585
586     sig = sig->next;
587   }
588
589   if (relaxed_data != NULL) free(relaxed_data);
590   return PDKIM_OK;
591 };
592
593
594 /* -------------------------------------------------------------------------- */
595 int pdkim_finish_bodyhash(pdkim_ctx *ctx) {
596   pdkim_signature *sig = ctx->sig;
597
598   /* Traverse all signatures */
599   while (sig != NULL) {
600
601 #ifdef PDKIM_DEBUG
602     if (ctx->debug_stream)
603       fprintf(ctx->debug_stream, "PDKIM [%s] Body bytes hashed: %lu\n",
604               sig->domain, sig->signed_body_bytes);
605 #endif
606
607     /* Finish hashes */
608     unsigned char bh[32]; /* SHA-256 = 32 Bytes,  SHA-1 = 20 Bytes */
609     if (sig->algo == PDKIM_ALGO_RSA_SHA1)
610       sha1_finish(&(sig->sha1_body),bh);
611     else
612       sha2_finish(&(sig->sha2_body),bh);
613
614     /* SIGNING -------------------------------------------------------------- */
615     if (ctx->mode == PDKIM_MODE_SIGN) {
616
617       /* Build base64 version of body hash and place it in the sig struct */
618       int slen = (sig->algo == PDKIM_ALGO_RSA_SHA1)?20:32;
619       int dlen = 0;
620       base64_encode(NULL,&dlen,bh,slen); /* Puts needed length in dlen */
621       sig->bodyhash = malloc(dlen+1);
622       if (sig->bodyhash == NULL) return PDKIM_ERR_OOM;
623       if (base64_encode((unsigned char *)sig->bodyhash,&dlen,bh,slen) == 0) {
624         sig->bodyhash[dlen] = '\0';
625 #ifdef PDKIM_DEBUG
626         if (ctx->debug_stream)
627           fprintf(ctx->debug_stream, "PDKIM [%s] body hash: %s\n",
628                   sig->domain, sig->bodyhash);
629 #endif
630         return PDKIM_OK;
631       }
632
633       /* If bodylength limit is set, and we have received less bytes
634          than the requested amount, effectively remove the limit tag. */
635       if (sig->signed_body_bytes < sig->bodylength) sig->bodylength = 0;
636     }
637     /* VERIFICATION --------------------------------------------------------- */
638     else {
639
640     }
641
642
643     sig = sig->next;
644   }
645
646   return PDKIM_OK;
647 };
648
649
650
651 /* -------------------------------------------------------------------------- */
652 /* Callback from pdkim_feed below for processing complete body lines */
653 int pdkim_bodyline_complete(pdkim_ctx *ctx) {
654   char *p = ctx->linebuf;
655   int   n = ctx->linebuf_offset;
656
657   /* Ignore extra data if we've seen the end-of-data marker */
658   if (ctx->seen_eod) goto BAIL;
659
660   /* We've always got one extra byte to stuff a zero ... */
661   ctx->linebuf[(ctx->linebuf_offset)] = '\0';
662
663   if (ctx->input_mode == PDKIM_INPUT_SMTP) {
664     /* Terminate on EOD marker */
665     if (memcmp(p,".\r\n",3) == 0) {
666       ctx->seen_eod = 1;
667       goto BAIL;
668     }
669     /* Unstuff dots */
670     if (memcmp(p,"..",2) == 0) {
671       p++;
672       n--;
673     }
674   }
675
676   /* Empty lines need to be buffered until we find a non-empty line */
677   if (memcmp(p,"\r\n",2) == 0) {
678     ctx->num_buffered_crlf++;
679     goto BAIL;
680   }
681
682   /* At this point, we have a non-empty line, so release the buffered ones. */
683   while (ctx->num_buffered_crlf) {
684     pdkim_update_bodyhash(ctx,"\r\n",2);
685     ctx->num_buffered_crlf--;
686   }
687
688   pdkim_update_bodyhash(ctx,p,n);
689
690   BAIL:
691   ctx->linebuf_offset = 0;
692   return PDKIM_OK;
693 }
694
695
696 /* -------------------------------------------------------------------------- */
697 /* Callback from pdkim_feed below for processing complete headers */
698 #define DKIM_SIGNATURE_HEADERNAME "DKIM-Signature:"
699 int pdkim_header_complete(pdkim_ctx *ctx) {
700   pdkim_signature *sig = ctx->sig;
701
702   /* Special case: The last header can have an extra \r appended */
703   if ( (ctx->cur_header->len > 1) &&
704        (ctx->cur_header->str[(ctx->cur_header->len)-1] == '\r') ) {
705     ctx->cur_header->str[(ctx->cur_header->len)-1] = '\0';
706     ctx->cur_header->len--;
707   }
708
709   /* Traverse all signatures */
710   while (sig != NULL) {
711
712     /* SIGNING -------------------------------------------------------------- */
713     if (ctx->mode == PDKIM_MODE_SIGN) {
714       if (header_name_match(ctx->cur_header->str,
715                             sig->sign_headers?sig->sign_headers
716                                              :PDKIM_DEFAULT_SIGN_HEADERS) == 0) {
717         pdkim_stringlist *list = pdkim_append_stringlist(sig->headers,
718                                                          ctx->cur_header->str);
719         if (list == NULL) return PDKIM_ERR_OOM;
720         sig->headers = list;
721       }
722     }
723     /* VERIFICATION --------------------------------------------------------- */
724     else {
725
726     }
727
728     sig = sig->next;
729   }
730
731   /* DKIM-Signature: headers are added to the verification list */
732   if ( (ctx->mode == PDKIM_MODE_VERIFY) &&
733        (strncasecmp(ctx->cur_header->str,
734                     DKIM_SIGNATURE_HEADERNAME,
735                     strlen(DKIM_SIGNATURE_HEADERNAME)) == 0) ) {
736     /* Create and chain new signature block */
737     #ifdef PDKIM_DEBUG
738     if (ctx->debug_stream)
739       fprintf(ctx->debug_stream,
740         "PDKIM >> Found sig, trying to parse >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
741     #endif
742     pdkim_signature *new_sig = pdkim_parse_sig_header(ctx, ctx->cur_header->str);
743     if (new_sig != NULL) {
744       pdkim_signature *last_sig = ctx->sig;
745       if (last_sig == NULL) {
746         ctx->sig = new_sig;
747       }
748       else {
749         while (last_sig->next != NULL) { last_sig = last_sig->next; };
750         last_sig->next = new_sig;
751       }
752     }
753     else {
754       #ifdef PDKIM_DEBUG
755       if (ctx->debug_stream) {
756         fprintf(ctx->debug_stream,"Error while parsing signature header\n");
757         fprintf(ctx->debug_stream,
758           "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
759       }
760     #endif
761     }
762   }
763
764   pdkim_strclear(ctx->cur_header); /* Re-use existing pdkim_str */
765   return PDKIM_OK;
766 };
767
768
769
770 /* -------------------------------------------------------------------------- */
771 #define HEADER_BUFFER_FRAG_SIZE 256
772 int pdkim_feed (pdkim_ctx *ctx,
773                 char *data,
774                 int   len) {
775   int p;
776   for (p=0;p<len;p++) {
777     char c = data[p];
778     if (ctx->past_headers) {
779       /* Processing body byte */
780       ctx->linebuf[(ctx->linebuf_offset)++] = c;
781       if (c == '\n') {
782         int rc = pdkim_bodyline_complete(ctx); /* End of line */
783         if (rc != PDKIM_OK) return rc;
784       }
785       if (ctx->linebuf_offset == (PDKIM_MAX_BODY_LINE_LEN-1))
786         return PDKIM_ERR_LONG_LINE;
787     }
788     else {
789       /* Processing header byte */
790       if (c != '\r') {
791         if (c == '\n') {
792           if (ctx->seen_lf) {
793             int rc = pdkim_header_complete(ctx); /* Seen last header line */
794             if (rc != PDKIM_OK) return rc;
795             ctx->past_headers = 1;
796             ctx->seen_lf = 0;
797 #ifdef PDKIM_DEBUG
798             if (ctx->debug_stream)
799               fprintf(ctx->debug_stream,
800                 "PDKIM >> Hashed body data, canonicalized >>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
801 #endif
802             continue;
803           }
804           else ctx->seen_lf = 1;
805         }
806         else if (ctx->seen_lf) {
807           if (! ((c == '\t') || (c == ' '))) {
808             int rc = pdkim_header_complete(ctx); /* End of header */
809             if (rc != PDKIM_OK) return rc;
810           }
811           ctx->seen_lf = 0;
812         }
813       }
814       if (ctx->cur_header == NULL) {
815         ctx->cur_header = pdkim_strnew(NULL);
816         if (ctx->cur_header == NULL) return PDKIM_ERR_OOM;
817       }
818       if (pdkim_strncat(ctx->cur_header,&data[p],1) == NULL)
819         return PDKIM_ERR_OOM;
820     }
821   }
822   return PDKIM_OK;
823 };
824
825
826 /* -------------------------------------------------------------------------- */
827 pdkim_str *pdkim_create_header(pdkim_signature *sig, int final) {
828
829   pdkim_str *hdr = pdkim_strnew("DKIM-Signature: v="PDKIM_SIGNATURE_VERSION);
830   if (hdr == NULL) return NULL;
831   /* Required and static bits */
832   if (
833         pdkim_strcat(hdr,"; a=")                                &&
834         pdkim_strcat(hdr,pdkim_algos[sig->algo])                &&
835         pdkim_strcat(hdr,"; q=")                                &&
836         pdkim_strcat(hdr,pdkim_querymethods[sig->querymethod])  &&
837         pdkim_strcat(hdr,"; c=")                                &&
838         pdkim_strcat(hdr,pdkim_canons[sig->canon_headers])      &&
839         pdkim_strcat(hdr,"/")                                   &&
840         pdkim_strcat(hdr,pdkim_canons[sig->canon_body])         &&
841         pdkim_strcat(hdr,"; d=")                                &&
842         pdkim_strcat(hdr,sig->domain)                           &&
843         pdkim_strcat(hdr,"; s=")                                &&
844         pdkim_strcat(hdr,sig->selector)                         &&
845         pdkim_strcat(hdr,";\r\n\th=")                           &&
846         pdkim_strcat(hdr,sig->headernames)                      &&
847         pdkim_strcat(hdr,"; bh=")                               &&
848         pdkim_strcat(hdr,sig->bodyhash)                         &&
849         pdkim_strcat(hdr,";\r\n\t")
850      ) {
851     /* Optional bits */
852     if (sig->identity != NULL) {
853       if (!( pdkim_strcat(hdr,"i=")                             &&
854              pdkim_strcat(hdr,sig->identity)                    &&
855              pdkim_strcat(hdr,";") ) ) {
856         return NULL;
857       }
858     }
859     if (sig->created > 0) {
860       if (!( pdkim_strcat(hdr,"t=")                             &&
861              pdkim_numcat(hdr,sig->created)                     &&
862              pdkim_strcat(hdr,";") ) ) {
863         return NULL;
864       }
865     }
866     if (sig->expires > 0) {
867       if (!( pdkim_strcat(hdr,"x=")                             &&
868              pdkim_numcat(hdr,sig->expires)                     &&
869              pdkim_strcat(hdr,";") ) ) {
870         return NULL;
871       }
872     }
873     if (sig->bodylength > 0) {
874       if (!( pdkim_strcat(hdr,"l=")                             &&
875              pdkim_numcat(hdr,sig->bodylength)                  &&
876              pdkim_strcat(hdr,";") ) ) {
877         return NULL;
878       }
879     }
880     /* Extra linebreak */
881     if (hdr->str[(hdr->len)-1] == ';') {
882       if (!pdkim_strcat(hdr," \r\n\t")) return NULL;
883     }
884     /* Preliminary or final version? */
885     if (final) {
886       if (
887             pdkim_strcat(hdr,"b=")                              &&
888             pdkim_strcat(hdr,sig->sigdata)                      &&
889             pdkim_strcat(hdr,";")
890          ) return hdr;
891     }
892     else {
893       if (pdkim_strcat(hdr,"b=;")) return hdr;
894     }
895   }
896   return NULL;
897 }
898
899
900 /* -------------------------------------------------------------------------- */
901 int pdkim_feed_finish(pdkim_ctx *ctx, char **signature) {
902
903   /* Check if we must still flush a (partial) header. If that is the
904      case, the message has no body, and we must compute a body hash
905      out of '<CR><LF>' */
906   if (ctx->cur_header->len) {
907     int rc = pdkim_header_complete(ctx);
908     if (rc != PDKIM_OK) return rc;
909     pdkim_update_bodyhash(ctx,"\r\n",2);
910   }
911   else {
912     /* For non-smtp input, check if there's an unfinished line in the
913        body line buffer. If that is the case, we must add a CRLF to the
914        hash to properly terminate the message. */
915     if ((ctx->input_mode == PDKIM_INPUT_NORMAL) && ctx->linebuf_offset) {
916       pdkim_update_bodyhash(ctx, ctx->linebuf, ctx->linebuf_offset);
917       pdkim_update_bodyhash(ctx,"\r\n",2);
918     }
919 #ifdef PDKIM_DEBUG
920     if (ctx->debug_stream)
921       fprintf(ctx->debug_stream,
922         "\nPDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
923 #endif
924   }
925
926   if (pdkim_finish_bodyhash(ctx) != PDKIM_OK) return PDKIM_ERR_OOM;
927
928   /* SIGNING ---------------------------------------------------------------- */
929   if (ctx->mode == PDKIM_MODE_SIGN) {
930     pdkim_stringlist *p;
931     pdkim_str *headernames;
932     pdkim_str *hdr;
933     char *canon_signature;
934     unsigned char headerhash[32];
935     char *headerhash_base64;
936     char *rsa_sig;
937     int sigdata_len = 0;
938     sha1_context sha1_headers;
939     sha2_context sha2_headers;
940     rsa_context rsa;
941     if (ctx->sig->algo == PDKIM_ALGO_RSA_SHA1) sha1_starts(&sha1_headers);
942     else sha2_starts(&sha2_headers,0);
943     /* Run through the accumulated list of to-be-signed headers */
944 #ifdef PDKIM_DEBUG
945     if (ctx->debug_stream)
946       fprintf(ctx->debug_stream,
947               "PDKIM >> Hashed header data, canonicalized, in sequence >>>>>>>>>>>>>>\n");
948 #endif
949     headernames = pdkim_strnew(NULL);
950     p = ctx->sig->headers;
951     while (p != NULL) {
952       char *rh = p->value;
953       /* Collect header names (Note: colon presence is guaranteed here) */
954       char *q = strchr(p->value,':');
955       if (pdkim_strncat(headernames, p->value,
956                         (q-(p->value))+((p->next==NULL)?0:1)) == NULL)
957         return PDKIM_ERR_OOM;
958       /* Cook the header if using relaxed canon */
959       if (ctx->sig->canon_body == PDKIM_CANON_RELAXED) {
960         rh = pdkim_relax_header(p->value,1);
961         if (rh == NULL) return PDKIM_ERR_OOM;
962       }
963       /* Feed header to the hash algorithm */
964       if (ctx->sig->algo == PDKIM_ALGO_RSA_SHA1)
965         sha1_update(&(sha1_headers),(unsigned char *)rh,strlen(rh));
966       else
967         sha2_update(&(sha2_headers),(unsigned char *)rh,strlen(rh));
968 #ifdef PDKIM_DEBUG
969       if (ctx->debug_stream)
970         pdkim_quoteprint(ctx->debug_stream, rh, strlen(rh), 1);
971 #endif
972       p = p->next;
973     }
974
975 #ifdef PDKIM_DEBUG
976     if (ctx->debug_stream)
977       fprintf(ctx->debug_stream,
978               "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
979 #endif
980
981     /* Copy headernames to signature struct */
982     ctx->sig->headernames = malloc((headernames->len)+1);
983     if (ctx->sig->headernames == NULL) return PDKIM_ERR_OOM;
984     strcpy(ctx->sig->headernames, headernames->str);
985     pdkim_strfree(headernames);
986
987     /* Create signature header with b= omitted */
988     hdr = pdkim_create_header(ctx->sig,0);
989     if (hdr == NULL) return PDKIM_ERR_OOM;
990
991     /* If necessary, perform relaxed canon */
992     canon_signature = hdr->str;
993     if (ctx->sig->canon_headers == PDKIM_CANON_RELAXED) {
994       canon_signature = pdkim_relax_header(canon_signature,0);
995       if (canon_signature == NULL) return PDKIM_ERR_OOM;
996     }
997
998 #ifdef PDKIM_DEBUG
999   if (ctx->debug_stream) {
1000     fprintf(ctx->debug_stream,
1001             "PDKIM >> Signed DKIM-Signature header, canonicalized >>>>>>>>>>>>>>>>>\n");
1002     pdkim_quoteprint(ctx->debug_stream, canon_signature, strlen(canon_signature), 1);
1003     fprintf(ctx->debug_stream,
1004             "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1005   }
1006 #endif
1007
1008     /* Feed preliminary signature header to the hash algorithm */
1009     if (ctx->sig->algo == PDKIM_ALGO_RSA_SHA1) {
1010       int dlen = 0;
1011       sha1_update(&(sha1_headers),(unsigned char *)canon_signature,strlen(canon_signature));
1012       sha1_finish(&(sha1_headers),headerhash);
1013       base64_encode(NULL,&dlen,headerhash,20);
1014       headerhash_base64 = malloc(dlen+1);
1015       if (headerhash == NULL) return PDKIM_ERR_OOM;
1016       base64_encode((unsigned char *)headerhash_base64,&dlen,headerhash,20);
1017       headerhash_base64[dlen] = '\0';
1018 #ifdef PDKIM_DEBUG
1019       if (ctx->debug_stream)
1020         fprintf(ctx->debug_stream,
1021           "PDKIM SHA1 header hash: %s\n",headerhash_base64);
1022 #endif
1023     }
1024     else {
1025       int dlen = 0;
1026       sha2_update(&(sha2_headers),(unsigned char *)canon_signature,strlen(canon_signature));
1027       sha2_finish(&(sha2_headers),headerhash);
1028       base64_encode(NULL,&dlen,headerhash,32);
1029       headerhash_base64 = malloc(dlen+1);
1030       if (headerhash == NULL) return PDKIM_ERR_OOM;
1031       base64_encode((unsigned char *)headerhash_base64,&dlen,headerhash,32);
1032       headerhash_base64[dlen] = '\0';
1033 #ifdef PDKIM_DEBUG
1034       if (ctx->debug_stream)
1035         fprintf(ctx->debug_stream,
1036           "PDKIM SHA256 header hash: %s\n",headerhash_base64);
1037 #endif
1038     }
1039
1040     if (rsa_parse_key(&rsa, (unsigned char *)ctx->sig->rsa_privkey,
1041                       strlen(ctx->sig->rsa_privkey), NULL, 0) != 0) {
1042       return PDKIM_ERR_RSA_PRIVKEY;
1043     }
1044
1045     rsa_sig = malloc(mpi_size(&(rsa.N)));
1046     if (rsa_sig == NULL) return PDKIM_ERR_OOM;
1047
1048     if (rsa_pkcs1_sign( &rsa, RSA_PRIVATE,
1049                         ((ctx->sig->algo == PDKIM_ALGO_RSA_SHA1)?
1050                            RSA_SHA1
1051                            :
1052                            RSA_SHA256
1053                         ),
1054                         0, headerhash, (unsigned char *)rsa_sig ) != 0) {
1055       return PDKIM_ERR_RSA_SIGNING;
1056     }
1057
1058     base64_encode(NULL,&sigdata_len,(unsigned char *)rsa_sig,mpi_size(&(rsa.N)));
1059     ctx->sig->sigdata = malloc(sigdata_len+1);
1060     if (ctx->sig->sigdata == NULL) return PDKIM_ERR_OOM;
1061     base64_encode((unsigned char *)ctx->sig->sigdata,
1062                   &sigdata_len,
1063                   (unsigned char *)rsa_sig,
1064                   mpi_size(&(rsa.N)));
1065     ctx->sig->sigdata[sigdata_len] = '\0';
1066
1067 #ifdef PDKIM_DEBUG
1068     if (ctx->debug_stream)
1069       fprintf(ctx->debug_stream,
1070         "PDKIM RSA-signed hash: %s\n",ctx->sig->sigdata);
1071 #endif
1072
1073     /* Recreate signature header with b= included */
1074     pdkim_strfree(hdr);
1075     hdr = pdkim_create_header(ctx->sig,1);
1076     if (hdr == NULL) return PDKIM_ERR_OOM;
1077
1078 #ifdef PDKIM_DEBUG
1079     if (ctx->debug_stream) {
1080       fprintf(ctx->debug_stream,
1081               "PDKIM >> Final DKIM-Signature header >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1082       pdkim_quoteprint(ctx->debug_stream, hdr->str, hdr->len, 1);
1083       fprintf(ctx->debug_stream,
1084               "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1085     }
1086 #endif
1087
1088     if (signature != NULL) {
1089       *signature = hdr->str;
1090     }
1091
1092   }
1093
1094
1095   return PDKIM_OK;
1096 }
1097
1098
1099 /* -------------------------------------------------------------------------- */
1100 pdkim_ctx *pdkim_init_verify(void) {
1101   pdkim_ctx *ctx = malloc(sizeof(pdkim_ctx));
1102   if (ctx == NULL) return NULL;
1103   memset(ctx,0,sizeof(pdkim_ctx));
1104   ctx->mode = PDKIM_MODE_VERIFY;
1105   return ctx;
1106 }
1107
1108
1109 /* -------------------------------------------------------------------------- */
1110 pdkim_ctx *pdkim_init_sign(char *domain,
1111                            char *selector,
1112                            char *rsa_privkey) {
1113   pdkim_ctx *ctx;
1114
1115   if (!domain || !selector || !rsa_privkey) return NULL;
1116
1117   ctx = malloc(sizeof(pdkim_ctx));
1118   if (ctx == NULL) return NULL;
1119   memset(ctx,0,sizeof(pdkim_ctx));
1120   pdkim_signature *sig = malloc(sizeof(pdkim_signature));
1121   if (sig == NULL) {
1122     free(ctx);
1123     return NULL;
1124   }
1125   memset(sig,0,sizeof(pdkim_signature));
1126
1127   ctx->mode = PDKIM_MODE_SIGN;
1128   ctx->sig = sig;
1129
1130   ctx->sig->domain = malloc(strlen(domain)+1);
1131   ctx->sig->selector = malloc(strlen(selector)+1);
1132   ctx->sig->rsa_privkey = malloc(strlen(rsa_privkey)+1);
1133
1134   if (!ctx->sig->domain || !ctx->sig->selector || !ctx->sig->rsa_privkey) {
1135     pdkim_free_ctx(ctx);
1136     return NULL;
1137   }
1138
1139   strcpy(ctx->sig->domain, domain);
1140   strcpy(ctx->sig->selector, selector);
1141   strcpy(ctx->sig->rsa_privkey, rsa_privkey);
1142
1143   sha1_starts(&(ctx->sig->sha1_body));
1144   sha2_starts(&(ctx->sig->sha2_body),0);
1145
1146   return ctx;
1147 };
1148
1149 #ifdef PDKIM_DEBUG
1150 /* -------------------------------------------------------------------------- */
1151 void pdkim_set_debug_stream(pdkim_ctx *ctx,
1152                             FILE *debug_stream) {
1153   ctx->debug_stream = debug_stream;
1154 };
1155 #endif
1156
1157 /* -------------------------------------------------------------------------- */
1158 int pdkim_set_optional(pdkim_ctx *ctx,
1159                        int input_mode,
1160                        char *sign_headers,
1161                        char *identity,
1162                        int canon_headers,
1163                        int canon_body,
1164                        unsigned long bodylength,
1165                        int algo,
1166                        unsigned long created,
1167                        unsigned long expires) {
1168
1169   if (identity != NULL) {
1170     ctx->sig->identity = malloc(strlen(identity)+1);
1171     if (!ctx->sig->identity) {
1172       return PDKIM_ERR_OOM;
1173     }
1174     strcpy(ctx->sig->identity, identity);
1175   }
1176
1177   if (sign_headers != NULL) {
1178     ctx->sig->sign_headers = malloc(strlen(sign_headers)+1);
1179     if (!ctx->sig->sign_headers) {
1180       return PDKIM_ERR_OOM;
1181     }
1182     strcpy(ctx->sig->sign_headers, sign_headers);
1183   }
1184
1185   ctx->input_mode = input_mode;
1186   ctx->sig->canon_headers = canon_headers;
1187   ctx->sig->canon_body = canon_body;
1188   ctx->sig->bodylength = bodylength;
1189   ctx->sig->algo = algo;
1190   ctx->sig->created = created;
1191   ctx->sig->expires = expires;
1192
1193   return PDKIM_OK;
1194 };
1195
1196
1197
1198
1199 /* -------------------------------------------------------------------------- */
1200 void pdkim_free_sig(pdkim_signature *sig) {
1201   if (sig) {
1202     pdkim_signature *next = (pdkim_signature *)sig->next;
1203
1204     pdkim_stringlist *e = sig->headers;
1205     while(e != NULL) {
1206       pdkim_stringlist *c = e;
1207       if (e->value != NULL) free(e->value);
1208       e = e->next;
1209       free(c);
1210     }
1211
1212     if (sig->sigdata        != NULL) free(sig->sigdata);
1213     if (sig->bodyhash       != NULL) free(sig->bodyhash);
1214     if (sig->selector       != NULL) free(sig->selector);
1215     if (sig->domain         != NULL) free(sig->domain);
1216     if (sig->identity       != NULL) free(sig->identity);
1217     if (sig->headernames    != NULL) free(sig->headernames);
1218     if (sig->copiedheaders  != NULL) free(sig->copiedheaders);
1219     if (sig->rsa_privkey    != NULL) free(sig->rsa_privkey);
1220     if (sig->sign_headers   != NULL) free(sig->sign_headers);
1221
1222     free(sig);
1223     if (next != NULL) pdkim_free_sig(next);
1224   }
1225 };
1226
1227
1228 /* -------------------------------------------------------------------------- */
1229 void pdkim_free_ctx(pdkim_ctx *ctx) {
1230   if (ctx) {
1231     pdkim_free_sig(ctx->sig);
1232     pdkim_strfree(ctx->cur_header);
1233     free(ctx);
1234   }
1235 };