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