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