2 * PDKIM - a RFC4871 (DKIM) implementation
4 * Copyright (C) 2009 - 2016 Tom Kistner <tom@duncanthrax.net>
5 * Copyright (C) 2016 Jeremy Harris <jgh@exim.org>
7 * http://duncanthrax.net/pdkim/
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.
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.
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.
27 #ifndef DISABLE_DKIM /* entire file */
30 # error Need SUPPORT_TLS for DKIM
33 #include "crypt_ver.h"
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>
47 #define PDKIM_SIGNATURE_VERSION "1"
48 #define PDKIM_PUB_RECORD_VERSION "DKIM1"
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"
63 /* -------------------------------------------------------------------------- */
64 struct pdkim_stringlist {
70 #define PDKIM_STR_ALLOC_FRAG 256
74 unsigned int allocated;
77 /* -------------------------------------------------------------------------- */
78 /* A bunch of list constants */
79 const char *pdkim_querymethods[] = {
83 const char *pdkim_algos[] = {
88 const char *pdkim_canons[] = {
93 const char *pdkim_hashes[] = {
98 const char *pdkim_keytypes[] = {
103 typedef struct pdkim_combined_canon_entry {
107 } pdkim_combined_canon_entry;
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 },
120 /* -------------------------------------------------------------------------- */
123 pdkim_verify_status_str(int 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";
135 pdkim_verify_ext_status_str(int 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";
149 /* -------------------------------------------------------------------------- */
150 /* Print debugging functions */
152 pdkim_quoteprint(const uschar *data, int len)
155 for (i = 0; i < len; i++)
157 const int c = data[i];
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;
167 if ( (c < 32) || (c > 127) )
168 debug_printf("{%02x}", c);
170 debug_printf("%c", c);
178 pdkim_hexprint(const uschar *data, int len)
181 for (i = 0 ; i < len; i++) debug_printf("%02x", data[i]);
187 /* SSS probably want to keep the "stringlist" notion */
189 static pdkim_stringlist *
190 pdkim_prepend_stringlist(pdkim_stringlist *base, char *str)
192 pdkim_stringlist *new_entry = malloc(sizeof(pdkim_stringlist));
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;
202 /* -------------------------------------------------------------------------- */
203 /* A small "growing string" implementation to escape malloc/realloc hell */
204 /* String package: should be replaced by Exim standard ones */
208 pdkim_strnew (const char *cstr)
210 unsigned int len = cstr ? strlen(cstr) : 0;
211 pdkim_str *p = malloc(sizeof(pdkim_str));
214 memset(p, 0, sizeof(pdkim_str));
215 if (!(p->str = malloc(len+1)))
220 p->allocated = len+1;
223 strcpy(p->str, cstr);
225 p->str[p->len] = '\0';
233 pdkim_strncat(pdkim_str *str, const char *data, int len)
235 if ((str->allocated - str->len) < (len+1))
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;
243 str->allocated += (num_frags*PDKIM_STR_ALLOC_FRAG);
245 strncpy(&(str->str[str->len]), data, len);
247 str->str[str->len] = '\0';
255 pdkim_strcat(pdkim_str *str, const char *cstr)
257 return pdkim_strncat(str, cstr, strlen(cstr));
262 /* Trim whitespace fore & aft */
265 pdkim_strtrim(pdkim_str *str)
269 while (*p == '\t' || *p == ' ') p++; /* skip whitespace */
270 while (*p) {*q = *p; q++; p++;} /* dump the leading whitespace */
272 while (q != str->str && ( (*q == '\0') || (*q == '\t') || (*q == ' ') ) )
273 { /* dump trailing whitespace */
277 str->len = strlen(str->str);
284 pdkim_strclear(pdkim_str *str)
294 pdkim_strfree(pdkim_str *str)
297 if (str->str) free(str->str);
303 pdkim_stringlist_free(pdkim_stringlist * e)
307 pdkim_stringlist * c = e;
308 if (e->value) free(e->value);
316 /* -------------------------------------------------------------------------- */
319 pdkim_free_pubkey(pdkim_pubkey *pub)
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);
334 /* -------------------------------------------------------------------------- */
337 pdkim_free_sig(pdkim_signature *sig)
341 pdkim_signature *next = (pdkim_signature *)sig->next;
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);
352 if (sig->pubkey) pdkim_free_pubkey(sig->pubkey);
355 if (next) pdkim_free_sig(next);
360 /* -------------------------------------------------------------------------- */
363 pdkim_free_ctx(pdkim_ctx *ctx)
367 pdkim_stringlist_free(ctx->headers);
368 pdkim_free_sig(ctx->sig);
369 pdkim_strfree(ctx->cur_header);
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" */
382 header_name_match(const char * header, char * tick)
390 /* Get header name */
391 char *hcolon = strchr(header, ':');
393 if (!hcolon) return rc; /* This isn't a header */
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));
400 /* Copy tick-off list locally, so we can punch zeroes into it */
401 if (!(lcopy = strdup(tick)))
404 return PDKIM_ERR_OOM;
412 if (strcasecmp(p, hname) == 0)
415 /* Invalidate header name instance in tick-off list */
424 if (strcasecmp(p, hname) == 0)
427 /* Invalidate header name instance in tick-off list */
438 /* -------------------------------------------------------------------------- */
439 /* Performs "relaxed" canonicalization of a header. The returned pointer needs
443 pdkim_relax_header (char *header, int crlf)
445 BOOL past_field_name = FALSE;
446 BOOL seen_wsp = FALSE;
449 char *relaxed = malloc(strlen(header)+3);
451 if (!relaxed) return NULL;
454 for (p = header; *p != '\0'; p++)
458 if (c == '\r' || c == '\n')
460 if (c == '\t' || c == ' ')
464 c = ' '; /* Turns WSP into SP */
468 if (!past_field_name && c == ':')
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;
477 /* Lowercase header name */
478 if (!past_field_name) c = tolower(c);
482 if (q > relaxed && q[-1] == ' ') q--; /* Squash eventual trailing SP */
485 if (crlf) strcat(relaxed, "\r\n");
490 /* -------------------------------------------------------------------------- */
491 #define PDKIM_QP_ERROR_DECODE -1
494 pdkim_decode_qp_char(char *qp_p, int *c)
496 char *initial_pos = qp_p;
498 /* Advance one char */
501 /* Check for two hex digits and decode them */
502 if (isxdigit(*qp_p) && isxdigit(qp_p[1]))
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;
510 /* Illegal char here */
511 *c = PDKIM_QP_ERROR_DECODE;
516 /* -------------------------------------------------------------------------- */
519 pdkim_decode_qp(char *str)
524 char *n = malloc(strlen(p)+1);
534 p = pdkim_decode_qp_char(p, &nchar);
550 /* -------------------------------------------------------------------------- */
553 pdkim_decode_base64(uschar *str, blob * b)
556 dlen = b64decode(str, &b->data);
557 if (dlen < 0) b->data = NULL;
561 /* -------------------------------------------------------------------------- */
564 pdkim_encode_base64(blob * b)
567 int old_pool = store_pool;
569 store_pool = POOL_PERM;
570 ret = CS b64encode(b->data, b->len);
571 store_pool = old_pool;
576 /* -------------------------------------------------------------------------- */
577 #define PDKIM_HDR_LIMBO 0
578 #define PDKIM_HDR_TAG 1
579 #define PDKIM_HDR_VALUE 2
581 static pdkim_signature *
582 pdkim_parse_sig_header(pdkim_ctx *ctx, char *raw_hdr)
584 pdkim_signature *sig ;
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;
592 int old_pool = store_pool;
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. */
598 store_pool = POOL_PERM;
600 if (!(sig = malloc(sizeof(pdkim_signature)))) return NULL;
601 memset(sig, 0, sizeof(pdkim_signature));
602 sig->bodylength = -1;
604 if (!(sig->rawsig_no_b_val = malloc(strlen(raw_hdr)+1)))
610 q = sig->rawsig_no_b_val;
612 for (p = raw_hdr; ; p++)
617 if (c == '\r' || c == '\n')
620 /* Fast-forward through header name */
623 if (c == ':') past_hname = TRUE;
627 if (where == PDKIM_HDR_LIMBO)
629 /* In limbo, just wait for a tag-char to appear */
630 if (!(c >= 'a' && c <= 'z'))
633 where = PDKIM_HDR_TAG;
636 if (where == PDKIM_HDR_TAG)
639 cur_tag = pdkim_strnew(NULL);
641 if (c >= 'a' && c <= 'z')
642 pdkim_strncat(cur_tag, p, 1);
646 if (strcmp(cur_tag->str, "b") == 0)
651 where = PDKIM_HDR_VALUE;
656 if (where == PDKIM_HDR_VALUE)
659 cur_val = pdkim_strnew(NULL);
661 if (c == '\r' || c == '\n' || c == ' ' || c == '\t')
664 if (c == ';' || c == '\0')
666 if (cur_tag->len > 0)
668 pdkim_strtrim(cur_val);
670 DEBUG(D_acl) debug_printf(" %s=%s\n", cur_tag->str, cur_val->str);
672 switch (cur_tag->str[0])
675 if (cur_tag->str[1] == 'h')
676 pdkim_decode_base64(US cur_val->str, &sig->bodyhash);
678 pdkim_decode_base64(US cur_val->str, &sig->sigdata);
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)
687 for (i = 0; pdkim_algos[i]; i++)
688 if (strcmp(cur_val->str, pdkim_algos[i]) == 0)
695 for (i = 0; pdkim_combined_canons[i].str; i++)
696 if (strcmp(cur_val->str, pdkim_combined_canons[i].str) == 0)
698 sig->canon_headers = pdkim_combined_canons[i].canon_headers;
699 sig->canon_body = pdkim_combined_canons[i].canon_body;
704 for (i = 0; pdkim_querymethods[i]; i++)
705 if (strcmp(cur_val->str, pdkim_querymethods[i]) == 0)
707 sig->querymethod = i;
712 sig->selector = strdup(cur_val->str); break;
714 sig->domain = strdup(cur_val->str); break;
716 sig->identity = pdkim_decode_qp(cur_val->str); break;
718 sig->created = strtoul(cur_val->str, NULL, 10); break;
720 sig->expires = strtoul(cur_val->str, NULL, 10); break;
722 sig->bodylength = strtol(cur_val->str, NULL, 10); break;
724 sig->headernames = string_copy(US cur_val->str); break;
726 sig->copiedheaders = pdkim_decode_qp(cur_val->str); break;
728 DEBUG(D_acl) debug_printf(" Unknown tag encountered\n");
732 pdkim_strclear(cur_tag);
733 pdkim_strclear(cur_val);
735 where = PDKIM_HDR_LIMBO;
738 pdkim_strncat(cur_val, p, 1);
749 store_pool = old_pool;
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') &&
762 /* Chomp raw header. The final newline must not be added to the signature. */
763 while (--q > sig->rawsig_no_b_val && (*q == '\r' || *q == '\n'))
769 "PDKIM >> Raw signature w/o b= tag value >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
770 pdkim_quoteprint(US sig->rawsig_no_b_val, strlen(sig->rawsig_no_b_val));
772 "PDKIM >> Sig size: %4u bits\n", (unsigned) sig->sigdata.len*8);
774 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
777 exim_sha_init(&sig->body_hash, sig->algo == PDKIM_ALGO_RSA_SHA1);
782 /* -------------------------------------------------------------------------- */
784 static pdkim_pubkey *
785 pdkim_parse_pubkey_record(pdkim_ctx *ctx, char *raw_record)
789 pdkim_str *cur_tag = NULL;
790 pdkim_str *cur_val = NULL;
791 int where = PDKIM_HDR_LIMBO;
793 if (!(pub = malloc(sizeof(pdkim_pubkey)))) return NULL;
794 memset(pub, 0, sizeof(pdkim_pubkey));
796 for (p = raw_record; ; p++)
801 if (c == '\r' || c == '\n')
804 if (where == PDKIM_HDR_LIMBO)
806 /* In limbo, just wait for a tag-char to appear */
807 if (!(c >= 'a' && c <= 'z'))
810 where = PDKIM_HDR_TAG;
813 if (where == PDKIM_HDR_TAG)
816 cur_tag = pdkim_strnew(NULL);
818 if (c >= 'a' && c <= 'z')
819 pdkim_strncat(cur_tag, p, 1);
823 where = PDKIM_HDR_VALUE;
828 if (where == PDKIM_HDR_VALUE)
831 cur_val = pdkim_strnew(NULL);
833 if (c == ';' || c == '\0')
835 if (cur_tag->len > 0)
837 pdkim_strtrim(cur_val);
838 DEBUG(D_acl) debug_printf(" %s=%s\n", cur_tag->str, cur_val->str);
840 switch (cur_tag->str[0])
843 /* This tag isn't evaluated because:
844 - We only support version DKIM1.
845 - Which is the default for this value (set below)
846 - Other versions are currently not specified. */
849 pub->hashes = strdup(cur_val->str); break;
851 pub->granularity = strdup(cur_val->str); break;
853 pub->notes = pdkim_decode_qp(cur_val->str); break;
855 pdkim_decode_base64(US cur_val->str, &pub->key);
858 pub->hashes = strdup(cur_val->str); break;
860 pub->srvtype = strdup(cur_val->str); break;
862 if (strchr(cur_val->str, 'y') != NULL) pub->testing = 1;
863 if (strchr(cur_val->str, 's') != NULL) pub->no_subdomaining = 1;
866 DEBUG(D_acl) debug_printf(" Unknown tag encountered\n");
870 pdkim_strclear(cur_tag);
871 pdkim_strclear(cur_val);
872 where = PDKIM_HDR_LIMBO;
875 pdkim_strncat(cur_val, p, 1);
879 if (c == '\0') break;
882 /* Set fallback defaults */
883 if (!pub->version ) pub->version = strdup(PDKIM_PUB_RECORD_VERSION);
884 if (!pub->granularity) pub->granularity = strdup("*");
885 if (!pub->keytype ) pub->keytype = strdup("rsa");
886 if (!pub->srvtype ) pub->srvtype = strdup("*");
892 pdkim_free_pubkey(pub);
897 /* -------------------------------------------------------------------------- */
900 pdkim_update_bodyhash(pdkim_ctx *ctx, const char *data, int len)
902 pdkim_signature *sig = ctx->sig;
903 /* Cache relaxed version of data */
904 uschar *relaxed_data = NULL;
907 /* Traverse all signatures, updating their hashes. */
910 /* Defaults to simple canon (no further treatment necessary) */
911 const uschar *canon_data = CUS data;
914 if (sig->canon_body == PDKIM_CANON_RELAXED)
916 /* Relax the line if not done already */
919 BOOL seen_wsp = FALSE;
923 if (!(relaxed_data = malloc(len+1)))
924 return PDKIM_ERR_OOM;
926 for (p = data; *p; p++)
931 if (q > 0 && relaxed_data[q-1] == ' ')
934 else if (c == '\t' || c == ' ')
936 c = ' '; /* Turns WSP into SP */
943 relaxed_data[q++] = c;
945 relaxed_data[q] = '\0';
948 canon_data = relaxed_data;
949 canon_len = relaxed_len;
952 /* Make sure we don't exceed the to-be-signed body length */
953 if ( sig->bodylength >= 0
954 && sig->signed_body_bytes + (unsigned long)canon_len > sig->bodylength
956 canon_len = sig->bodylength - sig->signed_body_bytes;
960 exim_sha_update(&sig->body_hash, CCS canon_data, canon_len);
961 sig->signed_body_bytes += canon_len;
962 DEBUG(D_acl) pdkim_quoteprint(canon_data, canon_len);
968 if (relaxed_data) free(relaxed_data);
973 /* -------------------------------------------------------------------------- */
976 pdkim_finish_bodyhash(pdkim_ctx *ctx)
978 pdkim_signature *sig;
980 /* Traverse all signatures */
981 for (sig = ctx->sig; sig; sig = sig->next)
982 { /* Finish hashes */
985 exim_sha_finish(&sig->body_hash, &bh);
989 debug_printf("PDKIM [%s] Body bytes hashed: %lu\n"
990 "PDKIM [%s] bh computed: ",
991 sig->domain, sig->signed_body_bytes, sig->domain);
992 pdkim_hexprint(CUS bh.data, bh.len);
995 /* SIGNING -------------------------------------------------------------- */
996 if (ctx->mode == PDKIM_MODE_SIGN)
1000 /* If bodylength limit is set, and we have received less bytes
1001 than the requested amount, effectively remove the limit tag. */
1002 if (sig->signed_body_bytes < sig->bodylength)
1003 sig->bodylength = -1;
1006 /* VERIFICATION --------------------------------------------------------- */
1009 /* Compare bodyhash */
1010 if (memcmp(bh.data, sig->bodyhash.data, bh.len) == 0)
1012 DEBUG(D_acl) debug_printf("PDKIM [%s] Body hash verified OK\n", sig->domain);
1018 debug_printf("PDKIM [%s] bh signature: ", sig->domain);
1019 pdkim_hexprint(sig->bodyhash.data,
1020 exim_sha_hashlen(&sig->body_hash));
1021 debug_printf("PDKIM [%s] Body hash did NOT verify\n", sig->domain);
1023 sig->verify_status = PDKIM_VERIFY_FAIL;
1024 sig->verify_ext_status = PDKIM_VERIFY_FAIL_BODY;
1034 /* -------------------------------------------------------------------------- */
1035 /* Callback from pdkim_feed below for processing complete body lines */
1038 pdkim_bodyline_complete(pdkim_ctx *ctx)
1040 char *p = ctx->linebuf;
1041 int n = ctx->linebuf_offset;
1042 pdkim_signature *sig = ctx->sig; /*XXX assumes only one sig */
1044 /* Ignore extra data if we've seen the end-of-data marker */
1045 if (ctx->seen_eod) goto BAIL;
1047 /* We've always got one extra byte to stuff a zero ... */
1048 ctx->linebuf[ctx->linebuf_offset] = '\0';
1050 /* Terminate on EOD marker */
1051 if (memcmp(p, ".\r\n", 3) == 0)
1053 /* In simple body mode, if any empty lines were buffered,
1054 replace with one. rfc 4871 3.4.3 */
1055 /*XXX checking the signed-body-bytes is a gross hack; I think
1056 it indicates that all linebreaks should be buffered, including
1057 the one terminating a text line */
1058 if ( sig && sig->canon_body == PDKIM_CANON_SIMPLE
1059 && sig->signed_body_bytes == 0
1060 && ctx->num_buffered_crlf > 0
1062 pdkim_update_bodyhash(ctx, "\r\n", 2);
1064 ctx->seen_eod = TRUE;
1068 if (memcmp(p, "..", 2) == 0)
1074 /* Empty lines need to be buffered until we find a non-empty line */
1075 if (memcmp(p, "\r\n", 2) == 0)
1077 ctx->num_buffered_crlf++;
1081 if (sig && sig->canon_body == PDKIM_CANON_RELAXED)
1083 /* Lines with just spaces need to be buffered too */
1085 while (memcmp(check, "\r\n", 2) != 0)
1089 if (c != '\t' && c != ' ')
1094 ctx->num_buffered_crlf++;
1099 /* At this point, we have a non-empty line, so release the buffered ones. */
1100 while (ctx->num_buffered_crlf)
1102 pdkim_update_bodyhash(ctx, "\r\n", 2);
1103 ctx->num_buffered_crlf--;
1106 pdkim_update_bodyhash(ctx, p, n);
1109 ctx->linebuf_offset = 0;
1114 /* -------------------------------------------------------------------------- */
1115 /* Callback from pdkim_feed below for processing complete headers */
1116 #define DKIM_SIGNATURE_HEADERNAME "DKIM-Signature:"
1119 pdkim_header_complete(pdkim_ctx *ctx)
1121 /* Special case: The last header can have an extra \r appended */
1122 if ( (ctx->cur_header->len > 1) &&
1123 (ctx->cur_header->str[(ctx->cur_header->len)-1] == '\r') )
1125 ctx->cur_header->str[(ctx->cur_header->len)-1] = '\0';
1126 ctx->cur_header->len--;
1130 if (ctx->num_headers > PDKIM_MAX_HEADERS) goto BAIL;
1132 /* SIGNING -------------------------------------------------------------- */
1133 if (ctx->mode == PDKIM_MODE_SIGN)
1135 pdkim_signature *sig;
1137 for (sig = ctx->sig; sig; sig = sig->next) /* Traverse all signatures */
1139 pdkim_stringlist *list;
1141 /* Add header to the signed headers list (in reverse order) */
1142 if (!(list = pdkim_prepend_stringlist(sig->headers,
1143 ctx->cur_header->str)))
1144 return PDKIM_ERR_OOM;
1145 sig->headers = list;
1149 /* VERIFICATION ----------------------------------------------------------- */
1150 /* DKIM-Signature: headers are added to the verification list */
1151 if (ctx->mode == PDKIM_MODE_VERIFY)
1153 if (strncasecmp(ctx->cur_header->str,
1154 DKIM_SIGNATURE_HEADERNAME,
1155 strlen(DKIM_SIGNATURE_HEADERNAME)) == 0)
1157 pdkim_signature *new_sig;
1159 /* Create and chain new signature block */
1160 DEBUG(D_acl) debug_printf(
1161 "PDKIM >> Found sig, trying to parse >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1163 if ((new_sig = pdkim_parse_sig_header(ctx, ctx->cur_header->str)))
1165 pdkim_signature *last_sig = ctx->sig;
1170 while (last_sig->next) last_sig = last_sig->next;
1171 last_sig->next = new_sig;
1175 DEBUG(D_acl) debug_printf(
1176 "Error while parsing signature header\n"
1177 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1180 /* every other header is stored for signature verification */
1183 pdkim_stringlist *list;
1185 if (!(list = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->str)))
1186 return PDKIM_ERR_OOM;
1187 ctx->headers = list;
1192 pdkim_strclear(ctx->cur_header); /* Re-use existing pdkim_str */
1198 /* -------------------------------------------------------------------------- */
1199 #define HEADER_BUFFER_FRAG_SIZE 256
1202 pdkim_feed (pdkim_ctx *ctx, char *data, int len)
1206 for (p = 0; p<len; p++)
1210 if (ctx->past_headers)
1212 /* Processing body byte */
1213 ctx->linebuf[ctx->linebuf_offset++] = c;
1216 int rc = pdkim_bodyline_complete(ctx); /* End of line */
1217 if (rc != PDKIM_OK) return rc;
1219 if (ctx->linebuf_offset == (PDKIM_MAX_BODY_LINE_LEN-1))
1220 return PDKIM_ERR_LONG_LINE;
1224 /* Processing header byte */
1231 int rc = pdkim_header_complete(ctx); /* Seen last header line */
1232 if (rc != PDKIM_OK) return rc;
1234 ctx->past_headers = TRUE;
1236 DEBUG(D_acl) debug_printf(
1237 "PDKIM >> Body data for hash, canonicalized >>>>>>>>>>>>>>>>>>>>>>\n");
1241 ctx->seen_lf = TRUE;
1243 else if (ctx->seen_lf)
1245 if (!(c == '\t' || c == ' '))
1247 int rc = pdkim_header_complete(ctx); /* End of header */
1248 if (rc != PDKIM_OK) return rc;
1250 ctx->seen_lf = FALSE;
1254 if (!ctx->cur_header)
1255 if (!(ctx->cur_header = pdkim_strnew(NULL)))
1256 return PDKIM_ERR_OOM;
1258 if (ctx->cur_header->len < PDKIM_MAX_HEADER_LEN)
1259 if (!pdkim_strncat(ctx->cur_header, &data[p], 1))
1260 return PDKIM_ERR_OOM;
1267 * RFC 5322 specifies that header line length SHOULD be no more than 78
1272 * col: this int holds and receives column number (octets since last '\n')
1273 * str: partial string to append to
1274 * pad: padding, split line or space after before or after eg: ";"
1275 * intro: - must join to payload eg "h=", usually the tag name
1276 * payload: eg base64 data - long data can be split arbitrarily.
1278 * this code doesn't fold the header in some of the places that RFC4871
1279 * allows: As per RFC5322(2.2.3) it only folds before or after tag-value
1280 * pairs and inside long values. it also always spaces or breaks after the
1283 * no guarantees are made for output given out-of range input. like tag
1284 * names longer than 78, or bogus col. Input is assumed to be free of line breaks.
1288 pdkim_headcat(int *col, pdkim_str *str, const char * pad,
1289 const char *intro, const char *payload)
1298 pdkim_strcat(str, "\r\n\t");
1301 pdkim_strncat(str, pad, l);
1305 l = (pad?1:0) + (intro?strlen(intro):0);
1308 { /*can't fit intro - start a new line to make room.*/
1309 pdkim_strcat(str, "\r\n\t");
1311 l = intro?strlen(intro):0;
1314 l += payload ? strlen(payload):0 ;
1317 { /* this fragment will not fit on a single line */
1320 pdkim_strcat(str, " ");
1322 pad = NULL; /* only want this once */
1328 size_t sl = strlen(intro);
1330 pdkim_strncat(str, intro, sl);
1333 intro = NULL; /* only want this once */
1338 size_t sl = strlen(payload);
1339 size_t chomp = *col+sl < 77 ? sl : 78-*col;
1341 pdkim_strncat(str, payload, chomp);
1347 /* the while precondition tells us it didn't fit. */
1348 pdkim_strcat(str, "\r\n\t");
1354 pdkim_strcat(str, "\r\n\t");
1361 pdkim_strcat(str, " ");
1368 size_t sl = strlen(intro);
1370 pdkim_strncat(str, intro, sl);
1378 size_t sl = strlen(payload);
1380 pdkim_strncat(str, payload, sl);
1388 /* -------------------------------------------------------------------------- */
1391 pdkim_create_header(pdkim_signature *sig, BOOL final)
1394 char *base64_bh = NULL;
1395 char *base64_b = NULL;
1398 pdkim_str *canon_all;
1400 if (!(hdr = pdkim_strnew("DKIM-Signature: v="PDKIM_SIGNATURE_VERSION)))
1403 if (!(canon_all = pdkim_strnew(pdkim_canons[sig->canon_headers])))
1406 if (!(base64_bh = pdkim_encode_base64(&sig->bodyhash)))
1409 col = strlen(hdr->str);
1411 /* Required and static bits */
1412 if ( pdkim_headcat(&col, hdr, ";", "a=", pdkim_algos[sig->algo])
1413 && pdkim_headcat(&col, hdr, ";", "q=", pdkim_querymethods[sig->querymethod])
1414 && pdkim_strcat(canon_all, "/")
1415 && pdkim_strcat(canon_all, pdkim_canons[sig->canon_body])
1416 && pdkim_headcat(&col, hdr, ";", "c=", canon_all->str)
1417 && pdkim_headcat(&col, hdr, ";", "d=", sig->domain)
1418 && pdkim_headcat(&col, hdr, ";", "s=", sig->selector)
1421 /* list of header names can be split between items. */
1423 char *n = CS string_copy(sig->headernames);
1430 char *c = strchr(n, ':');
1435 if (!pdkim_headcat(&col, hdr, NULL, NULL, ":"))
1440 if (!pdkim_headcat(&col, hdr, s, i, n))
1454 if(!pdkim_headcat(&col, hdr, ";", "bh=", base64_bh))
1459 if(!pdkim_headcat(&col, hdr, ";", "i=", sig->identity))
1462 if (sig->created > 0)
1466 snprintf(minibuf, 20, "%lu", sig->created);
1467 if(!pdkim_headcat(&col, hdr, ";", "t=", minibuf))
1471 if (sig->expires > 0)
1475 snprintf(minibuf, 20, "%lu", sig->expires);
1476 if(!pdkim_headcat(&col, hdr, ";", "x=", minibuf))
1480 if (sig->bodylength >= 0)
1484 snprintf(minibuf, 20, "%lu", sig->bodylength);
1485 if(!pdkim_headcat(&col, hdr, ";", "l=", minibuf))
1489 /* Preliminary or final version? */
1492 if (!(base64_b = pdkim_encode_base64(&sig->sigdata)))
1494 if (!pdkim_headcat(&col, hdr, ";", "b=", base64_b))
1498 if(!pdkim_headcat(&col, hdr, ";", "b=", ""))
1501 /* add trailing semicolon: I'm not sure if this is actually needed */
1502 if (!pdkim_headcat(&col, hdr, NULL, ";", ""))
1506 rc = strdup(hdr->str);
1510 if (canon_all) pdkim_strfree(canon_all);
1515 /* -------------------------------------------------------------------------- */
1518 pdkim_feed_finish(pdkim_ctx *ctx, pdkim_signature **return_signatures)
1520 pdkim_signature *sig = ctx->sig;
1521 pdkim_str *headernames = NULL; /* Collected signed header names */
1523 /* Check if we must still flush a (partial) header. If that is the
1524 case, the message has no body, and we must compute a body hash
1525 out of '<CR><LF>' */
1526 if (ctx->cur_header && ctx->cur_header->len)
1528 int rc = pdkim_header_complete(ctx);
1529 if (rc != PDKIM_OK) return rc;
1530 pdkim_update_bodyhash(ctx, "\r\n", 2);
1533 DEBUG(D_acl) debug_printf(
1534 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1536 /* Build (and/or evaluate) body hash */
1537 if (pdkim_finish_bodyhash(ctx) != PDKIM_OK)
1538 return PDKIM_ERR_OOM;
1540 /* SIGNING -------------------------------------------------------------- */
1541 if (ctx->mode == PDKIM_MODE_SIGN)
1542 if (!(headernames = pdkim_strnew(NULL)))
1543 return PDKIM_ERR_OOM;
1544 /* ---------------------------------------------------------------------- */
1548 BOOL is_sha1 = sig->algo == PDKIM_ALGO_RSA_SHA1;
1553 int hdata_alloc = 0;
1558 exim_sha_init(&hhash_ctx, is_sha1);
1560 DEBUG(D_acl) debug_printf(
1561 "PDKIM >> Hashed header data, canonicalized, in sequence >>>>>>>>>>>>>>\n");
1563 /* SIGNING ---------------------------------------------------------------- */
1564 /* When signing, walk through our header list and add them to the hash. As we
1565 go, construct a list of the header's names to use for the h= parameter.
1566 Then append to that list any remaining header names for which there was no
1569 if (ctx->mode == PDKIM_MODE_SIGN)
1571 pdkim_stringlist *p;
1576 for (p = sig->headers; p; p = p->next)
1577 if (header_name_match(p->value, sig->sign_headers) == PDKIM_OK)
1580 /* Collect header names (Note: colon presence is guaranteed here) */
1581 uschar * q = Ustrchr(p->value, ':');
1583 if (!(pdkim_strncat(headernames, p->value,
1584 (q - US p->value) + (p->next ? 1 : 0))))
1585 return PDKIM_ERR_OOM;
1587 rh = sig->canon_headers == PDKIM_CANON_RELAXED
1588 ? US pdkim_relax_header(p->value, 1) /* cook header for relaxed canon */
1589 : string_copy(CUS p->value); /* just copy it for simple canon */
1591 return PDKIM_ERR_OOM;
1593 /* Feed header to the hash algorithm */
1594 exim_sha_update(&hhash_ctx, CCS rh, Ustrlen(rh));
1596 /* Remember headers block for signing (when the library cannot do incremental) */
1597 (void) exim_rsa_data_append(&hdata, &hdata_alloc, rh);
1599 DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1602 l = US sig->sign_headers;
1603 while((s = string_nextinlist(&l, &sep, NULL, 0)))
1605 { /*SSS string_append_listele() */
1606 if (headernames->len > 0 && headernames->str[headernames->len-1] != ':')
1607 if (!(pdkim_strncat(headernames, ":", 1)))
1608 return PDKIM_ERR_OOM;
1609 if (!(pdkim_strncat(headernames, CS s, Ustrlen(s))))
1610 return PDKIM_ERR_OOM;
1614 /* VERIFICATION ----------------------------------------------------------- */
1615 /* When verifying, walk through the header name list in the h= parameter and
1616 add the headers to the hash in that order. */
1619 uschar * b = string_copy(sig->headernames);
1622 pdkim_stringlist * hdrs;
1624 if (!b) return PDKIM_ERR_OOM;
1627 for (hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1632 if ((q = Ustrchr(p, ':')))
1635 /*XXX walk the list of headers in same order as received. */
1636 for (hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1638 && strncasecmp(hdrs->value, CS p, Ustrlen(p)) == 0
1639 && (hdrs->value)[Ustrlen(p)] == ':'
1642 uschar * rh = sig->canon_headers == PDKIM_CANON_RELAXED
1643 ? US pdkim_relax_header(hdrs->value, 1) /* cook header for relaxed canon */
1644 : string_copy(CUS hdrs->value); /* just copy it for simple canon */
1646 return PDKIM_ERR_OOM;
1648 /* Feed header to the hash algorithm */
1649 exim_sha_update(&hhash_ctx, CCS rh, Ustrlen(rh));
1651 DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1661 DEBUG(D_acl) debug_printf(
1662 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1664 /* SIGNING ---------------------------------------------------------------- */
1665 if (ctx->mode == PDKIM_MODE_SIGN)
1667 /* Copy headernames to signature struct */
1668 sig->headernames = string_copy(US headernames->str);
1669 pdkim_strfree(headernames);
1671 /* Create signature header with b= omitted */
1672 sig_hdr = pdkim_create_header(sig, FALSE);
1675 /* VERIFICATION ----------------------------------------------------------- */
1677 sig_hdr = strdup(sig->rawsig_no_b_val);
1678 /* ------------------------------------------------------------------------ */
1681 return PDKIM_ERR_OOM;
1683 /* Relax header if necessary */
1684 if (sig->canon_headers == PDKIM_CANON_RELAXED)
1686 char *relaxed_hdr = pdkim_relax_header(sig_hdr, 0);
1690 return PDKIM_ERR_OOM;
1691 sig_hdr = relaxed_hdr;
1697 "PDKIM >> Signed DKIM-Signature header, canonicalized >>>>>>>>>>>>>>>>>\n");
1698 pdkim_quoteprint(CUS sig_hdr, strlen(sig_hdr));
1700 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1703 /* Finalize header hash */
1704 exim_sha_update(&hhash_ctx, sig_hdr, strlen(sig_hdr));
1705 exim_sha_finish(&hhash_ctx, &hhash);
1709 debug_printf("PDKIM [%s] hh computed: ", sig->domain);
1710 pdkim_hexprint(hhash.data, hhash.len);
1713 /* Remember headers block for signing (when the library cannot do incremental) */
1714 if (ctx->mode == PDKIM_MODE_SIGN)
1715 (void) exim_rsa_data_append(&hdata, &hdata_alloc, US sig_hdr);
1719 /* SIGNING ---------------------------------------------------------------- */
1720 if (ctx->mode == PDKIM_MODE_SIGN)
1723 const uschar * errstr;
1725 /* Import private key */
1726 if ((errstr = exim_rsa_signing_init(US sig->rsa_privkey, &sctx)))
1728 DEBUG(D_acl) debug_printf("signing_init: %s\n", errstr);
1729 return PDKIM_ERR_RSA_PRIVKEY;
1732 /* Do signing. With OpenSSL we are signing the hash of headers just
1733 calculated, with GnuTLS we have to sign an entire block of headers
1734 (due to available interfaces) and it recalculates the hash internally. */
1736 #if defined(RSA_OPENSSL) || defined(RSA_GCRYPT)
1740 if ((errstr = exim_rsa_sign(&sctx, is_sha1, &hdata, &sig->sigdata)))
1742 DEBUG(D_acl) debug_printf("signing: %s\n", errstr);
1743 return PDKIM_ERR_RSA_SIGNING;
1748 debug_printf( "PDKIM [%s] b computed: ", sig->domain);
1749 pdkim_hexprint(sig->sigdata.data, sig->sigdata.len);
1752 if (!(sig->signature_header = pdkim_create_header(sig, TRUE)))
1753 return PDKIM_ERR_OOM;
1755 /* We only ever sign with one sig, and we free'd "headernames"
1756 above. So to keep static-analysers happy, exit the loop explicitly.
1757 Perhaps the code would be more clear if signing and verification
1758 loops were separated? */
1763 /* VERIFICATION ----------------------------------------------------------- */
1767 const uschar * errstr;
1769 char *dns_txt_name, *dns_txt_reply;
1771 /* Fetch public key for signing domain, from DNS */
1773 if (!(dns_txt_name = malloc(PDKIM_DNS_TXT_MAX_NAMELEN)))
1774 return PDKIM_ERR_OOM;
1776 if (!(dns_txt_reply = malloc(PDKIM_DNS_TXT_MAX_RECLEN)))
1779 return PDKIM_ERR_OOM;
1782 memset(dns_txt_reply, 0, PDKIM_DNS_TXT_MAX_RECLEN);
1783 memset(dns_txt_name , 0, PDKIM_DNS_TXT_MAX_NAMELEN);
1785 if (snprintf(dns_txt_name, PDKIM_DNS_TXT_MAX_NAMELEN,
1786 "%s._domainkey.%s.",
1787 sig->selector, sig->domain) >= PDKIM_DNS_TXT_MAX_NAMELEN)
1789 sig->verify_status = PDKIM_VERIFY_INVALID;
1790 sig->verify_ext_status = PDKIM_VERIFY_INVALID_BUFFER_SIZE;
1794 if ( ctx->dns_txt_callback(dns_txt_name, dns_txt_reply) != PDKIM_OK
1795 || dns_txt_reply[0] == '\0')
1797 sig->verify_status = PDKIM_VERIFY_INVALID;
1798 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE;
1805 "PDKIM >> Parsing public key record >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"
1807 pdkim_quoteprint(CUS dns_txt_reply, strlen(dns_txt_reply));
1810 if (!(sig->pubkey = pdkim_parse_pubkey_record(ctx, dns_txt_reply)))
1812 sig->verify_status = PDKIM_VERIFY_INVALID;
1813 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD;
1815 DEBUG(D_acl) debug_printf(
1816 " Error while parsing public key record\n"
1817 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1821 DEBUG(D_acl) debug_printf(
1822 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1824 /* Import public key */
1825 if ((errstr = exim_rsa_verify_init(&sig->pubkey->key, &vctx)))
1827 DEBUG(D_acl) debug_printf("verify_init: %s\n", errstr);
1828 sig->verify_status = PDKIM_VERIFY_INVALID;
1829 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
1833 /* Check the signature */
1834 if ((errstr = exim_rsa_verify(&vctx, is_sha1, &hhash, &sig->sigdata)))
1836 DEBUG(D_acl) debug_printf("headers verify: %s\n", errstr);
1837 sig->verify_status = PDKIM_VERIFY_FAIL;
1838 sig->verify_ext_status = PDKIM_VERIFY_FAIL_MESSAGE;
1843 /* We have a winner! (if bodydhash was correct earlier) */
1844 if (sig->verify_status == PDKIM_VERIFY_NONE)
1845 sig->verify_status = PDKIM_VERIFY_PASS;
1851 debug_printf("PDKIM [%s] signature status: %s",
1852 sig->domain, pdkim_verify_status_str(sig->verify_status));
1853 if (sig->verify_ext_status > 0)
1854 debug_printf(" (%s)\n",
1855 pdkim_verify_ext_status_str(sig->verify_ext_status));
1861 free(dns_txt_reply);
1867 /* If requested, set return pointer to signature(s) */
1868 if (return_signatures)
1869 *return_signatures = ctx->sig;
1875 /* -------------------------------------------------------------------------- */
1877 DLLEXPORT pdkim_ctx *
1878 pdkim_init_verify(int(*dns_txt_callback)(char *, char *))
1880 pdkim_ctx *ctx = malloc(sizeof(pdkim_ctx));
1884 memset(ctx, 0, sizeof(pdkim_ctx));
1886 if (!(ctx->linebuf = malloc(PDKIM_MAX_BODY_LINE_LEN)))
1892 ctx->mode = PDKIM_MODE_VERIFY;
1893 ctx->dns_txt_callback = dns_txt_callback;
1899 /* -------------------------------------------------------------------------- */
1901 DLLEXPORT pdkim_ctx *
1902 pdkim_init_sign(char *domain, char *selector, char *rsa_privkey, int algo)
1905 pdkim_signature *sig;
1907 if (!domain || !selector || !rsa_privkey)
1910 if (!(ctx = malloc(sizeof(pdkim_ctx))))
1912 memset(ctx, 0, sizeof(pdkim_ctx));
1914 if (!(ctx->linebuf = malloc(PDKIM_MAX_BODY_LINE_LEN)))
1920 if (!(sig = malloc(sizeof(pdkim_signature))))
1926 memset(sig, 0, sizeof(pdkim_signature));
1928 sig->bodylength = -1;
1930 ctx->mode = PDKIM_MODE_SIGN;
1933 sig->domain = strdup(domain);
1934 sig->selector = strdup(selector);
1935 sig->rsa_privkey = strdup(rsa_privkey);
1938 if (!sig->domain || !sig->selector || !sig->rsa_privkey)
1941 exim_sha_init(&sig->body_hash, algo == PDKIM_ALGO_RSA_SHA1);
1945 pdkim_free_ctx(ctx);
1950 /* -------------------------------------------------------------------------- */
1953 pdkim_set_optional(pdkim_ctx *ctx,
1959 unsigned long created,
1960 unsigned long expires)
1962 pdkim_signature * sig = ctx->sig;
1965 if (!(sig->identity = strdup(identity)))
1966 return PDKIM_ERR_OOM;
1968 if (!(sig->sign_headers = strdup(sign_headers
1969 ? sign_headers : PDKIM_DEFAULT_SIGN_HEADERS)))
1970 return PDKIM_ERR_OOM;
1972 sig->canon_headers = canon_headers;
1973 sig->canon_body = canon_body;
1974 sig->bodylength = bodylength;
1975 sig->created = created;
1976 sig->expires = expires;
1990 #endif /*DISABLE_DKIM*/