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 char *data, int len)
155 const unsigned char *p = (const unsigned char *)data;
157 for (i = 0; i < len; i++)
162 case ' ' : debug_printf("{SP}"); break;
163 case '\t': debug_printf("{TB}"); break;
164 case '\r': debug_printf("{CR}"); break;
165 case '\n': debug_printf("{LF}"); break;
166 case '{' : debug_printf("{BO}"); break;
167 case '}' : debug_printf("{BC}"); break;
169 if ( (c < 32) || (c > 127) )
170 debug_printf("{%02x}", c);
172 debug_printf("%c", c);
180 pdkim_hexprint(const char *data, int len)
183 const unsigned char *p = (const unsigned char *)data;
185 for (i = 0 ; i < len; i++)
186 debug_printf("%02x", p[i]);
192 /* SSS probably want to keep the "stringlist" notion */
194 static pdkim_stringlist *
195 pdkim_prepend_stringlist(pdkim_stringlist *base, char *str)
197 pdkim_stringlist *new_entry = malloc(sizeof(pdkim_stringlist));
199 if (!new_entry) return NULL;
200 memset(new_entry, 0, sizeof(pdkim_stringlist));
201 if (!(new_entry->value = strdup(str))) return NULL;
202 if (base) new_entry->next = base;
207 /* -------------------------------------------------------------------------- */
208 /* A small "growing string" implementation to escape malloc/realloc hell */
209 /* String package: should be replaced by Exim standard ones */
213 pdkim_strnew (const char *cstr)
215 unsigned int len = cstr ? strlen(cstr) : 0;
216 pdkim_str *p = malloc(sizeof(pdkim_str));
219 memset(p, 0, sizeof(pdkim_str));
220 if (!(p->str = malloc(len+1)))
225 p->allocated = len+1;
228 strcpy(p->str, cstr);
230 p->str[p->len] = '\0';
238 pdkim_strncat(pdkim_str *str, const char *data, int len)
240 if ((str->allocated - str->len) < (len+1))
242 /* Extend the buffer */
243 int num_frags = ((len+1)/PDKIM_STR_ALLOC_FRAG)+1;
244 char *n = realloc(str->str,
245 (str->allocated+(num_frags*PDKIM_STR_ALLOC_FRAG)));
246 if (n == NULL) return NULL;
248 str->allocated += (num_frags*PDKIM_STR_ALLOC_FRAG);
250 strncpy(&(str->str[str->len]), data, len);
252 str->str[str->len] = '\0';
260 pdkim_strcat(pdkim_str *str, const char *cstr)
262 return pdkim_strncat(str, cstr, strlen(cstr));
267 /* Trim whitespace fore & aft */
270 pdkim_strtrim(pdkim_str *str)
274 while (*p == '\t' || *p == ' ') p++; /* skip whitespace */
275 while (*p) {*q = *p; q++; p++;} /* dump the leading whitespace */
277 while (q != str->str && ( (*q == '\0') || (*q == '\t') || (*q == ' ') ) )
278 { /* dump trailing whitespace */
282 str->len = strlen(str->str);
289 pdkim_strclear(pdkim_str *str)
299 pdkim_strfree(pdkim_str *str)
302 if (str->str) free(str->str);
308 pdkim_stringlist_free(pdkim_stringlist * e)
312 pdkim_stringlist * c = e;
313 if (e->value) free(e->value);
321 /* -------------------------------------------------------------------------- */
324 pdkim_free_pubkey(pdkim_pubkey *pub)
328 if (pub->version ) free(pub->version);
329 if (pub->granularity) free(pub->granularity);
330 if (pub->hashes ) free(pub->hashes);
331 if (pub->keytype ) free(pub->keytype);
332 if (pub->srvtype ) free(pub->srvtype);
333 if (pub->notes ) free(pub->notes);
339 /* -------------------------------------------------------------------------- */
342 pdkim_free_sig(pdkim_signature *sig)
346 pdkim_signature *next = (pdkim_signature *)sig->next;
348 pdkim_stringlist_free(sig->headers);
349 if (sig->selector ) free(sig->selector);
350 if (sig->domain ) free(sig->domain);
351 if (sig->identity ) free(sig->identity);
352 if (sig->copiedheaders ) free(sig->copiedheaders);
353 if (sig->rsa_privkey ) free(sig->rsa_privkey);
354 if (sig->sign_headers ) free(sig->sign_headers);
355 if (sig->signature_header) free(sig->signature_header);
357 if (sig->pubkey) pdkim_free_pubkey(sig->pubkey);
360 if (next) pdkim_free_sig(next);
365 /* -------------------------------------------------------------------------- */
368 pdkim_free_ctx(pdkim_ctx *ctx)
372 pdkim_stringlist_free(ctx->headers);
373 pdkim_free_sig(ctx->sig);
374 pdkim_strfree(ctx->cur_header);
380 /* -------------------------------------------------------------------------- */
381 /* Matches the name of the passed raw "header" against
382 the passed colon-separated "tick", and invalidates
383 the entry in tick. Returns OK or fail-code */
384 /*XXX might be safer done using a pdkim_stringlist for "tick" */
387 header_name_match(const char * header, char * tick)
395 /* Get header name */
396 char *hcolon = strchr(header, ':');
398 if (!hcolon) return rc; /* This isn't a header */
400 if (!(hname = malloc((hcolon-header)+1)))
401 return PDKIM_ERR_OOM;
402 memset(hname, 0, (hcolon-header)+1);
403 strncpy(hname, header, (hcolon-header));
405 /* Copy tick-off list locally, so we can punch zeroes into it */
406 if (!(lcopy = strdup(tick)))
409 return PDKIM_ERR_OOM;
417 if (strcasecmp(p, hname) == 0)
420 /* Invalidate header name instance in tick-off list */
429 if (strcasecmp(p, hname) == 0)
432 /* Invalidate header name instance in tick-off list */
443 /* -------------------------------------------------------------------------- */
444 /* Performs "relaxed" canonicalization of a header. The returned pointer needs
448 pdkim_relax_header (char *header, int crlf)
450 BOOL past_field_name = FALSE;
451 BOOL seen_wsp = FALSE;
454 char *relaxed = malloc(strlen(header)+3);
456 if (!relaxed) return NULL;
459 for (p = header; *p != '\0'; p++)
463 if (c == '\r' || c == '\n')
465 if (c == '\t' || c == ' ')
469 c = ' '; /* Turns WSP into SP */
473 if (!past_field_name && c == ':')
475 if (seen_wsp) q--; /* This removes WSP before the colon */
476 seen_wsp = TRUE; /* This removes WSP after the colon */
477 past_field_name = TRUE;
482 /* Lowercase header name */
483 if (!past_field_name) c = tolower(c);
487 if (q > relaxed && q[-1] == ' ') q--; /* Squash eventual trailing SP */
490 if (crlf) strcat(relaxed, "\r\n");
495 /* -------------------------------------------------------------------------- */
496 #define PDKIM_QP_ERROR_DECODE -1
499 pdkim_decode_qp_char(char *qp_p, int *c)
501 char *initial_pos = qp_p;
503 /* Advance one char */
506 /* Check for two hex digits and decode them */
507 if (isxdigit(*qp_p) && isxdigit(qp_p[1]))
509 /* Do hex conversion */
510 *c = (isdigit(*qp_p) ? *qp_p - '0' : toupper(*qp_p) - 'A' + 10) << 4;
511 *c |= isdigit(qp_p[1]) ? qp_p[1] - '0' : toupper(qp_p[1]) - 'A' + 10;
515 /* Illegal char here */
516 *c = PDKIM_QP_ERROR_DECODE;
521 /* -------------------------------------------------------------------------- */
524 pdkim_decode_qp(char *str)
529 char *n = malloc(strlen(p)+1);
539 p = pdkim_decode_qp_char(p, &nchar);
555 /* -------------------------------------------------------------------------- */
558 pdkim_decode_base64(uschar *str, blob * b)
562 dlen = b64decode(str, &b->data);
563 if (dlen < 0) b->data = NULL;
567 /* -------------------------------------------------------------------------- */
570 pdkim_encode_base64(blob * b)
573 int old_pool = store_pool;
575 store_pool = POOL_PERM;
576 ret = CS b64encode(b->data, b->len);
577 store_pool = old_pool;
582 /* -------------------------------------------------------------------------- */
583 #define PDKIM_HDR_LIMBO 0
584 #define PDKIM_HDR_TAG 1
585 #define PDKIM_HDR_VALUE 2
587 static pdkim_signature *
588 pdkim_parse_sig_header(pdkim_ctx *ctx, char *raw_hdr)
590 pdkim_signature *sig ;
592 pdkim_str *cur_tag = NULL;
593 pdkim_str *cur_val = NULL;
594 BOOL past_hname = FALSE;
595 BOOL in_b_val = FALSE;
596 int where = PDKIM_HDR_LIMBO;
598 int old_pool = store_pool;
600 /* There is a store-reset between header & body reception
601 so cannot use the main pool. Any allocs done by Exim
602 memory-handling must use the perm pool. */
604 store_pool = POOL_PERM;
606 if (!(sig = malloc(sizeof(pdkim_signature)))) return NULL;
607 memset(sig, 0, sizeof(pdkim_signature));
608 sig->bodylength = -1;
610 if (!(sig->rawsig_no_b_val = malloc(strlen(raw_hdr)+1)))
616 q = sig->rawsig_no_b_val;
618 for (p = raw_hdr; ; p++)
623 if (c == '\r' || c == '\n')
626 /* Fast-forward through header name */
629 if (c == ':') past_hname = TRUE;
633 if (where == PDKIM_HDR_LIMBO)
635 /* In limbo, just wait for a tag-char to appear */
636 if (!(c >= 'a' && c <= 'z'))
639 where = PDKIM_HDR_TAG;
642 if (where == PDKIM_HDR_TAG)
645 cur_tag = pdkim_strnew(NULL);
647 if (c >= 'a' && c <= 'z')
648 pdkim_strncat(cur_tag, p, 1);
652 if (strcmp(cur_tag->str, "b") == 0)
657 where = PDKIM_HDR_VALUE;
662 if (where == PDKIM_HDR_VALUE)
665 cur_val = pdkim_strnew(NULL);
667 if (c == '\r' || c == '\n' || c == ' ' || c == '\t')
670 if (c == ';' || c == '\0')
672 if (cur_tag->len > 0)
674 pdkim_strtrim(cur_val);
676 DEBUG(D_acl) debug_printf(" %s=%s\n", cur_tag->str, cur_val->str);
678 switch (cur_tag->str[0])
681 if (cur_tag->str[1] == 'h')
682 pdkim_decode_base64(US cur_val->str, &sig->bodyhash);
684 pdkim_decode_base64(US cur_val->str, &sig->sigdata);
687 /* We only support version 1, and that is currently the
688 only version there is. */
689 if (strcmp(cur_val->str, PDKIM_SIGNATURE_VERSION) == 0)
693 for (i = 0; pdkim_algos[i]; i++)
694 if (strcmp(cur_val->str, pdkim_algos[i]) == 0)
701 for (i = 0; pdkim_combined_canons[i].str; i++)
702 if (strcmp(cur_val->str, pdkim_combined_canons[i].str) == 0)
704 sig->canon_headers = pdkim_combined_canons[i].canon_headers;
705 sig->canon_body = pdkim_combined_canons[i].canon_body;
710 for (i = 0; pdkim_querymethods[i]; i++)
711 if (strcmp(cur_val->str, pdkim_querymethods[i]) == 0)
713 sig->querymethod = i;
718 sig->selector = strdup(cur_val->str); break;
720 sig->domain = strdup(cur_val->str); break;
722 sig->identity = pdkim_decode_qp(cur_val->str); break;
724 sig->created = strtoul(cur_val->str, NULL, 10); break;
726 sig->expires = strtoul(cur_val->str, NULL, 10); break;
728 sig->bodylength = strtol(cur_val->str, NULL, 10); break;
730 sig->headernames = string_copy(cur_val->str); break;
732 sig->copiedheaders = pdkim_decode_qp(cur_val->str); break;
734 DEBUG(D_acl) debug_printf(" Unknown tag encountered\n");
738 pdkim_strclear(cur_tag);
739 pdkim_strclear(cur_val);
741 where = PDKIM_HDR_LIMBO;
744 pdkim_strncat(cur_val, p, 1);
755 store_pool = old_pool;
757 /* Make sure the most important bits are there. */
758 if (!(sig->domain && (*(sig->domain) != '\0') &&
759 sig->selector && (*(sig->selector) != '\0') &&
760 sig->headernames && (*(sig->headernames) != '\0') &&
768 /* Chomp raw header. The final newline must not be added to the signature. */
770 while (q > sig->rawsig_no_b_val && (*q == '\r' || *q == '\n'))
771 *q = '\0'; q--; /*XXX questionable code layout; possible bug */
776 "PDKIM >> Raw signature w/o b= tag value >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
777 pdkim_quoteprint(sig->rawsig_no_b_val, strlen(sig->rawsig_no_b_val));
779 "PDKIM >> Sig size: %4d bits\n", sig->sigdata.len*8);
781 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
784 exim_sha_init(&sig->body_hash, sig->algo == PDKIM_ALGO_RSA_SHA1);
789 /* -------------------------------------------------------------------------- */
791 static pdkim_pubkey *
792 pdkim_parse_pubkey_record(pdkim_ctx *ctx, char *raw_record)
796 pdkim_str *cur_tag = NULL;
797 pdkim_str *cur_val = NULL;
798 int where = PDKIM_HDR_LIMBO;
800 if (!(pub = malloc(sizeof(pdkim_pubkey)))) return NULL;
801 memset(pub, 0, sizeof(pdkim_pubkey));
803 for (p = raw_record; ; p++)
808 if (c == '\r' || c == '\n')
811 if (where == PDKIM_HDR_LIMBO)
813 /* In limbo, just wait for a tag-char to appear */
814 if (!(c >= 'a' && c <= 'z'))
817 where = PDKIM_HDR_TAG;
820 if (where == PDKIM_HDR_TAG)
823 cur_tag = pdkim_strnew(NULL);
825 if (c >= 'a' && c <= 'z')
826 pdkim_strncat(cur_tag, p, 1);
830 where = PDKIM_HDR_VALUE;
835 if (where == PDKIM_HDR_VALUE)
838 cur_val = pdkim_strnew(NULL);
840 if (c == '\r' || c == '\n')
843 if (c == ';' || c == '\0')
845 if (cur_tag->len > 0)
847 pdkim_strtrim(cur_val);
848 DEBUG(D_acl) debug_printf(" %s=%s\n", cur_tag->str, cur_val->str);
850 switch (cur_tag->str[0])
853 /* This tag isn't evaluated because:
854 - We only support version DKIM1.
855 - Which is the default for this value (set below)
856 - Other versions are currently not specified. */
859 pub->hashes = strdup(cur_val->str); break;
861 pub->granularity = strdup(cur_val->str); break;
863 pub->notes = pdkim_decode_qp(cur_val->str); break;
865 pdkim_decode_base64(US cur_val->str, &pub->key);
868 pub->hashes = strdup(cur_val->str); break;
870 pub->srvtype = strdup(cur_val->str); break;
872 if (strchr(cur_val->str, 'y') != NULL) pub->testing = 1;
873 if (strchr(cur_val->str, 's') != NULL) pub->no_subdomaining = 1;
876 DEBUG(D_acl) debug_printf(" Unknown tag encountered\n");
880 pdkim_strclear(cur_tag);
881 pdkim_strclear(cur_val);
882 where = PDKIM_HDR_LIMBO;
885 pdkim_strncat(cur_val, p, 1);
889 if (c == '\0') break;
892 /* Set fallback defaults */
893 if (!pub->version ) pub->version = strdup(PDKIM_PUB_RECORD_VERSION);
894 if (!pub->granularity) pub->granularity = strdup("*");
895 if (!pub->keytype ) pub->keytype = strdup("rsa");
896 if (!pub->srvtype ) pub->srvtype = strdup("*");
902 pdkim_free_pubkey(pub);
907 /* -------------------------------------------------------------------------- */
910 pdkim_update_bodyhash(pdkim_ctx *ctx, const char *data, int len)
912 pdkim_signature *sig = ctx->sig;
913 /* Cache relaxed version of data */
914 char *relaxed_data = NULL;
917 /* Traverse all signatures, updating their hashes. */
920 /* Defaults to simple canon (no further treatment necessary) */
921 const char *canon_data = data;
924 if (sig->canon_body == PDKIM_CANON_RELAXED)
926 /* Relax the line if not done already */
929 BOOL seen_wsp = FALSE;
933 if (!(relaxed_data = malloc(len+1)))
934 return PDKIM_ERR_OOM;
936 for (p = data; *p; p++)
941 if (q > 0 && relaxed_data[q-1] == ' ')
944 else if (c == '\t' || c == ' ')
946 c = ' '; /* Turns WSP into SP */
953 relaxed_data[q++] = c;
955 relaxed_data[q] = '\0';
958 canon_data = relaxed_data;
959 canon_len = relaxed_len;
962 /* Make sure we don't exceed the to-be-signed body length */
963 if ( sig->bodylength >= 0
964 && sig->signed_body_bytes + (unsigned long)canon_len > sig->bodylength
966 canon_len = sig->bodylength - sig->signed_body_bytes;
970 exim_sha_update(&sig->body_hash, canon_data, canon_len);
971 sig->signed_body_bytes += canon_len;
972 DEBUG(D_acl) pdkim_quoteprint(canon_data, canon_len);
978 if (relaxed_data) free(relaxed_data);
983 /* -------------------------------------------------------------------------- */
986 pdkim_finish_bodyhash(pdkim_ctx *ctx)
988 pdkim_signature *sig;
990 /* Traverse all signatures */
991 for (sig = ctx->sig; sig; sig = sig->next)
992 { /* Finish hashes */
995 exim_sha_finish(&sig->body_hash, &bh);
999 debug_printf("PDKIM [%s] Body bytes hashed: %lu\n"
1000 "PDKIM [%s] bh computed: ",
1001 sig->domain, sig->signed_body_bytes, sig->domain);
1002 pdkim_hexprint(CS bh.data, bh.len);
1005 /* SIGNING -------------------------------------------------------------- */
1006 if (ctx->mode == PDKIM_MODE_SIGN)
1010 /* If bodylength limit is set, and we have received less bytes
1011 than the requested amount, effectively remove the limit tag. */
1012 if (sig->signed_body_bytes < sig->bodylength)
1013 sig->bodylength = -1;
1016 /* VERIFICATION --------------------------------------------------------- */
1019 /* Compare bodyhash */
1020 if (memcmp(bh.data, sig->bodyhash.data, bh.len) == 0)
1022 DEBUG(D_acl) debug_printf("PDKIM [%s] Body hash verified OK\n", sig->domain);
1028 debug_printf("PDKIM [%s] bh signature: ", sig->domain);
1029 pdkim_hexprint(sig->bodyhash.data,
1030 exim_sha_hashlen(&sig->body_hash));
1031 debug_printf("PDKIM [%s] Body hash did NOT verify\n", sig->domain);
1033 sig->verify_status = PDKIM_VERIFY_FAIL;
1034 sig->verify_ext_status = PDKIM_VERIFY_FAIL_BODY;
1044 /* -------------------------------------------------------------------------- */
1045 /* Callback from pdkim_feed below for processing complete body lines */
1048 pdkim_bodyline_complete(pdkim_ctx *ctx)
1050 char *p = ctx->linebuf;
1051 int n = ctx->linebuf_offset;
1052 pdkim_signature *sig = ctx->sig; /*XXX assumes only one sig */
1054 /* Ignore extra data if we've seen the end-of-data marker */
1055 if (ctx->seen_eod) goto BAIL;
1057 /* We've always got one extra byte to stuff a zero ... */
1058 ctx->linebuf[ctx->linebuf_offset] = '\0';
1060 /* Terminate on EOD marker */
1061 if (memcmp(p, ".\r\n", 3) == 0)
1063 /* In simple body mode, if any empty lines were buffered,
1064 replace with one. rfc 4871 3.4.3 */
1065 /*XXX checking the signed-body-bytes is a gross hack; I think
1066 it indicates that all linebreaks should be buffered, including
1067 the one terminating a text line */
1068 if ( sig && sig->canon_body == PDKIM_CANON_SIMPLE
1069 && sig->signed_body_bytes == 0
1070 && ctx->num_buffered_crlf > 0
1072 pdkim_update_bodyhash(ctx, "\r\n", 2);
1074 ctx->seen_eod = TRUE;
1078 if (memcmp(p, "..", 2) == 0)
1084 /* Empty lines need to be buffered until we find a non-empty line */
1085 if (memcmp(p, "\r\n", 2) == 0)
1087 ctx->num_buffered_crlf++;
1091 if (sig && sig->canon_body == PDKIM_CANON_RELAXED)
1093 /* Lines with just spaces need to be buffered too */
1095 while (memcmp(check, "\r\n", 2) != 0)
1099 if (c != '\t' && c != ' ')
1104 ctx->num_buffered_crlf++;
1109 /* At this point, we have a non-empty line, so release the buffered ones. */
1110 while (ctx->num_buffered_crlf)
1112 pdkim_update_bodyhash(ctx, "\r\n", 2);
1113 ctx->num_buffered_crlf--;
1116 pdkim_update_bodyhash(ctx, p, n);
1119 ctx->linebuf_offset = 0;
1124 /* -------------------------------------------------------------------------- */
1125 /* Callback from pdkim_feed below for processing complete headers */
1126 #define DKIM_SIGNATURE_HEADERNAME "DKIM-Signature:"
1129 pdkim_header_complete(pdkim_ctx *ctx)
1131 /* Special case: The last header can have an extra \r appended */
1132 if ( (ctx->cur_header->len > 1) &&
1133 (ctx->cur_header->str[(ctx->cur_header->len)-1] == '\r') )
1135 ctx->cur_header->str[(ctx->cur_header->len)-1] = '\0';
1136 ctx->cur_header->len--;
1140 if (ctx->num_headers > PDKIM_MAX_HEADERS) goto BAIL;
1142 /* SIGNING -------------------------------------------------------------- */
1143 if (ctx->mode == PDKIM_MODE_SIGN)
1145 pdkim_signature *sig;
1147 for (sig = ctx->sig; sig; sig = sig->next) /* Traverse all signatures */
1149 pdkim_stringlist *list;
1151 /* Add header to the signed headers list (in reverse order) */
1152 if (!(list = pdkim_prepend_stringlist(sig->headers,
1153 ctx->cur_header->str)))
1154 return PDKIM_ERR_OOM;
1155 sig->headers = list;
1159 /* VERIFICATION ----------------------------------------------------------- */
1160 /* DKIM-Signature: headers are added to the verification list */
1161 if (ctx->mode == PDKIM_MODE_VERIFY)
1163 if (strncasecmp(ctx->cur_header->str,
1164 DKIM_SIGNATURE_HEADERNAME,
1165 strlen(DKIM_SIGNATURE_HEADERNAME)) == 0)
1167 pdkim_signature *new_sig;
1169 /* Create and chain new signature block */
1170 DEBUG(D_acl) debug_printf(
1171 "PDKIM >> Found sig, trying to parse >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1173 if ((new_sig = pdkim_parse_sig_header(ctx, ctx->cur_header->str)))
1175 pdkim_signature *last_sig = ctx->sig;
1180 while (last_sig->next) last_sig = last_sig->next;
1181 last_sig->next = new_sig;
1185 DEBUG(D_acl) debug_printf(
1186 "Error while parsing signature header\n"
1187 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1190 /* every other header is stored for signature verification */
1193 pdkim_stringlist *list;
1195 if (!(list = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->str)))
1196 return PDKIM_ERR_OOM;
1197 ctx->headers = list;
1202 pdkim_strclear(ctx->cur_header); /* Re-use existing pdkim_str */
1208 /* -------------------------------------------------------------------------- */
1209 #define HEADER_BUFFER_FRAG_SIZE 256
1212 pdkim_feed (pdkim_ctx *ctx, char *data, int len)
1216 for (p = 0; p<len; p++)
1220 if (ctx->past_headers)
1222 /* Processing body byte */
1223 ctx->linebuf[ctx->linebuf_offset++] = c;
1226 int rc = pdkim_bodyline_complete(ctx); /* End of line */
1227 if (rc != PDKIM_OK) return rc;
1229 if (ctx->linebuf_offset == (PDKIM_MAX_BODY_LINE_LEN-1))
1230 return PDKIM_ERR_LONG_LINE;
1234 /* Processing header byte */
1241 int rc = pdkim_header_complete(ctx); /* Seen last header line */
1242 if (rc != PDKIM_OK) return rc;
1244 ctx->past_headers = TRUE;
1246 DEBUG(D_acl) debug_printf(
1247 "PDKIM >> Body data for hash, canonicalized >>>>>>>>>>>>>>>>>>>>>>\n");
1251 ctx->seen_lf = TRUE;
1253 else if (ctx->seen_lf)
1255 if (!(c == '\t' || c == ' '))
1257 int rc = pdkim_header_complete(ctx); /* End of header */
1258 if (rc != PDKIM_OK) return rc;
1260 ctx->seen_lf = FALSE;
1264 if (!ctx->cur_header)
1265 if (!(ctx->cur_header = pdkim_strnew(NULL)))
1266 return PDKIM_ERR_OOM;
1268 if (ctx->cur_header->len < PDKIM_MAX_HEADER_LEN)
1269 if (!pdkim_strncat(ctx->cur_header, &data[p], 1))
1270 return PDKIM_ERR_OOM;
1277 * RFC 5322 specifies that header line length SHOULD be no more than 78
1282 * col: this int holds and receives column number (octets since last '\n')
1283 * str: partial string to append to
1284 * pad: padding, split line or space after before or after eg: ";"
1285 * intro: - must join to payload eg "h=", usually the tag name
1286 * payload: eg base64 data - long data can be split arbitrarily.
1288 * this code doesn't fold the header in some of the places that RFC4871
1289 * allows: As per RFC5322(2.2.3) it only folds before or after tag-value
1290 * pairs and inside long values. it also always spaces or breaks after the
1293 * no guarantees are made for output given out-of range input. like tag
1294 * names longer than 78, or bogus col. Input is assumed to be free of line breaks.
1298 pdkim_headcat(int *col, pdkim_str *str, const char * pad,
1299 const char *intro, const char *payload)
1308 pdkim_strcat(str, "\r\n\t");
1311 pdkim_strncat(str, pad, l);
1315 l = (pad?1:0) + (intro?strlen(intro):0);
1318 { /*can't fit intro - start a new line to make room.*/
1319 pdkim_strcat(str, "\r\n\t");
1321 l = intro?strlen(intro):0;
1324 l += payload ? strlen(payload):0 ;
1327 { /* this fragment will not fit on a single line */
1330 pdkim_strcat(str, " ");
1332 pad = NULL; /* only want this once */
1338 size_t sl = strlen(intro);
1340 pdkim_strncat(str, intro, sl);
1343 intro = NULL; /* only want this once */
1348 size_t sl = strlen(payload);
1349 size_t chomp = *col+sl < 77 ? sl : 78-*col;
1351 pdkim_strncat(str, payload, chomp);
1357 /* the while precondition tells us it didn't fit. */
1358 pdkim_strcat(str, "\r\n\t");
1364 pdkim_strcat(str, "\r\n\t");
1371 pdkim_strcat(str, " ");
1378 size_t sl = strlen(intro);
1380 pdkim_strncat(str, intro, sl);
1388 size_t sl = strlen(payload);
1390 pdkim_strncat(str, payload, sl);
1398 /* -------------------------------------------------------------------------- */
1401 pdkim_create_header(pdkim_signature *sig, BOOL final)
1404 char *base64_bh = NULL;
1405 char *base64_b = NULL;
1408 pdkim_str *canon_all;
1410 if (!(hdr = pdkim_strnew("DKIM-Signature: v="PDKIM_SIGNATURE_VERSION)))
1413 if (!(canon_all = pdkim_strnew(pdkim_canons[sig->canon_headers])))
1416 if (!(base64_bh = pdkim_encode_base64(&sig->bodyhash)))
1419 col = strlen(hdr->str);
1421 /* Required and static bits */
1422 if ( pdkim_headcat(&col, hdr, ";", "a=", pdkim_algos[sig->algo])
1423 && pdkim_headcat(&col, hdr, ";", "q=", pdkim_querymethods[sig->querymethod])
1424 && pdkim_strcat(canon_all, "/")
1425 && pdkim_strcat(canon_all, pdkim_canons[sig->canon_body])
1426 && pdkim_headcat(&col, hdr, ";", "c=", canon_all->str)
1427 && pdkim_headcat(&col, hdr, ";", "d=", sig->domain)
1428 && pdkim_headcat(&col, hdr, ";", "s=", sig->selector)
1431 /* list of header names can be split between items. */
1433 char *n = CS string_copy(sig->headernames);
1441 char *c = strchr(n, ':');
1446 if (!pdkim_headcat(&col, hdr, NULL, NULL, ":"))
1451 if (!pdkim_headcat(&col, hdr, s, i, n))
1465 if(!pdkim_headcat(&col, hdr, ";", "bh=", base64_bh))
1470 if(!pdkim_headcat(&col, hdr, ";", "i=", sig->identity))
1473 if (sig->created > 0)
1477 snprintf(minibuf, 20, "%lu", sig->created);
1478 if(!pdkim_headcat(&col, hdr, ";", "t=", minibuf))
1482 if (sig->expires > 0)
1486 snprintf(minibuf, 20, "%lu", sig->expires);
1487 if(!pdkim_headcat(&col, hdr, ";", "x=", minibuf))
1491 if (sig->bodylength >= 0)
1495 snprintf(minibuf, 20, "%lu", sig->bodylength);
1496 if(!pdkim_headcat(&col, hdr, ";", "l=", minibuf))
1500 /* Preliminary or final version? */
1503 if (!(base64_b = pdkim_encode_base64(&sig->sigdata)))
1505 if (!pdkim_headcat(&col, hdr, ";", "b=", base64_b))
1509 if(!pdkim_headcat(&col, hdr, ";", "b=", ""))
1512 /* add trailing semicolon: I'm not sure if this is actually needed */
1513 if (!pdkim_headcat(&col, hdr, NULL, ";", ""))
1517 rc = strdup(hdr->str);
1521 if (canon_all) pdkim_strfree(canon_all);
1526 /* -------------------------------------------------------------------------- */
1529 pdkim_feed_finish(pdkim_ctx *ctx, pdkim_signature **return_signatures)
1531 pdkim_signature *sig = ctx->sig;
1532 pdkim_str *headernames = NULL; /* Collected signed header names */
1534 /* Check if we must still flush a (partial) header. If that is the
1535 case, the message has no body, and we must compute a body hash
1536 out of '<CR><LF>' */
1537 if (ctx->cur_header && ctx->cur_header->len)
1539 int rc = pdkim_header_complete(ctx);
1540 if (rc != PDKIM_OK) return rc;
1541 pdkim_update_bodyhash(ctx, "\r\n", 2);
1544 DEBUG(D_acl) debug_printf(
1545 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1547 /* Build (and/or evaluate) body hash */
1548 if (pdkim_finish_bodyhash(ctx) != PDKIM_OK)
1549 return PDKIM_ERR_OOM;
1551 /* SIGNING -------------------------------------------------------------- */
1552 if (ctx->mode == PDKIM_MODE_SIGN)
1553 if (!(headernames = pdkim_strnew(NULL)))
1554 return PDKIM_ERR_OOM;
1555 /* ---------------------------------------------------------------------- */
1559 BOOL is_sha1 = sig->algo == PDKIM_ALGO_RSA_SHA1;
1564 int hdata_alloc = 0;
1569 exim_sha_init(&hhash_ctx, is_sha1);
1571 DEBUG(D_acl) debug_printf(
1572 "PDKIM >> Hashed header data, canonicalized, in sequence >>>>>>>>>>>>>>\n");
1574 /* SIGNING ---------------------------------------------------------------- */
1575 /* When signing, walk through our header list and add them to the hash. As we
1576 go, construct a list of the header's names to use for the h= parameter.
1577 Then append to that list any remaining header names for which there was no
1580 if (ctx->mode == PDKIM_MODE_SIGN)
1582 pdkim_stringlist *p;
1587 for (p = sig->headers; p; p = p->next)
1588 if (header_name_match(p->value, sig->sign_headers) == PDKIM_OK)
1591 /* Collect header names (Note: colon presence is guaranteed here) */
1592 uschar * q = Ustrchr(p->value, ':');
1594 if (!(pdkim_strncat(headernames, p->value,
1595 (q - US p->value) + (p->next ? 1 : 0))))
1596 return PDKIM_ERR_OOM;
1598 rh = sig->canon_headers == PDKIM_CANON_RELAXED
1599 ? US pdkim_relax_header(p->value, 1) /* cook header for relaxed canon */
1600 : string_copy(p->value); /* just copy it for simple canon */
1602 return PDKIM_ERR_OOM;
1604 /* Feed header to the hash algorithm */
1605 exim_sha_update(&hhash_ctx, rh, strlen(rh));
1607 /* Remember headers block for signing (when the library cannot do incremental) */
1608 (void) exim_rsa_data_append(&hdata, &hdata_alloc, rh);
1610 DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1613 l = US sig->sign_headers;
1614 while((s = string_nextinlist(&l, &sep, NULL, 0)))
1616 { /*SSS string_append_listele() */
1617 if (headernames->len > 0 && headernames->str[headernames->len-1] != ':')
1618 if (!(pdkim_strncat(headernames, ":", 1)))
1619 return PDKIM_ERR_OOM;
1620 if (!(pdkim_strncat(headernames, CS s, Ustrlen(s))))
1621 return PDKIM_ERR_OOM;
1625 /* VERIFICATION ----------------------------------------------------------- */
1626 /* When verifying, walk through the header name list in the h= parameter and
1627 add the headers to the hash in that order. */
1630 uschar * b = string_copy(sig->headernames);
1633 pdkim_stringlist * hdrs;
1635 if (!b) return PDKIM_ERR_OOM;
1638 for (hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1643 if ((q = Ustrchr(p, ':')))
1646 /*XXX walk the list of headers in same order as received. */
1647 for (hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
1649 && strncasecmp(hdrs->value, CS p, Ustrlen(p)) == 0
1650 && (hdrs->value)[Ustrlen(p)] == ':'
1653 uschar * rh = sig->canon_headers == PDKIM_CANON_RELAXED
1654 ? US pdkim_relax_header(hdrs->value, 1) /* cook header for relaxed canon */
1655 : string_copy(hdrs->value); /* just copy it for simple canon */
1657 return PDKIM_ERR_OOM;
1659 /* Feed header to the hash algorithm */
1660 exim_sha_update(&hhash_ctx, rh, strlen(rh));
1662 DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh));
1672 DEBUG(D_acl) debug_printf(
1673 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1675 /* SIGNING ---------------------------------------------------------------- */
1676 if (ctx->mode == PDKIM_MODE_SIGN)
1678 /* Copy headernames to signature struct */
1679 sig->headernames = string_copy(US headernames->str);
1680 pdkim_strfree(headernames);
1682 /* Create signature header with b= omitted */
1683 sig_hdr = pdkim_create_header(sig, FALSE);
1686 /* VERIFICATION ----------------------------------------------------------- */
1688 sig_hdr = strdup(sig->rawsig_no_b_val);
1689 /* ------------------------------------------------------------------------ */
1692 return PDKIM_ERR_OOM;
1694 /* Relax header if necessary */
1695 if (sig->canon_headers == PDKIM_CANON_RELAXED)
1697 char *relaxed_hdr = pdkim_relax_header(sig_hdr, 0);
1701 return PDKIM_ERR_OOM;
1702 sig_hdr = relaxed_hdr;
1708 "PDKIM >> Signed DKIM-Signature header, canonicalized >>>>>>>>>>>>>>>>>\n");
1709 pdkim_quoteprint(sig_hdr, strlen(sig_hdr));
1711 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1714 /* Finalize header hash */
1715 exim_sha_update(&hhash_ctx, sig_hdr, strlen(sig_hdr));
1716 exim_sha_finish(&hhash_ctx, &hhash);
1720 debug_printf("PDKIM [%s] hh computed: ", sig->domain);
1721 pdkim_hexprint(hhash.data, hhash.len);
1724 /* Remember headers block for signing (when the library cannot do incremental) */
1725 if (ctx->mode == PDKIM_MODE_SIGN)
1726 (void) exim_rsa_data_append(&hdata, &hdata_alloc, sig_hdr);
1730 /* SIGNING ---------------------------------------------------------------- */
1731 if (ctx->mode == PDKIM_MODE_SIGN)
1734 const uschar * errstr;
1736 /* Import private key */
1737 if ((errstr = exim_rsa_signing_init(sig->rsa_privkey, &sctx)))
1739 DEBUG(D_acl) debug_printf("signing_init: %s\n", errstr);
1740 return PDKIM_ERR_RSA_PRIVKEY;
1743 /* Do signing. With OpenSSL we are signing the hash of headers just
1744 calculated, with GnuTLS we have to sign an entire block of headers
1745 (due to available interfaces) and it recalculates the hash internally. */
1747 #if defined(RSA_OPENSSL) || defined(RSA_GCRYPT)
1751 if ((errstr = exim_rsa_sign(&sctx, is_sha1, &hdata, &sig->sigdata)))
1753 DEBUG(D_acl) debug_printf("signing: %s\n", errstr);
1754 return PDKIM_ERR_RSA_SIGNING;
1759 debug_printf( "PDKIM [%s] b computed: ", sig->domain);
1760 pdkim_hexprint(sig->sigdata.data, sig->sigdata.len);
1763 if (!(sig->signature_header = pdkim_create_header(sig, TRUE)))
1764 return PDKIM_ERR_OOM;
1767 /* VERIFICATION ----------------------------------------------------------- */
1771 const uschar * errstr;
1773 char *dns_txt_name, *dns_txt_reply;
1775 /* Fetch public key for signing domain, from DNS */
1777 if (!(dns_txt_name = malloc(PDKIM_DNS_TXT_MAX_NAMELEN)))
1778 return PDKIM_ERR_OOM;
1780 if (!(dns_txt_reply = malloc(PDKIM_DNS_TXT_MAX_RECLEN)))
1783 return PDKIM_ERR_OOM;
1786 memset(dns_txt_reply, 0, PDKIM_DNS_TXT_MAX_RECLEN);
1787 memset(dns_txt_name , 0, PDKIM_DNS_TXT_MAX_NAMELEN);
1789 if (snprintf(dns_txt_name, PDKIM_DNS_TXT_MAX_NAMELEN,
1790 "%s._domainkey.%s.",
1791 sig->selector, sig->domain) >= PDKIM_DNS_TXT_MAX_NAMELEN)
1793 sig->verify_status = PDKIM_VERIFY_INVALID;
1794 sig->verify_ext_status = PDKIM_VERIFY_INVALID_BUFFER_SIZE;
1798 if ( ctx->dns_txt_callback(dns_txt_name, dns_txt_reply) != PDKIM_OK
1799 || dns_txt_reply[0] == '\0')
1801 sig->verify_status = PDKIM_VERIFY_INVALID;
1802 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE;
1809 "PDKIM >> Parsing public key record >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"
1811 pdkim_quoteprint(dns_txt_reply, strlen(dns_txt_reply));
1814 if (!(sig->pubkey = pdkim_parse_pubkey_record(ctx, dns_txt_reply)))
1816 sig->verify_status = PDKIM_VERIFY_INVALID;
1817 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD;
1819 DEBUG(D_acl) debug_printf(
1820 " Error while parsing public key record\n"
1821 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1825 DEBUG(D_acl) debug_printf(
1826 "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
1828 /* Import public key */
1829 if ((errstr = exim_rsa_verify_init(&sig->pubkey->key, &vctx)))
1831 DEBUG(D_acl) debug_printf("verify_init: %s\n", errstr);
1832 sig->verify_status = PDKIM_VERIFY_INVALID;
1833 sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_IMPORT;
1837 /* Check the signature */
1838 if ((errstr = exim_rsa_verify(&vctx, is_sha1, &hhash, &sig->sigdata)))
1840 DEBUG(D_acl) debug_printf("headers verify: %s\n", errstr);
1841 sig->verify_status = PDKIM_VERIFY_FAIL;
1842 sig->verify_ext_status = PDKIM_VERIFY_FAIL_MESSAGE;
1847 /* We have a winner! (if bodydhash was correct earlier) */
1848 if (sig->verify_status == PDKIM_VERIFY_NONE)
1849 sig->verify_status = PDKIM_VERIFY_PASS;
1855 debug_printf("PDKIM [%s] signature status: %s",
1856 sig->domain, pdkim_verify_status_str(sig->verify_status));
1857 if (sig->verify_ext_status > 0)
1858 debug_printf(" (%s)\n",
1859 pdkim_verify_ext_status_str(sig->verify_ext_status));
1865 free(dns_txt_reply);
1871 /* If requested, set return pointer to signature(s) */
1872 if (return_signatures)
1873 *return_signatures = ctx->sig;
1879 /* -------------------------------------------------------------------------- */
1881 DLLEXPORT pdkim_ctx *
1882 pdkim_init_verify(int(*dns_txt_callback)(char *, char *))
1884 pdkim_ctx *ctx = malloc(sizeof(pdkim_ctx));
1888 memset(ctx, 0, sizeof(pdkim_ctx));
1890 if (!(ctx->linebuf = malloc(PDKIM_MAX_BODY_LINE_LEN)))
1896 ctx->mode = PDKIM_MODE_VERIFY;
1897 ctx->dns_txt_callback = dns_txt_callback;
1903 /* -------------------------------------------------------------------------- */
1905 DLLEXPORT pdkim_ctx *
1906 pdkim_init_sign(char *domain, char *selector, char *rsa_privkey, int algo)
1909 pdkim_signature *sig;
1911 if (!domain || !selector || !rsa_privkey)
1914 if (!(ctx = malloc(sizeof(pdkim_ctx))))
1916 memset(ctx, 0, sizeof(pdkim_ctx));
1918 if (!(ctx->linebuf = malloc(PDKIM_MAX_BODY_LINE_LEN)))
1924 if (!(sig = malloc(sizeof(pdkim_signature))))
1930 memset(sig, 0, sizeof(pdkim_signature));
1932 sig->bodylength = -1;
1934 ctx->mode = PDKIM_MODE_SIGN;
1937 sig->domain = strdup(domain);
1938 sig->selector = strdup(selector);
1939 sig->rsa_privkey = strdup(rsa_privkey);
1942 if (!sig->domain || !sig->selector || !sig->rsa_privkey)
1945 exim_sha_init(&sig->body_hash, algo == PDKIM_ALGO_RSA_SHA1);
1949 pdkim_free_ctx(ctx);
1954 /* -------------------------------------------------------------------------- */
1957 pdkim_set_optional(pdkim_ctx *ctx,
1963 unsigned long created,
1964 unsigned long expires)
1966 pdkim_signature * sig = ctx->sig;
1969 if (!(sig->identity = strdup(identity)))
1970 return PDKIM_ERR_OOM;
1972 if (!(sig->sign_headers = strdup(sign_headers
1973 ? sign_headers : PDKIM_DEFAULT_SIGN_HEADERS)))
1974 return PDKIM_ERR_OOM;
1976 sig->canon_headers = canon_headers;
1977 sig->canon_body = canon_body;
1978 sig->bodylength = bodylength;
1979 sig->created = created;
1980 sig->expires = expires;
1994 #endif /*DISABLE_DKIM*/