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