cb57f77c022aa1ddea4b8c0356e40a3184835ca4
[users/jgh/exim.git] / src / src / pdkim / pdkim.c
1 /* $Cambridge: exim/src/src/pdkim/pdkim.c,v 1.1.2.3 2009/02/25 12:52:58 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 };
18 char *pdkim_algos[] = {
19   "rsa-sha256",
20   "rsa-sha1"
21 };
22 char *pdkim_canons[] = {
23   "simple",
24   "relaxed"
25 };
26
27
28 /* -------------------------------------------------------------------------- */
29 /* Various debugging functions */
30 #ifdef PDKIM_DEBUG
31 void pdkim_quoteprint(FILE *stream, char *data, int len, int lf) {
32   int i;
33   unsigned char *p = (unsigned char *)data;
34
35   for (i=0;i<len;i++) {
36     int c = p[i];
37     switch (c) {
38       case ' ' : fprintf(stream,"{SP}"); break;
39       case '\t': fprintf(stream,"{TB}"); break;
40       case '\r': fprintf(stream,"{CR}"); break;
41       case '\n': fprintf(stream,"{LF}"); break;
42       case '{' : fprintf(stream,"{BO}"); break;
43       case '}' : fprintf(stream,"{BC}"); break;
44       default:
45         if ( (c < 32) || (c > 127) )
46           fprintf(stream,"{%02x}",c);
47         else
48           fputc(c,stream);
49       break;
50     }
51   }
52   if (lf)
53     fputc('\n',stream);
54 }
55 #endif
56
57
58 /* -------------------------------------------------------------------------- */
59 /* Simple string list implementation for convinience */
60 pdkim_stringlist *pdkim_append_stringlist(pdkim_stringlist *base, char *str) {
61   pdkim_stringlist *new_entry = malloc(sizeof(pdkim_stringlist));
62   if (new_entry == NULL) return NULL;
63   memset(new_entry,0,sizeof(pdkim_stringlist));
64   new_entry->value = malloc(strlen(str)+1);
65   if (new_entry->value == NULL) return NULL;
66   strcpy(new_entry->value,str);
67   if (base != NULL) {
68     pdkim_stringlist *last = base;
69     while (last->next != NULL) { last = last->next; };
70     last->next = new_entry;
71     return base;
72   }
73   else return new_entry;
74 };
75
76
77 /* -------------------------------------------------------------------------- */
78 /* A small "growing string" implementation to escape malloc/realloc hell */
79 pdkim_str *pdkim_strnew (char *cstr) {
80   unsigned int len = cstr?strlen(cstr):0;
81   pdkim_str *p = malloc(sizeof(pdkim_str));
82   if (p == NULL) return NULL;
83   memset(p,0,sizeof(pdkim_str));
84   p->str = malloc(len+1);
85   if (p->str == NULL) {
86     free(p);
87     return NULL;
88   }
89   p->allocated=(len+1);
90   p->len=len;
91   if (cstr) strcpy(p->str,cstr);
92   return p;
93 };
94 char *pdkim_strcat(pdkim_str *str, char *cstr) {
95   return pdkim_strncat(str, cstr, strlen(cstr));
96 };
97 char *pdkim_strncat(pdkim_str *str, char *data, int len) {
98   if ((str->allocated - str->len) < (len+1)) {
99     /* Extend the buffer */
100     int num_frags = ((len+1)/PDKIM_STR_ALLOC_FRAG)+1;
101     char *n = realloc(str->str,
102                       (str->allocated+(num_frags*PDKIM_STR_ALLOC_FRAG)));
103     if (n == NULL) return NULL;
104     str->str = n;
105     str->allocated += (num_frags*PDKIM_STR_ALLOC_FRAG);
106   }
107   strncpy(&(str->str[str->len]),data,len);
108   str->len+=len;
109   str->str[str->len] = '\0';
110   return str->str;
111 };
112 char *pdkim_numcat(pdkim_str *str, unsigned long num) {
113   char minibuf[20];
114   snprintf(minibuf,20,"%lu",num);
115   return pdkim_strcat(str,minibuf);
116 };
117 void pdkim_strfree(pdkim_str *str) {
118   if (str == NULL) return;
119   if (str->str != NULL) free(str->str);
120   free(str);
121 };
122
123
124 /* -------------------------------------------------------------------------- */
125 /* Matches the name of the passed raw "header" against
126    the passed colon-separated "list". Case-insensitive.
127    Returns '0' for a match. */
128 int header_name_match(char *header,
129                       char *list) {
130   char *hname;
131   char *lcopy;
132   char *p;
133   char *q;
134   int rc = PDKIM_FAIL;
135   char *hcolon = strchr(header,':');
136   if (hcolon == NULL) return rc; /* This isn't a header */
137   hname = malloc((hcolon-header)+1);
138   if (hname == NULL) return PDKIM_ERR_OOM;
139   memset(hname,0,(hcolon-header)+1);
140   strncpy(hname,header,(hcolon-header));
141   lcopy = malloc(strlen(list)+1);
142   if (lcopy == NULL) {
143     free(hname);
144     return PDKIM_ERR_OOM;
145   }
146   strcpy(lcopy,list);
147   p = lcopy;
148   q = strchr(p,':');
149   while (q != NULL) {
150     *q = '\0';
151     if (strcasecmp(p,hname) == 0) {
152       rc = PDKIM_OK;
153       goto BAIL;
154     }
155     p = q+1;
156     q = strchr(p,':');
157   }
158   if (strcasecmp(p,hname) == 0) rc = PDKIM_OK;
159   BAIL:
160   free(hname);
161   free(lcopy);
162   return rc;
163 }
164
165
166 /* -------------------------------------------------------------------------- */
167 /* Performs "relaxed" canonicalization of a header. The returned pointer needs
168    to be free()d. */
169 char *pdkim_relax_header (char *header, int crlf) {
170   int past_field_name = 0;
171   int seen_wsp = 0;
172   char *p = header;
173   char *q;
174   char *relaxed = malloc(strlen(header));
175   if (relaxed == NULL) return NULL;
176   q = relaxed;
177   while (*p != '\0') {
178     int c = *p;
179     /* Ignore CR & LF */
180     if ( (c == '\r') || (c == '\n') ) {
181       p++;
182       continue;
183     }
184     if ( (c == '\t') || (c == ' ') ) {
185       c = ' '; /* Turns WSP into SP */
186       if (seen_wsp) {
187         p++;
188         continue;
189       }
190       else seen_wsp = 1;
191     }
192     else {
193       if ( (!past_field_name) && (c == ':') ) {
194         if (seen_wsp) q--;   /* This removes WSP before the colon */
195         seen_wsp = 1;        /* This removes WSP after the colon */
196         past_field_name = 1;
197       }
198       else seen_wsp = 0;
199     }
200     /* Lowercase header name */
201     if (!past_field_name) c = tolower(c);
202     *q = c;
203     p++;
204     q++;
205   }
206   *q = '\0';
207   if (crlf) strcat(relaxed,"\r\n");
208   return relaxed;
209 };
210
211
212 /* -------------------------------------------------------------------------- */
213 int pdkim_update_bodyhash(pdkim_ctx *ctx, char *data, int len) {
214   pdkim_signature *sig = ctx->sig;
215   /* Cache relaxed version of data */
216   char *relaxed_data = NULL;
217   int   relaxed_len  = 0;
218
219   /* Traverse all signatures, updating their hashes. */
220   while (sig != NULL) {
221     /* Defaults to simple canon (no further treatment necessary) */
222     char *canon_data = data;
223     int   canon_len = len;
224
225     if (sig->canon_body == PDKIM_CANON_RELAXED) {
226       /* Relax the line if not done already */
227       if (relaxed_data == NULL) {
228         int seen_wsp = 0;
229         char *p = data;
230         int q = 0;
231         relaxed_data = malloc(len+1);
232         if (relaxed_data == NULL) return PDKIM_ERR_OOM;
233         while (*p != '\0') {
234           char c = *p;
235           if ( (c == '\t') || (c == ' ') ) {
236             c = ' '; /* Turns WSP into SP */
237             if (seen_wsp) {
238               p++;
239               continue;
240             }
241             else seen_wsp = 1;
242           }
243           else seen_wsp = 0;
244           relaxed_data[q++] = c;
245           p++;
246         }
247         relaxed_data[q] = '\0';
248         relaxed_len = q;
249       }
250       canon_data = relaxed_data;
251       canon_len  = relaxed_len;
252     }
253
254     /* Make sure we don't exceed the to-be-signed body length */
255     if (sig->bodylength &&
256         ((sig->signed_body_bytes+(unsigned long)canon_len) > sig->bodylength))
257       canon_len = (sig->bodylength - sig->signed_body_bytes);
258
259     if (canon_len > 0) {
260       if (sig->algo == PDKIM_ALGO_RSA_SHA1)
261         sha1_update(&(sig->sha1_body),(unsigned char *)canon_data,canon_len);
262       else
263         sha2_update(&(sig->sha2_body),(unsigned char *)canon_data,canon_len);
264       sig->signed_body_bytes += canon_len;
265 #ifdef PDKIM_DEBUG
266       if (ctx->debug_stream!=NULL)
267         pdkim_quoteprint(ctx->debug_stream,canon_data,canon_len,0);
268 #endif
269     }
270
271     sig = sig->next;
272   }
273
274   if (relaxed_data != NULL) free(relaxed_data);
275   return PDKIM_OK;
276 };
277
278
279 /* -------------------------------------------------------------------------- */
280 int pdkim_finish_bodyhash(pdkim_ctx *ctx) {
281   pdkim_signature *sig = ctx->sig;
282
283   /* Traverse all signatures */
284   while (sig != NULL) {
285
286 #ifdef PDKIM_DEBUG
287     if (ctx->debug_stream)
288       fprintf(ctx->debug_stream, "PDKIM [%s] Body bytes hashed: %lu\n",
289               sig->domain, sig->signed_body_bytes);
290 #endif
291
292     /* Finish hashes */
293     unsigned char bh[32]; /* SHA-256 = 32 Bytes,  SHA-1 = 20 Bytes */
294     if (sig->algo == PDKIM_ALGO_RSA_SHA1)
295       sha1_finish(&(sig->sha1_body),bh);
296     else
297       sha2_finish(&(sig->sha2_body),bh);
298
299     /* SIGNING -------------------------------------------------------------- */
300     if (ctx->mode == PDKIM_MODE_SIGN) {
301
302       /* Build base64 version of body hash and place it in the sig struct */
303       int slen = (sig->algo == PDKIM_ALGO_RSA_SHA1)?20:32;
304       int dlen = 0;
305       base64_encode(NULL,&dlen,bh,slen); /* Puts needed length in dlen */
306       sig->bodyhash = malloc(dlen+1);
307       if (sig->bodyhash == NULL) return PDKIM_ERR_OOM;
308       if (base64_encode((unsigned char *)sig->bodyhash,&dlen,bh,slen) == 0) {
309         sig->bodyhash[dlen] = '\0';
310 #ifdef PDKIM_DEBUG
311         if (ctx->debug_stream)
312           fprintf(ctx->debug_stream, "PDKIM [%s] body hash: %s\n",
313                   sig->domain, sig->bodyhash);
314 #endif
315         return PDKIM_OK;
316       }
317
318       /* If bodylength limit is set, and we have received less bytes
319          than the requested amount, effectively remove the limit tag. */
320       if (sig->signed_body_bytes < sig->bodylength) sig->bodylength = 0;
321     }
322     /* VERIFICATION --------------------------------------------------------- */
323     else {
324
325
326     }
327
328
329     sig = sig->next;
330   }
331
332   return PDKIM_OK;
333 };
334
335
336
337 /* -------------------------------------------------------------------------- */
338 /* Callback from pdkim_feed below for processing complete body lines */
339 int pdkim_bodyline_complete(pdkim_ctx *ctx) {
340   char *p = ctx->linebuf;
341   int   n = ctx->linebuf_offset;
342
343   /* Ignore extra data if we've seen the end-of-data marker */
344   if (ctx->seen_eod) goto BAIL;
345
346   /* We've always got one extra byte to stuff a zero ... */
347   ctx->linebuf[(ctx->linebuf_offset)] = '\0';
348
349   if (ctx->input_mode == PDKIM_INPUT_SMTP) {
350     /* Terminate on EOD marker */
351     if (memcmp(p,".\r\n",3) == 0) {
352       ctx->seen_eod = 1;
353       goto BAIL;
354     }
355     /* Unstuff dots */
356     if (memcmp(p,"..",2) == 0) {
357       p++;
358       n--;
359     }
360   }
361
362   /* Empty lines need to be buffered until we find a non-empty line */
363   if (memcmp(p,"\r\n",2) == 0) {
364     ctx->num_buffered_crlf++;
365     goto BAIL;
366   }
367
368   /* At this point, we have a non-empty line, so release the buffered ones. */
369   while (ctx->num_buffered_crlf) {
370     pdkim_update_bodyhash(ctx,"\r\n",2);
371     ctx->num_buffered_crlf--;
372   }
373
374   pdkim_update_bodyhash(ctx,p,n);
375
376   BAIL:
377   ctx->linebuf_offset = 0;
378   return PDKIM_OK;
379 }
380
381
382 /* -------------------------------------------------------------------------- */
383 /* Callback from pdkim_feed below for processing complete headers */
384 int pdkim_header_complete(pdkim_ctx *ctx) {
385   pdkim_signature *sig = ctx->sig;
386
387   /* Special case: The last header can have an extra \r appended */
388   if ( (ctx->cur_header->len > 1) &&
389        (ctx->cur_header->str[(ctx->cur_header->len)-1] == '\r') ) {
390     ctx->cur_header->str[(ctx->cur_header->len)-1] = '\0';
391     ctx->cur_header->len--;
392   }
393
394   /* Traverse all signatures */
395   while (sig != NULL) {
396
397     /* SIGNING -------------------------------------------------------------- */
398     if (ctx->mode == PDKIM_MODE_SIGN) {
399       if (header_name_match(ctx->cur_header->str,
400                             sig->sign_headers?sig->sign_headers
401                                              :PDKIM_DEFAULT_SIGN_HEADERS) == 0) {
402         pdkim_stringlist *list = pdkim_append_stringlist(sig->headers,
403                                                          ctx->cur_header->str);
404         if (list == NULL) return PDKIM_ERR_OOM;
405         sig->headers = list;
406       }
407     }
408     /* VERIFICATION --------------------------------------------------------- */
409     else {
410
411     }
412
413     sig = sig->next;
414   }
415   ctx->cur_header->len = 0; /* Re-use existing pdkim_str */
416   return PDKIM_OK;
417 };
418
419
420
421 /* -------------------------------------------------------------------------- */
422 #define HEADER_BUFFER_FRAG_SIZE 256
423 int pdkim_feed (pdkim_ctx *ctx,
424                 char *data,
425                 int   len) {
426   int p;
427   for (p=0;p<len;p++) {
428     char c = data[p];
429     if (ctx->past_headers) {
430       /* Processing body byte */
431       ctx->linebuf[(ctx->linebuf_offset)++] = c;
432       if (c == '\n') {
433         int rc = pdkim_bodyline_complete(ctx); /* End of line */
434         if (rc != PDKIM_OK) return rc;
435       }
436       if (ctx->linebuf_offset == (PDKIM_MAX_BODY_LINE_LEN-1))
437         return PDKIM_ERR_LONG_LINE;
438     }
439     else {
440       /* Processing header byte */
441       if (c != '\r') {
442         if (c == '\n') {
443           if (ctx->seen_lf) {
444             int rc = pdkim_header_complete(ctx); /* Seen last header line */
445             if (rc != PDKIM_OK) return rc;
446             ctx->past_headers = 1;
447             ctx->seen_lf = 0;
448 #ifdef PDKIM_DEBUG
449             if (ctx->debug_stream)
450               fprintf(ctx->debug_stream,
451                 "PDKIM >> Hashed body data, canonicalized >>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
452 #endif
453             continue;
454           }
455           else ctx->seen_lf = 1;
456         }
457         else if (ctx->seen_lf) {
458           if (! ((c == '\t') || (c == ' '))) {
459             int rc = pdkim_header_complete(ctx); /* End of header */
460             if (rc != PDKIM_OK) return rc;
461           }
462           ctx->seen_lf = 0;
463         }
464       }
465       if (ctx->cur_header == NULL) {
466         ctx->cur_header = pdkim_strnew(NULL);
467         if (ctx->cur_header == NULL) return PDKIM_ERR_OOM;
468       }
469       if (pdkim_strncat(ctx->cur_header,&data[p],1) == NULL)
470         return PDKIM_ERR_OOM;
471     }
472   }
473   return PDKIM_OK;
474 };
475
476
477 /* -------------------------------------------------------------------------- */
478 pdkim_str *pdkim_create_header(pdkim_ctx *ctx, int final) {
479
480   pdkim_str *hdr = pdkim_strnew("DKIM-Signature: v="PDKIM_SIGNATURE_VERSION);
481   if (hdr == NULL) return NULL;
482   /* Required and static bits */
483   if (
484         pdkim_strcat(hdr,"; a=")                                     &&
485         pdkim_strcat(hdr,pdkim_algos[ctx->sig->algo])                &&
486         pdkim_strcat(hdr,"; q=")                                     &&
487         pdkim_strcat(hdr,pdkim_querymethods[ctx->sig->querymethod])  &&
488         pdkim_strcat(hdr,"; c=")                                     &&
489         pdkim_strcat(hdr,pdkim_canons[ctx->sig->canon_headers])      &&
490         pdkim_strcat(hdr,"/")                                        &&
491         pdkim_strcat(hdr,pdkim_canons[ctx->sig->canon_body])         &&
492         pdkim_strcat(hdr,"; d=")                                     &&
493         pdkim_strcat(hdr,ctx->sig->domain)                           &&
494         pdkim_strcat(hdr,"; s=")                                     &&
495         pdkim_strcat(hdr,ctx->sig->selector)                         &&
496         pdkim_strcat(hdr,";\r\n\th=")                                &&
497         pdkim_strcat(hdr,ctx->sig->headernames)                      &&
498         pdkim_strcat(hdr,"; bh=")                                    &&
499         pdkim_strcat(hdr,ctx->sig->bodyhash)                         &&
500         pdkim_strcat(hdr,";\r\n\t")
501      ) {
502     /* Optional bits */
503     if (ctx->sig->identity != NULL) {
504       if (!( pdkim_strcat(hdr,"i=")                                  &&
505              pdkim_strcat(hdr,ctx->sig->identity)                    &&
506              pdkim_strcat(hdr,";") ) ) {
507         return NULL;
508       }
509     }
510     if (ctx->sig->created > 0) {
511       if (!( pdkim_strcat(hdr,"t=")                                  &&
512              pdkim_numcat(hdr,ctx->sig->created)                     &&
513              pdkim_strcat(hdr,";") ) ) {
514         return NULL;
515       }
516     }
517     if (ctx->sig->expires > 0) {
518       if (!( pdkim_strcat(hdr,"x=")                                  &&
519              pdkim_numcat(hdr,ctx->sig->expires)                     &&
520              pdkim_strcat(hdr,";") ) ) {
521         return NULL;
522       }
523     }
524     if (ctx->sig->bodylength > 0) {
525       if (!( pdkim_strcat(hdr,"l=")                                  &&
526              pdkim_numcat(hdr,ctx->sig->bodylength)                  &&
527              pdkim_strcat(hdr,";") ) ) {
528         return NULL;
529       }
530     }
531     /* Extra linebreak */
532     if (hdr->str[(hdr->len)-1] == ';') {
533       if (!pdkim_strcat(hdr," \r\n\t")) return NULL;
534     }
535     /* Preliminary or final version? */
536     if (final) {
537       if (
538             pdkim_strcat(hdr,"b=")                                   &&
539             pdkim_strcat(hdr,ctx->sig->sigdata)                      &&
540             pdkim_strcat(hdr,";")
541          ) return hdr;
542     }
543     else {
544       if (pdkim_strcat(hdr,"b=;")) return hdr;
545     }
546   }
547   return NULL;
548 }
549
550
551 /* -------------------------------------------------------------------------- */
552 int pdkim_feed_finish(pdkim_ctx *ctx, char **signature) {
553
554   /* Check if we must still flush a (partial) header. If that is the
555      case, the message has no body, and we must compute a body hash
556      out of '<CR><LF>' */
557   if (ctx->cur_header->len) {
558     int rc = pdkim_header_complete(ctx);
559     if (rc != PDKIM_OK) return rc;
560     pdkim_update_bodyhash(ctx,"\r\n",2);
561   }
562   else {
563     /* For non-smtp input, check if there's an unfinished line in the
564        body line buffer. If that is the case, we must add a CRLF to the
565        hash to properly terminate the message. */
566     if ((ctx->input_mode == PDKIM_INPUT_NORMAL) && ctx->linebuf_offset) {
567       pdkim_update_bodyhash(ctx, ctx->linebuf, ctx->linebuf_offset);
568       pdkim_update_bodyhash(ctx,"\r\n",2);
569     }
570 #ifdef PDKIM_DEBUG
571     if (ctx->debug_stream)
572       fprintf(ctx->debug_stream,
573         "\nPDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
574 #endif
575   }
576
577   if (pdkim_finish_bodyhash(ctx) != PDKIM_OK) return PDKIM_ERR_OOM;
578
579   /* SIGNING ---------------------------------------------------------------- */
580   if (ctx->mode == PDKIM_MODE_SIGN) {
581     pdkim_stringlist *p;
582     pdkim_str *headernames;
583     pdkim_str *hdr;
584     char *canon_signature;
585     unsigned char headerhash[32];
586     char *headerhash_base64;
587     char *rsa_sig;
588     int sigdata_len = 0;
589     sha1_context sha1_headers;
590     sha2_context sha2_headers;
591     rsa_context rsa;
592     if (ctx->sig->algo == PDKIM_ALGO_RSA_SHA1) sha1_starts(&sha1_headers);
593     else sha2_starts(&sha2_headers,0);
594     /* Run through the accumulated list of to-be-signed headers */
595 #ifdef PDKIM_DEBUG
596     if (ctx->debug_stream)
597       fprintf(ctx->debug_stream,
598               "PDKIM >> Hashed header data, canonicalized, in sequence >>>>>>>>>>>>>>\n");
599 #endif
600     headernames = pdkim_strnew(NULL);
601     p = ctx->sig->headers;
602     while (p != NULL) {
603       char *rh = p->value;
604       /* Collect header names (Note: colon presence is guaranteed here) */
605       char *q = strchr(p->value,':');
606       if (pdkim_strncat(headernames, p->value,
607                         (q-(p->value))+((p->next==NULL)?0:1)) == NULL)
608         return PDKIM_ERR_OOM;
609       /* Cook the header if using relaxed canon */
610       if (ctx->sig->canon_body == PDKIM_CANON_RELAXED) {
611         rh = pdkim_relax_header(p->value,1);
612         if (rh == NULL) return PDKIM_ERR_OOM;
613       }
614       /* Feed header to the hash algorithm */
615       if (ctx->sig->algo == PDKIM_ALGO_RSA_SHA1)
616         sha1_update(&(sha1_headers),(unsigned char *)rh,strlen(rh));
617       else
618         sha2_update(&(sha2_headers),(unsigned char *)rh,strlen(rh));
619 #ifdef PDKIM_DEBUG
620       if (ctx->debug_stream)
621         pdkim_quoteprint(ctx->debug_stream, rh, strlen(rh), 1);
622 #endif
623       p = p->next;
624     }
625
626 #ifdef PDKIM_DEBUG
627     if (ctx->debug_stream)
628       fprintf(ctx->debug_stream,
629               "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
630 #endif
631
632     /* Copy headernames to signature struct */
633     ctx->sig->headernames = malloc((headernames->len)+1);
634     if (ctx->sig->headernames == NULL) return PDKIM_ERR_OOM;
635     strcpy(ctx->sig->headernames, headernames->str);
636     pdkim_strfree(headernames);
637
638     /* Create signature header with b= omitted */
639     hdr = pdkim_create_header(ctx,0);
640     if (hdr == NULL) return PDKIM_ERR_OOM;
641
642     /* If necessary, perform relaxed canon */
643     canon_signature = hdr->str;
644     if (ctx->sig->canon_headers == PDKIM_CANON_RELAXED) {
645       canon_signature = pdkim_relax_header(canon_signature,0);
646       if (canon_signature == NULL) return PDKIM_ERR_OOM;
647     }
648
649 #ifdef PDKIM_DEBUG
650   if (ctx->debug_stream) {
651     fprintf(ctx->debug_stream,
652             "PDKIM >> Signed DKIM-Signature header, canonicalized >>>>>>>>>>>>>>>>>\n");
653     pdkim_quoteprint(ctx->debug_stream, canon_signature, strlen(canon_signature), 1);
654     fprintf(ctx->debug_stream,
655             "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
656   }
657 #endif
658
659     /* Feed preliminary signature header to the hash algorithm */
660     if (ctx->sig->algo == PDKIM_ALGO_RSA_SHA1) {
661       int dlen = 0;
662       sha1_update(&(sha1_headers),(unsigned char *)canon_signature,strlen(canon_signature));
663       sha1_finish(&(sha1_headers),headerhash);
664       base64_encode(NULL,&dlen,headerhash,20);
665       headerhash_base64 = malloc(dlen+1);
666       if (headerhash == NULL) return PDKIM_ERR_OOM;
667       base64_encode((unsigned char *)headerhash_base64,&dlen,headerhash,20);
668       headerhash_base64[dlen] = '\0';
669 #ifdef PDKIM_DEBUG
670       if (ctx->debug_stream)
671         fprintf(ctx->debug_stream,
672           "PDKIM SHA1 header hash: %s\n",headerhash_base64);
673 #endif
674     }
675     else {
676       int dlen = 0;
677       sha2_update(&(sha2_headers),(unsigned char *)canon_signature,strlen(canon_signature));
678       sha2_finish(&(sha2_headers),headerhash);
679       base64_encode(NULL,&dlen,headerhash,32);
680       headerhash_base64 = malloc(dlen+1);
681       if (headerhash == NULL) return PDKIM_ERR_OOM;
682       base64_encode((unsigned char *)headerhash_base64,&dlen,headerhash,32);
683       headerhash_base64[dlen] = '\0';
684 #ifdef PDKIM_DEBUG
685       if (ctx->debug_stream)
686         fprintf(ctx->debug_stream,
687           "PDKIM SHA256 header hash: %s\n",headerhash_base64);
688 #endif
689     }
690
691     if (rsa_parse_key(&rsa, (unsigned char *)ctx->sig->rsa_privkey,
692                       strlen(ctx->sig->rsa_privkey), NULL, 0) != 0) {
693       return PDKIM_ERR_RSA_PRIVKEY;
694     }
695
696     rsa_sig = malloc(mpi_size(&(rsa.N)));
697     if (rsa_sig == NULL) return PDKIM_ERR_OOM;
698
699     if (rsa_pkcs1_sign( &rsa, RSA_PRIVATE,
700                         ((ctx->sig->algo == PDKIM_ALGO_RSA_SHA1)?
701                            RSA_SHA1
702                            :
703                            RSA_SHA256
704                         ),
705                         0, headerhash, (unsigned char *)rsa_sig ) != 0) {
706       return PDKIM_ERR_RSA_SIGNING;
707     }
708
709     base64_encode(NULL,&sigdata_len,(unsigned char *)rsa_sig,mpi_size(&(rsa.N)));
710     ctx->sig->sigdata = malloc(sigdata_len+1);
711     if (ctx->sig->sigdata == NULL) return PDKIM_ERR_OOM;
712     base64_encode((unsigned char *)ctx->sig->sigdata,
713                   &sigdata_len,
714                   (unsigned char *)rsa_sig,
715                   mpi_size(&(rsa.N)));
716     ctx->sig->sigdata[sigdata_len] = '\0';
717
718 #ifdef PDKIM_DEBUG
719     if (ctx->debug_stream)
720       fprintf(ctx->debug_stream,
721         "PDKIM RSA-signed hash: %s\n",ctx->sig->sigdata);
722 #endif
723
724     /* Recreate signature header with b= included */
725     pdkim_strfree(hdr);
726     hdr = pdkim_create_header(ctx,1);
727     if (hdr == NULL) return PDKIM_ERR_OOM;
728
729 #ifdef PDKIM_DEBUG
730     if (ctx->debug_stream) {
731       fprintf(ctx->debug_stream,
732               "PDKIM >> Final DKIM-Signature header >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
733       pdkim_quoteprint(ctx->debug_stream, hdr->str, hdr->len, 1);
734       fprintf(ctx->debug_stream,
735               "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
736     }
737 #endif
738
739     if (signature != NULL) {
740       *signature = hdr->str;
741     }
742
743   }
744
745
746   return PDKIM_OK;
747 }
748
749
750 /* -------------------------------------------------------------------------- */
751 pdkim_ctx *pdkim_init_sign(char *domain,
752                            char *selector,
753                            char *rsa_privkey) {
754   pdkim_ctx *ctx;
755
756   if (!domain || !selector || !rsa_privkey) return NULL;
757
758   ctx = malloc(sizeof(pdkim_ctx));
759   if (ctx == NULL) return NULL;
760   memset(ctx,0,sizeof(pdkim_ctx));
761   pdkim_signature *sig = malloc(sizeof(pdkim_signature));
762   if (sig == NULL) {
763     free(ctx);
764     return NULL;
765   }
766   memset(sig,0,sizeof(pdkim_signature));
767
768   ctx->mode = PDKIM_MODE_SIGN;
769   ctx->sig = sig;
770
771   ctx->sig->domain = malloc(strlen(domain)+1);
772   ctx->sig->selector = malloc(strlen(selector)+1);
773   ctx->sig->rsa_privkey = malloc(strlen(rsa_privkey)+1);
774
775   if (!ctx->sig->domain || !ctx->sig->selector || !ctx->sig->rsa_privkey) {
776     pdkim_free_ctx(ctx);
777     return NULL;
778   }
779
780   strcpy(ctx->sig->domain, domain);
781   strcpy(ctx->sig->selector, selector);
782   strcpy(ctx->sig->rsa_privkey, rsa_privkey);
783
784   sha1_starts(&(ctx->sig->sha1_body));
785   sha2_starts(&(ctx->sig->sha2_body),0);
786
787   return ctx;
788
789 };
790
791 #ifdef PDKIM_DEBUG
792 /* -------------------------------------------------------------------------- */
793 void pdkim_set_debug_stream(pdkim_ctx *ctx,
794                             FILE *debug_stream) {
795   ctx->debug_stream = debug_stream;
796 };
797 #endif
798
799 /* -------------------------------------------------------------------------- */
800 int pdkim_set_optional(pdkim_ctx *ctx,
801                        int input_mode,
802                        char *sign_headers,
803                        char *identity,
804                        int canon_headers,
805                        int canon_body,
806                        unsigned long bodylength,
807                        int algo,
808                        unsigned long created,
809                        unsigned long expires) {
810
811   if (identity != NULL) {
812     ctx->sig->identity = malloc(strlen(identity)+1);
813     if (!ctx->sig->identity) {
814       return PDKIM_ERR_OOM;
815     }
816     strcpy(ctx->sig->identity, identity);
817   }
818
819   if (sign_headers != NULL) {
820     ctx->sig->sign_headers = malloc(strlen(sign_headers)+1);
821     if (!ctx->sig->sign_headers) {
822       return PDKIM_ERR_OOM;
823     }
824     strcpy(ctx->sig->sign_headers, sign_headers);
825   }
826
827   ctx->input_mode = input_mode;
828   ctx->sig->canon_headers = canon_headers;
829   ctx->sig->canon_body = canon_body;
830   ctx->sig->bodylength = bodylength;
831   ctx->sig->algo = algo;
832   ctx->sig->created = created;
833   ctx->sig->expires = expires;
834
835   return PDKIM_OK;
836 };
837
838
839
840
841 /* -------------------------------------------------------------------------- */
842 void pdkim_free_sig(pdkim_signature *sig) {
843   if (sig) {
844     pdkim_signature *next = (pdkim_signature *)sig->next;
845
846     pdkim_stringlist *e = sig->headers;
847     while(e != NULL) {
848       pdkim_stringlist *c = e;
849       if (e->value != NULL) free(e->value);
850       e = e->next;
851       free(c);
852     }
853
854     if (sig->sigdata        != NULL) free(sig->sigdata);
855     if (sig->bodyhash       != NULL) free(sig->bodyhash);
856     if (sig->selector       != NULL) free(sig->selector);
857     if (sig->domain         != NULL) free(sig->domain);
858     if (sig->identity       != NULL) free(sig->identity);
859     if (sig->headernames    != NULL) free(sig->headernames);
860     if (sig->copiedheaders  != NULL) free(sig->copiedheaders);
861     if (sig->rsa_privkey    != NULL) free(sig->rsa_privkey);
862     if (sig->sign_headers   != NULL) free(sig->sign_headers);
863
864     free(sig);
865     if (next != NULL) pdkim_free_sig(next);
866   }
867 };
868
869
870 /* -------------------------------------------------------------------------- */
871 void pdkim_free_ctx(pdkim_ctx *ctx) {
872   if (ctx) {
873     pdkim_free_sig(ctx->sig);
874     pdkim_strfree(ctx->cur_header);
875     free(ctx);
876   }
877 };