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. */
764 while (q > sig->rawsig_no_b_val && (*q == '\r' || *q == '\n'))
765 *q = '\0'; q--; /*XXX questionable code layout; possible bug */
770 "PDKIM >> Raw signature w/o b= tag value >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
771 pdkim_quoteprint(US sig->rawsig_no_b_val, strlen(sig->rawsig_no_b_val));
773 "PDKIM >> Sig size: %4u bits\n", (unsigned) sig->sigdata.len*8);
775 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
778 exim_sha_init(&sig->body_hash, sig->algo == PDKIM_ALGO_RSA_SHA1);
783 /* -------------------------------------------------------------------------- */
785 static pdkim_pubkey *
786 pdkim_parse_pubkey_record(pdkim_ctx *ctx, char *raw_record)
790 pdkim_str *cur_tag = NULL;
791 pdkim_str *cur_val = NULL;
792 int where = PDKIM_HDR_LIMBO;
794 if (!(pub = malloc(sizeof(pdkim_pubkey)))) return NULL;
795 memset(pub, 0, sizeof(pdkim_pubkey));
797 for (p = raw_record; ; p++)
802 if (c == '\r' || c == '\n')
805 if (where == PDKIM_HDR_LIMBO)
807 /* In limbo, just wait for a tag-char to appear */
808 if (!(c >= 'a' && c <= 'z'))
811 where = PDKIM_HDR_TAG;
814 if (where == PDKIM_HDR_TAG)
817 cur_tag = pdkim_strnew(NULL);
819 if (c >= 'a' && c <= 'z')
820 pdkim_strncat(cur_tag, p, 1);
824 where = PDKIM_HDR_VALUE;
829 if (where == PDKIM_HDR_VALUE)
832 cur_val = pdkim_strnew(NULL);
834 if (c == ';' || c == '\0')
836 if (cur_tag->len > 0)
838 pdkim_strtrim(cur_val);
839 DEBUG(D_acl) debug_printf(" %s=%s\n", cur_tag->str, cur_val->str);
841 switch (cur_tag->str[0])
844 /* This tag isn't evaluated because:
845 - We only support version DKIM1.
846 - Which is the default for this value (set below)
847 - Other versions are currently not specified. */
850 pub->hashes = strdup(cur_val->str); break;
852 pub->granularity = strdup(cur_val->str); break;
854 pub->notes = pdkim_decode_qp(cur_val->str); break;
856 pdkim_decode_base64(US cur_val->str, &pub->key);
859 pub->hashes = strdup(cur_val->str); break;
861 pub->srvtype = strdup(cur_val->str); break;
863 if (strchr(cur_val->str, 'y') != NULL) pub->testing = 1;
864 if (strchr(cur_val->str, 's') != NULL) pub->no_subdomaining = 1;
867 DEBUG(D_acl) debug_printf(" Unknown tag encountered\n");
871 pdkim_strclear(cur_tag);
872 pdkim_strclear(cur_val);
873 where = PDKIM_HDR_LIMBO;
876 pdkim_strncat(cur_val, p, 1);
880 if (c == '\0') break;
883 /* Set fallback defaults */
884 if (!pub->version ) pub->version = strdup(PDKIM_PUB_RECORD_VERSION);
885 if (!pub->granularity) pub->granularity = strdup("*");
886 if (!pub->keytype ) pub->keytype = strdup("rsa");
887 if (!pub->srvtype ) pub->srvtype = strdup("*");
893 pdkim_free_pubkey(pub);
898 /* -------------------------------------------------------------------------- */
901 pdkim_update_bodyhash(pdkim_ctx *ctx, const char *data, int len)
903 pdkim_signature *sig = ctx->sig;
904 /* Cache relaxed version of data */
905 uschar *relaxed_data = NULL;
908 /* Traverse all signatures, updating their hashes. */
911 /* Defaults to simple canon (no further treatment necessary) */
912 const uschar *canon_data = CUS data;
915 if (sig->canon_body == PDKIM_CANON_RELAXED)
917 /* Relax the line if not done already */
920 BOOL seen_wsp = FALSE;
924 if (!(relaxed_data = malloc(len+1)))
925 return PDKIM_ERR_OOM;
927 for (p = data; *p; p++)
932 if (q > 0 && relaxed_data[q-1] == ' ')
935 else if (c == '\t' || c == ' ')
937 c = ' '; /* Turns WSP into SP */
944 relaxed_data[q++] = c;
946 relaxed_data[q] = '\0';
949 canon_data = relaxed_data;
950 canon_len = relaxed_len;
953 /* Make sure we don't exceed the to-be-signed body length */
954 if ( sig->bodylength >= 0
955 && sig->signed_body_bytes + (unsigned long)canon_len > sig->bodylength
957 canon_len = sig->bodylength - sig->signed_body_bytes;
961 exim_sha_update(&sig->body_hash, CCS canon_data, canon_len);
962 sig->signed_body_bytes += canon_len;
963 DEBUG(D_acl) pdkim_quoteprint(canon_data, canon_len);
969 if (relaxed_data) free(relaxed_data);
974 /* -------------------------------------------------------------------------- */
977 pdkim_finish_bodyhash(pdkim_ctx *ctx)
979 pdkim_signature *sig;
981 /* Traverse all signatures */
982 for (sig = ctx->sig; sig; sig = sig->next)
983 { /* Finish hashes */
986 exim_sha_finish(&sig->body_hash, &bh);
990 debug_printf("PDKIM [%s] Body bytes hashed: %lu\n"
991 "PDKIM [%s] bh computed: ",
992 sig->domain, sig->signed_body_bytes, sig->domain);
993 pdkim_hexprint(CUS bh.data, bh.len);
996 /* SIGNING -------------------------------------------------------------- */
997 if (ctx->mode == PDKIM_MODE_SIGN)
1001 /* If bodylength limit is set, and we have received less bytes
1002 than the requested amount, effectively remove the limit tag. */
1003 if (sig->signed_body_bytes < sig->bodylength)
1004 sig->bodylength = -1;
1007 /* VERIFICATION --------------------------------------------------------- */
1010 /* Compare bodyhash */
1011 if (memcmp(bh.data, sig->bodyhash.data, bh.len) == 0)
1013 DEBUG(D_acl) debug_printf("PDKIM [%s] Body hash verified OK\n", sig->domain);
1019 debug_printf("PDKIM [%s] bh signature: ", sig->domain);
1020 pdkim_hexprint(sig->bodyhash.data,
1021 exim_sha_hashlen(&sig->body_hash));
1022 debug_printf("PDKIM [%s] Body hash did NOT verify\n", sig->domain);
1024 sig->verify_status = PDKIM_VERIFY_FAIL;
1025 sig->verify_ext_status = PDKIM_VERIFY_FAIL_BODY;
1035 /* -------------------------------------------------------------------------- */
1036 /* Callback from pdkim_feed below for processing complete body lines */
1039 pdkim_bodyline_complete(pdkim_ctx *ctx)
1041 char *p = ctx->linebuf;
1042 int n = ctx->linebuf_offset;
1043 pdkim_signature *sig = ctx->sig; /*XXX assumes only one sig */
1045 /* Ignore extra data if we've seen the end-of-data marker */
1046 if (ctx->seen_eod) goto BAIL;
1048 /* We've always got one extra byte to stuff a zero ... */
1049 ctx->linebuf[ctx->linebuf_offset] = '\0';
1051 /* Terminate on EOD marker */
1052 if (memcmp(p, ".\r\n", 3) == 0)
1054 /* In simple body mode, if any empty lines were buffered,
1055 replace with one. rfc 4871 3.4.3 */
1056 /*XXX checking the signed-body-bytes is a gross hack; I think
1057 it indicates that all linebreaks should be buffered, including
1058 the one terminating a text line */
1059 if ( sig && sig->canon_body == PDKIM_CANON_SIMPLE
1060 && sig->signed_body_bytes == 0
1061 && ctx->num_buffered_crlf > 0
1063 pdkim_update_bodyhash(ctx, "\r\n", 2);
1065 ctx->seen_eod = TRUE;
1069 if (memcmp(p, "..", 2) == 0)
1075 /* Empty lines need to be buffered until we find a non-empty line */
1076 if (memcmp(p, "\r\n", 2) == 0)
1078 ctx->num_buffered_crlf++;
1082 if (sig && sig->canon_body == PDKIM_CANON_RELAXED)
1084 /* Lines with just spaces need to be buffered too */
1086 while (memcmp(check, "\r\n", 2) != 0)
1090 if (c != '\t' && c != ' ')
1095 ctx->num_buffered_crlf++;
1100 /* At this point, we have a non-empty line, so release the buffered ones. */
1101 while (ctx->num_buffered_crlf)
1103 pdkim_update_bodyhash(ctx, "\r\n", 2);
1104 ctx->num_buffered_crlf--;
1107 pdkim_update_bodyhash(ctx, p, n);
1110 ctx->linebuf_offset = 0;
1115 /* -------------------------------------------------------------------------- */
1116 /* Callback from pdkim_feed below for processing complete headers */
1117 #define DKIM_SIGNATURE_HEADERNAME "DKIM-Signature:"
1120 pdkim_header_complete(pdkim_ctx *ctx)
1122 /* Special case: The last header can have an extra \r appended */
1123 if ( (ctx->cur_header->len > 1) &&
1124 (ctx->cur_header->str[(ctx->cur_header->len)-1] == '\r') )
1126 ctx->cur_header->str[(ctx->cur_header->len)-1] = '\0';
1127 ctx->cur_header->len--;
1131 if (ctx->num_headers > PDKIM_MAX_HEADERS) goto BAIL;
1133 /* SIGNING -------------------------------------------------------------- */
1134 if (ctx->mode == PDKIM_MODE_SIGN)
1136 pdkim_signature *sig;
1138 for (sig = ctx->sig; sig; sig = sig->next) /* Traverse all signatures */
1140 pdkim_stringlist *list;
1142 /* Add header to the signed headers list (in reverse order) */
1143 if (!(list = pdkim_prepend_stringlist(sig->headers,
1144 ctx->cur_header->str)))
1145 return PDKIM_ERR_OOM;
1146 sig->headers = list;
1150 /* VERIFICATION ----------------------------------------------------------- */
1151 /* DKIM-Signature: headers are added to the verification list */
1152 if (ctx->mode == PDKIM_MODE_VERIFY)
1154 if (strncasecmp(ctx->cur_header->str,
1155 DKIM_SIGNATURE_HEADERNAME,
1156 strlen(DKIM_SIGNATURE_HEADERNAME)) == 0)
1158 pdkim_signature *new_sig;
1160 /* Create and chain new signature block */
1161 DEBUG(D_acl) debug_printf(
1162 "PDKIM >> Found sig, trying to parse >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1164 if ((new_sig = pdkim_parse_sig_header(ctx, ctx->cur_header->str)))
1166 pdkim_signature *last_sig = ctx->sig;
1171 while (last_sig->next) last_sig = last_sig->next;
1172 last_sig->next = new_sig;
1176 DEBUG(D_acl) debug_printf(
1177 "Error while parsing signature header\n"
1178 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1181 /* every other header is stored for signature verification */
1184 pdkim_stringlist *list;
1186 if (!(list = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->str)))
1187 return PDKIM_ERR_OOM;
1188 ctx->headers = list;
1193 pdkim_strclear(ctx->cur_header); /* Re-use existing pdkim_str */
1199 /* -------------------------------------------------------------------------- */
1200 #define HEADER_BUFFER_FRAG_SIZE 256
1203 pdkim_feed (pdkim_ctx *ctx, char *data, int len)
1207 for (p = 0; p<len; p++)
1211 if (ctx->past_headers)
1213 /* Processing body byte */
1214 ctx->linebuf[ctx->linebuf_offset++] = c;
1217 int rc = pdkim_bodyline_complete(ctx); /* End of line */
1218 if (rc != PDKIM_OK) return rc;
1220 if (ctx->linebuf_offset == (PDKIM_MAX_BODY_LINE_LEN-1))
1221 return PDKIM_ERR_LONG_LINE;
1225 /* Processing header byte */
1232 int rc = pdkim_header_complete(ctx); /* Seen last header line */
1233 if (rc != PDKIM_OK) return rc;
1235 ctx->past_headers = TRUE;
1237 DEBUG(D_acl) debug_printf(
1238 "PDKIM >> Body data for hash, canonicalized >>>>>>>>>>>>>>>>>>>>>>\n");
1242 ctx->seen_lf = TRUE;
1244 else if (ctx->seen_lf)
1246 if (!(c == '\t' || c == ' '))
1248 int rc = pdkim_header_complete(ctx); /* End of header */
1249 if (rc != PDKIM_OK) return rc;
1251 ctx->seen_lf = FALSE;
1255 if (!ctx->cur_header)
1256 if (!(ctx->cur_header = pdkim_strnew(NULL)))
1257 return PDKIM_ERR_OOM;
1259 if (ctx->cur_header->len < PDKIM_MAX_HEADER_LEN)
1260 if (!pdkim_strncat(ctx->cur_header, &data[p], 1))
1261 return PDKIM_ERR_OOM;
1268 * RFC 5322 specifies that header line length SHOULD be no more than 78
1273 * col: this int holds and receives column number (octets since last '\n')
1274 * str: partial string to append to
1275 * pad: padding, split line or space after before or after eg: ";"
1276 * intro: - must join to payload eg "h=", usually the tag name
1277 * payload: eg base64 data - long data can be split arbitrarily.
1279 * this code doesn't fold the header in some of the places that RFC4871
1280 * allows: As per RFC5322(2.2.3) it only folds before or after tag-value
1281 * pairs and inside long values. it also always spaces or breaks after the
1284 * no guarantees are made for output given out-of range input. like tag
1285 * names longer than 78, or bogus col. Input is assumed to be free of line breaks.
1289 pdkim_headcat(int *col, pdkim_str *str, const char * pad,
1290 const char *intro, const char *payload)
1299 pdkim_strcat(str, "\r\n\t");
1302 pdkim_strncat(str, pad, l);
1306 l = (pad?1:0) + (intro?strlen(intro):0);
1309 { /*can't fit intro - start a new line to make room.*/
1310 pdkim_strcat(str, "\r\n\t");
1312 l = intro?strlen(intro):0;
1315 l += payload ? strlen(payload):0 ;
1318 { /* this fragment will not fit on a single line */
1321 pdkim_strcat(str, " ");
1323 pad = NULL; /* only want this once */
1329 size_t sl = strlen(intro);
1331 pdkim_strncat(str, intro, sl);
1334 intro = NULL; /* only want this once */
1339 size_t sl = strlen(payload);
1340 size_t chomp = *col+sl < 77 ? sl : 78-*col;
1342 pdkim_strncat(str, payload, chomp);
1348 /* the while precondition tells us it didn't fit. */
1349 pdkim_strcat(str, "\r\n\t");
1355 pdkim_strcat(str, "\r\n\t");
1362 pdkim_strcat(str, " ");
1369 size_t sl = strlen(intro);
1371 pdkim_strncat(str, intro, sl);
1379 size_t sl = strlen(payload);
1381 pdkim_strncat(str, payload, sl);
1389 /* -------------------------------------------------------------------------- */
1392 pdkim_create_header(pdkim_signature *sig, BOOL final)
1395 char *base64_bh = NULL;
1396 char *base64_b = NULL;
1399 pdkim_str *canon_all;
1401 if (!(hdr = pdkim_strnew("DKIM-Signature: v="PDKIM_SIGNATURE_VERSION)))
1404 if (!(canon_all = pdkim_strnew(pdkim_canons[sig->canon_headers])))
1407 if (!(base64_bh = pdkim_encode_base64(&sig->bodyhash)))
1410 col = strlen(hdr->str);
1412 /* Required and static bits */
1413 if ( pdkim_headcat(&col, hdr, ";", "a=", pdkim_algos[sig->algo])
1414 && pdkim_headcat(&col, hdr, ";", "q=", pdkim_querymethods[sig->querymethod])
1415 && pdkim_strcat(canon_all, "/")
1416 && pdkim_strcat(canon_all, pdkim_canons[sig->canon_body])
1417 && pdkim_headcat(&col, hdr, ";", "c=", canon_all->str)
1418 && pdkim_headcat(&col, hdr, ";", "d=", sig->domain)
1419 && pdkim_headcat(&col, hdr, ";", "s=", sig->selector)
1422 /* list of header names can be split between items. */
1424 char *n = CS string_copy(sig->headernames);
1431 char *c = strchr(n, ':');
1436 if (!pdkim_headcat(&col, hdr, NULL, NULL, ":"))
1441 if (!pdkim_headcat(&col, hdr, s, i, n))
1455 if(!pdkim_headcat(&col, hdr, ";", "bh=", base64_bh))
1460 if(!pdkim_headcat(&col, hdr, ";", "i=", sig->identity))
1463 if (sig->created > 0)
1467 snprintf(minibuf, 20, "%lu", sig->created);
1468 if(!pdkim_headcat(&col, hdr, ";", "t=", minibuf))
1472 if (sig->expires > 0)
1476 snprintf(minibuf, 20, "%lu", sig->expires);
1477 if(!pdkim_headcat(&col, hdr, ";", "x=", minibuf))
1481 if (sig->bodylength >= 0)
1485 snprintf(minibuf, 20, "%lu", sig->bodylength);
1486 if(!pdkim_headcat(&col, hdr, ";", "l=", minibuf))
1490 /* Preliminary or final version? */
1493 if (!(base64_b = pdkim_encode_base64(&sig->sigdata)))
1495 if (!pdkim_headcat(&col, hdr, ";", "b=", base64_b))
1499 if(!pdkim_headcat(&col, hdr, ";", "b=", ""))
1502 /* add trailing semicolon: I'm not sure if this is actually needed */
1503 if (!pdkim_headcat(&col, hdr, NULL, ";", ""))
1507 rc = strdup(hdr->str);
1511 if (canon_all) pdkim_strfree(canon_all);
1516 /* -------------------------------------------------------------------------- */
1519 pdkim_feed_finish(pdkim_ctx *ctx, pdkim_signature **return_signatures)
1521 pdkim_signature *sig = ctx->sig;
1522 pdkim_str *headernames = NULL; /* Collected signed header names */
1524 /* Check if we must still flush a (partial) header. If that is the
1525 case, the message has no body, and we must compute a body hash
1526 out of '<CR><LF>' */
1527 if (ctx->cur_header && ctx->cur_header->len)
1529 int rc = pdkim_header_complete(ctx);
1530 if (rc != PDKIM_OK) return rc;
1531 pdkim_update_bodyhash(ctx, "\r\n", 2);
1534 DEBUG(D_acl) debug_printf(
1535 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1537 /* Build (and/or evaluate) body hash */
1538 if (pdkim_finish_bodyhash(ctx) != PDKIM_OK)
1539 return PDKIM_ERR_OOM;
1541 /* SIGNING -------------------------------------------------------------- */
1542 if (ctx->mode == PDKIM_MODE_SIGN)
1543 if (!(headernames = pdkim_strnew(NULL)))
1544 return PDKIM_ERR_OOM;
1545 /* ---------------------------------------------------------------------- */
1549 BOOL is_sha1 = sig->algo == PDKIM_ALGO_RSA_SHA1;
1554 int hdata_alloc = 0;
1559 exim_sha_init(&hhash_ctx, is_sha1);
1561 DEBUG(D_acl) debug_printf(
1562 "PDKIM >> Hashed header data, canonicalized, in sequence >>>>>>>>>>>>>>\n");
1564 /* SIGNING ---------------------------------------------------------------- */
1565 /* When signing, walk through our header list and add them to the hash. As we
1566 go, construct a list of the header's names to use for the h= parameter.
1567 Then append to that list any remaining header names for which there was no
1570 if (ctx->mode == PDKIM_MODE_SIGN)
1572 pdkim_stringlist *p;
1577 for (p = sig->headers; p; p = p->next)
1578 if (header_name_match(p->value, sig->sign_headers) == PDKIM_OK)
1581 /* Collect header names (Note: colon presence is guaranteed here) */
1582 uschar * q = Ustrchr(p->value, ':');
1584 if (!(pdkim_strncat(headernames, p->value,
1585 (q - US p->value) + (p->next ? 1 : 0))))
1586 return PDKIM_ERR_OOM;
1588 rh = sig->canon_headers == PDKIM_CANON_RELAXED
1589 ? US pdkim_relax_header(p->value, 1) /* cook header for relaxed canon */
1590 : string_copy(CUS p->value); /* just copy it for simple canon */
1592 return PDKIM_ERR_OOM;
1594 /* Feed header to the hash algorithm */
1595 exim_sha_update(&hhash_ctx, CCS rh, Ustrlen(rh));
1597 /* Remember headers block for signing (when the library cannot do incremental) */
1598 (void) exim_rsa_data_append(&hdata, &hdata_alloc, rh);
1600 DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1603 l = US sig->sign_headers;
1604 while((s = string_nextinlist(&l, &sep, NULL, 0)))
1606 { /*SSS string_append_listele() */
1607 if (headernames->len > 0 && headernames->str[headernames->len-1] != ':')
1608 if (!(pdkim_strncat(headernames, ":", 1)))
1609 return PDKIM_ERR_OOM;
1610 if (!(pdkim_strncat(headernames, CS s, Ustrlen(s))))
1611 return PDKIM_ERR_OOM;
1615 /* VERIFICATION ----------------------------------------------------------- */
1616 /* When verifying, walk through the header name list in the h= parameter and
1617 add the headers to the hash in that order. */
1620 uschar * b = string_copy(sig->headernames);
1623 pdkim_stringlist * hdrs;
1625 if (!b) return PDKIM_ERR_OOM;
1628 for (hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1633 if ((q = Ustrchr(p, ':')))
1636 /*XXX walk the list of headers in same order as received. */
1637 for (hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1639 && strncasecmp(hdrs->value, CS p, Ustrlen(p)) == 0
1640 && (hdrs->value)[Ustrlen(p)] == ':'
1643 uschar * rh = sig->canon_headers == PDKIM_CANON_RELAXED
1644 ? US pdkim_relax_header(hdrs->value, 1) /* cook header for relaxed canon */
1645 : string_copy(CUS hdrs->value); /* just copy it for simple canon */
1647 return PDKIM_ERR_OOM;
1649 /* Feed header to the hash algorithm */
1650 exim_sha_update(&hhash_ctx, CCS rh, Ustrlen(rh));
1652 DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1662 DEBUG(D_acl) debug_printf(
1663 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1665 /* SIGNING ---------------------------------------------------------------- */
1666 if (ctx->mode == PDKIM_MODE_SIGN)
1668 /* Copy headernames to signature struct */
1669 sig->headernames = string_copy(US headernames->str);
1670 pdkim_strfree(headernames);
1672 /* Create signature header with b= omitted */
1673 sig_hdr = pdkim_create_header(sig, FALSE);
1676 /* VERIFICATION ----------------------------------------------------------- */
1678 sig_hdr = strdup(sig->rawsig_no_b_val);
1679 /* ------------------------------------------------------------------------ */
1682 return PDKIM_ERR_OOM;
1684 /* Relax header if necessary */
1685 if (sig->canon_headers == PDKIM_CANON_RELAXED)
1687 char *relaxed_hdr = pdkim_relax_header(sig_hdr, 0);
1691 return PDKIM_ERR_OOM;
1692 sig_hdr = relaxed_hdr;
1698 "PDKIM >> Signed DKIM-Signature header, canonicalized >>>>>>>>>>>>>>>>>\n");
1699 pdkim_quoteprint(CUS sig_hdr, strlen(sig_hdr));
1701 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1704 /* Finalize header hash */
1705 exim_sha_update(&hhash_ctx, sig_hdr, strlen(sig_hdr));
1706 exim_sha_finish(&hhash_ctx, &hhash);
1710 debug_printf("PDKIM [%s] hh computed: ", sig->domain);
1711 pdkim_hexprint(hhash.data, hhash.len);
1714 /* Remember headers block for signing (when the library cannot do incremental) */
1715 if (ctx->mode == PDKIM_MODE_SIGN)
1716 (void) exim_rsa_data_append(&hdata, &hdata_alloc, US sig_hdr);
1720 /* SIGNING ---------------------------------------------------------------- */
1721 if (ctx->mode == PDKIM_MODE_SIGN)
1724 const uschar * errstr;
1726 /* Import private key */
1727 if ((errstr = exim_rsa_signing_init(US sig->rsa_privkey, &sctx)))
1729 DEBUG(D_acl) debug_printf("signing_init: %s\n", errstr);
1730 return PDKIM_ERR_RSA_PRIVKEY;
1733 /* Do signing. With OpenSSL we are signing the hash of headers just
1734 calculated, with GnuTLS we have to sign an entire block of headers
1735 (due to available interfaces) and it recalculates the hash internally. */
1737 #if defined(RSA_OPENSSL) || defined(RSA_GCRYPT)
1741 if ((errstr = exim_rsa_sign(&sctx, is_sha1, &hdata, &sig->sigdata)))
1743 DEBUG(D_acl) debug_printf("signing: %s\n", errstr);
1744 return PDKIM_ERR_RSA_SIGNING;
1749 debug_printf( "PDKIM [%s] b computed: ", sig->domain);
1750 pdkim_hexprint(sig->sigdata.data, sig->sigdata.len);
1753 if (!(sig->signature_header = pdkim_create_header(sig, TRUE)))
1754 return PDKIM_ERR_OOM;
1756 /* We only ever sign with one sig, and we free'd "headernames"
1757 above. So to keep static-analysers happy, exit the loop explicitly.
1758 Perhaps the code would be more clear if signing and verification
1759 loops were separated? */
1764 /* VERIFICATION ----------------------------------------------------------- */
1768 const uschar * errstr;
1770 char *dns_txt_name, *dns_txt_reply;
1772 /* Fetch public key for signing domain, from DNS */
1774 if (!(dns_txt_name = malloc(PDKIM_DNS_TXT_MAX_NAMELEN)))
1775 return PDKIM_ERR_OOM;
1777 if (!(dns_txt_reply = malloc(PDKIM_DNS_TXT_MAX_RECLEN)))
1780 return PDKIM_ERR_OOM;
1783 memset(dns_txt_reply, 0, PDKIM_DNS_TXT_MAX_RECLEN);
1784 memset(dns_txt_name , 0, PDKIM_DNS_TXT_MAX_NAMELEN);
1786 if (snprintf(dns_txt_name, PDKIM_DNS_TXT_MAX_NAMELEN,
1787 "%s._domainkey.%s.",
1788 sig->selector, sig->domain) >= PDKIM_DNS_TXT_MAX_NAMELEN)
1790 sig->verify_status = PDKIM_VERIFY_INVALID;
1791 sig->verify_ext_status = PDKIM_VERIFY_INVALID_BUFFER_SIZE;
1795 if ( ctx->dns_txt_callback(dns_txt_name, dns_txt_reply) != PDKIM_OK
1796 || dns_txt_reply[0] == '\0')
1798 sig->verify_status = PDKIM_VERIFY_INVALID;
1799 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE;
1806 "PDKIM >> Parsing public key record >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"
1808 pdkim_quoteprint(CUS dns_txt_reply, strlen(dns_txt_reply));
1811 if (!(sig->pubkey = pdkim_parse_pubkey_record(ctx, dns_txt_reply)))
1813 sig->verify_status = PDKIM_VERIFY_INVALID;
1814 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD;
1816 DEBUG(D_acl) debug_printf(
1817 " Error while parsing public key record\n"
1818 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1822 DEBUG(D_acl) debug_printf(
1823 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1825 /* Import public key */
1826 if ((errstr = exim_rsa_verify_init(&sig->pubkey->key, &vctx)))
1828 DEBUG(D_acl) debug_printf("verify_init: %s\n", errstr);
1829 sig->verify_status = PDKIM_VERIFY_INVALID;
1830 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
1834 /* Check the signature */
1835 if ((errstr = exim_rsa_verify(&vctx, is_sha1, &hhash, &sig->sigdata)))
1837 DEBUG(D_acl) debug_printf("headers verify: %s\n", errstr);
1838 sig->verify_status = PDKIM_VERIFY_FAIL;
1839 sig->verify_ext_status = PDKIM_VERIFY_FAIL_MESSAGE;
1844 /* We have a winner! (if bodydhash was correct earlier) */
1845 if (sig->verify_status == PDKIM_VERIFY_NONE)
1846 sig->verify_status = PDKIM_VERIFY_PASS;
1852 debug_printf("PDKIM [%s] signature status: %s",
1853 sig->domain, pdkim_verify_status_str(sig->verify_status));
1854 if (sig->verify_ext_status > 0)
1855 debug_printf(" (%s)\n",
1856 pdkim_verify_ext_status_str(sig->verify_ext_status));
1862 free(dns_txt_reply);
1868 /* If requested, set return pointer to signature(s) */
1869 if (return_signatures)
1870 *return_signatures = ctx->sig;
1876 /* -------------------------------------------------------------------------- */
1878 DLLEXPORT pdkim_ctx *
1879 pdkim_init_verify(int(*dns_txt_callback)(char *, char *))
1881 pdkim_ctx *ctx = malloc(sizeof(pdkim_ctx));
1885 memset(ctx, 0, sizeof(pdkim_ctx));
1887 if (!(ctx->linebuf = malloc(PDKIM_MAX_BODY_LINE_LEN)))
1893 ctx->mode = PDKIM_MODE_VERIFY;
1894 ctx->dns_txt_callback = dns_txt_callback;
1900 /* -------------------------------------------------------------------------- */
1902 DLLEXPORT pdkim_ctx *
1903 pdkim_init_sign(char *domain, char *selector, char *rsa_privkey, int algo)
1906 pdkim_signature *sig;
1908 if (!domain || !selector || !rsa_privkey)
1911 if (!(ctx = malloc(sizeof(pdkim_ctx))))
1913 memset(ctx, 0, sizeof(pdkim_ctx));
1915 if (!(ctx->linebuf = malloc(PDKIM_MAX_BODY_LINE_LEN)))
1921 if (!(sig = malloc(sizeof(pdkim_signature))))
1927 memset(sig, 0, sizeof(pdkim_signature));
1929 sig->bodylength = -1;
1931 ctx->mode = PDKIM_MODE_SIGN;
1934 sig->domain = strdup(domain);
1935 sig->selector = strdup(selector);
1936 sig->rsa_privkey = strdup(rsa_privkey);
1939 if (!sig->domain || !sig->selector || !sig->rsa_privkey)
1942 exim_sha_init(&sig->body_hash, algo == PDKIM_ALGO_RSA_SHA1);
1946 pdkim_free_ctx(ctx);
1951 /* -------------------------------------------------------------------------- */
1954 pdkim_set_optional(pdkim_ctx *ctx,
1960 unsigned long created,
1961 unsigned long expires)
1963 pdkim_signature * sig = ctx->sig;
1966 if (!(sig->identity = strdup(identity)))
1967 return PDKIM_ERR_OOM;
1969 if (!(sig->sign_headers = strdup(sign_headers
1970 ? sign_headers : PDKIM_DEFAULT_SIGN_HEADERS)))
1971 return PDKIM_ERR_OOM;
1973 sig->canon_headers = canon_headers;
1974 sig->canon_body = canon_body;
1975 sig->bodylength = bodylength;
1976 sig->created = created;
1977 sig->expires = expires;
1991 #endif /*DISABLE_DKIM*/