X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/abe1010cc7d7d02629e1c9ca4a00240a44fe041e..df3def249f555f5e6cbfa1bf3fb1a20db4f48fcd:/src/src/pdkim/pdkim.c diff --git a/src/src/pdkim/pdkim.c b/src/src/pdkim/pdkim.c index 825a2f996..6e471a614 100644 --- a/src/src/pdkim/pdkim.c +++ b/src/src/pdkim/pdkim.c @@ -1,7 +1,8 @@ /* * PDKIM - a RFC4871 (DKIM) implementation * - * Copyright (C) 2009 - 2015 Tom Kistner + * Copyright (C) 2009 - 2016 Tom Kistner + * Copyright (C) 2016 Jeremy Harris * * http://duncanthrax.net/pdkim/ * @@ -20,19 +21,35 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include -#include -#include -#include +#include "../exim.h" -#include "../mytypes.h" -#include "pdkim.h" -#include "pdkim-rsa.h" -#include "polarssl/sha1.h" -#include "polarssl/sha2.h" -#include "polarssl/rsa.h" -#include "polarssl/base64.h" +#ifndef DISABLE_DKIM /* entire file */ + +#ifndef SUPPORT_TLS +# error Need SUPPORT_TLS for DKIM +#endif + +#include "crypt_ver.h" + +#ifdef RSA_OPENSSL +# include +# include +# include +#elif defined(RSA_GNUTLS) +# include +# include +# include +#endif + +#ifdef SHA_GNUTLS +# include +#elif defined(SHA_POLARSSL) +# include "polarssl/sha1.h" +# include "polarssl/sha2.h" +#endif + +#include "pdkim.h" #define PDKIM_SIGNATURE_VERSION "1" #define PDKIM_PUB_RECORD_VERSION "DKIM1" @@ -95,6 +112,7 @@ typedef struct pdkim_combined_canon_entry { int canon_headers; int canon_body; } pdkim_combined_canon_entry; + pdkim_combined_canon_entry pdkim_combined_canons[] = { { "simple/simple", PDKIM_CANON_SIMPLE, PDKIM_CANON_SIMPLE }, { "simple/relaxed", PDKIM_CANON_SIMPLE, PDKIM_CANON_RELAXED }, @@ -106,7 +124,11 @@ pdkim_combined_canon_entry pdkim_combined_canons[] = { }; -const char *pdkim_verify_status_str(int status) { +/* -------------------------------------------------------------------------- */ + +const char * +pdkim_verify_status_str(int status) +{ switch(status) { case PDKIM_VERIFY_NONE: return "PDKIM_VERIFY_NONE"; case PDKIM_VERIFY_INVALID: return "PDKIM_VERIFY_INVALID"; @@ -115,13 +137,17 @@ const char *pdkim_verify_status_str(int status) { default: return "PDKIM_VERIFY_UNKNOWN"; } } -const char *pdkim_verify_ext_status_str(int ext_status) { + +const char * +pdkim_verify_ext_status_str(int ext_status) +{ switch(ext_status) { case PDKIM_VERIFY_FAIL_BODY: return "PDKIM_VERIFY_FAIL_BODY"; case PDKIM_VERIFY_FAIL_MESSAGE: return "PDKIM_VERIFY_FAIL_MESSAGE"; case PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE: return "PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE"; case PDKIM_VERIFY_INVALID_BUFFER_SIZE: return "PDKIM_VERIFY_INVALID_BUFFER_SIZE"; - case PDKIM_VERIFY_INVALID_PUBKEY_PARSING: return "PDKIM_VERIFY_INVALID_PUBKEY_PARSING"; + case PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD: return "PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD"; + case PDKIM_VERIFY_INVALID_PUBKEY_IMPORT: return "PDKIM_VERIFY_INVALID_PUBKEY_IMPORT"; default: return "PDKIM_VERIFY_UNKNOWN"; } } @@ -129,57 +155,53 @@ const char *pdkim_verify_ext_status_str(int ext_status) { /* -------------------------------------------------------------------------- */ /* Print debugging functions */ -#ifdef PDKIM_DEBUG void -pdkim_quoteprint(FILE *stream, const char *data, int len, int lf) +pdkim_quoteprint(const char *data, int len, int lf) { int i; const unsigned char *p = (const unsigned char *)data; -for (i = 0; i 127) ) - fprintf(stream, "{%02x}", c); + debug_printf("{%02x}", c); else - fputc(c, stream); + debug_printf("%c", c); break; } } if (lf) - fputc('\n', stream); + debug_printf("\n"); } void -pdkim_hexprint(FILE *stream, const char *data, int len, int lf) +pdkim_hexprint(const char *data, int len, int lf) { int i; const unsigned char *p = (const unsigned char *)data; -for (i =0 ; ivalue = strdup(str))) return NULL; -if (base) - new_entry->next = base; -return new_entry; -} - /* -------------------------------------------------------------------------- */ /* A small "growing string" implementation to escape malloc/realloc hell */ -pdkim_str * +static pdkim_str * pdkim_strnew (const char *cstr) { unsigned int len = cstr ? strlen(cstr) : 0; @@ -236,7 +245,7 @@ else return p; } -char * +static char * pdkim_strncat(pdkim_str *str, const char *data, int len) { if ((str->allocated - str->len) < (len+1)) @@ -255,21 +264,13 @@ str->str[str->len] = '\0'; return str->str; } -char * +static char * pdkim_strcat(pdkim_str *str, const char *cstr) { return pdkim_strncat(str, cstr, strlen(cstr)); } -char * -pdkim_numcat(pdkim_str *str, unsigned long num) -{ -char minibuf[20]; -snprintf(minibuf, 20, "%lu", num); -return pdkim_strcat(str, minibuf); -} - -char * +static char * pdkim_strtrim(pdkim_str *str) { char *p = str->str; @@ -286,7 +287,7 @@ str->len = strlen(str->str); return str->str; } -char * +static char * pdkim_strclear(pdkim_str *str) { str->str[0] = '\0'; @@ -294,7 +295,7 @@ str->len = 0; return str->str; } -void +static void pdkim_strfree(pdkim_str *str) { if (!str) return; @@ -306,7 +307,7 @@ free(str); /* -------------------------------------------------------------------------- */ -void +static void pdkim_free_pubkey(pdkim_pubkey *pub) { if (pub) @@ -317,7 +318,7 @@ if (pub) if (pub->keytype ) free(pub->keytype); if (pub->srvtype ) free(pub->srvtype); if (pub->notes ) free(pub->notes); - if (pub->key ) free(pub->key); +/* if (pub->key ) free(pub->key); */ free(pub); } } @@ -325,7 +326,7 @@ if (pub) /* -------------------------------------------------------------------------- */ -void +static void pdkim_free_sig(pdkim_signature *sig) { if (sig) @@ -341,8 +342,6 @@ if (sig) free(c); } - if (sig->sigdata ) free(sig->sigdata); - if (sig->bodyhash ) free(sig->bodyhash); if (sig->selector ) free(sig->selector); if (sig->domain ) free(sig->domain); if (sig->identity ) free(sig->identity); @@ -351,8 +350,6 @@ if (sig) if (sig->rsa_privkey ) free(sig->rsa_privkey); if (sig->sign_headers ) free(sig->sign_headers); if (sig->signature_header) free(sig->signature_header); - if (sig->sha1_body ) free(sig->sha1_body); - if (sig->sha2_body ) free(sig->sha2_body); if (sig->pubkey) pdkim_free_pubkey(sig->pubkey); @@ -390,7 +387,7 @@ if (ctx) "start". Returns the position of the header name in the list. */ -int +static int header_name_match(const char *header, char *tick, int do_tick) @@ -453,7 +450,7 @@ return rc; /* Performs "relaxed" canonicalization of a header. The returned pointer needs to be free()d. */ -char * +static char * pdkim_relax_header (char *header, int crlf) { BOOL past_field_name = FALSE; @@ -504,7 +501,7 @@ return relaxed; /* -------------------------------------------------------------------------- */ #define PDKIM_QP_ERROR_DECODE -1 -char * +static char * pdkim_decode_qp_char(char *qp_p, int *c) { char *initial_pos = qp_p; @@ -517,7 +514,7 @@ if (isxdigit(*qp_p) && isxdigit(qp_p[1])) { /* Do hex conversion */ *c = (isdigit(*qp_p) ? *qp_p - '0' : toupper(*qp_p) - 'A' + 10) << 4; - *c != isdigit(qp_p[1]) ? qp_p[1] - '0' : toupper(qp_p[1]) - 'A' + 10; + *c |= isdigit(qp_p[1]) ? qp_p[1] - '0' : toupper(qp_p[1]) - 'A' + 10; return qp_p + 2; } @@ -529,7 +526,7 @@ return initial_pos; /* -------------------------------------------------------------------------- */ -char * +static char * pdkim_decode_qp(char *str) { int nchar = 0; @@ -563,21 +560,21 @@ return n; /* -------------------------------------------------------------------------- */ -char * +static char * pdkim_decode_base64(char *str, int *num_decoded) { int dlen = 0; char *res; +int old_pool = store_pool; -base64_decode(NULL, &dlen, (unsigned char *)str, strlen(str)); +/* There is a store-reset between header & body reception +so cannot use the main pool */ -if (!(res = malloc(dlen+1))) - return NULL; -if (base64_decode((unsigned char *)res, &dlen, (unsigned char *)str, strlen(str)) != 0) - { - free(res); - return NULL; - } +store_pool = POOL_PERM; +dlen = b64decode(US str, USS &res); +store_pool = old_pool; + +if (dlen < 0) return NULL; if (num_decoded) *num_decoded = dlen; return res; @@ -586,22 +583,16 @@ return res; /* -------------------------------------------------------------------------- */ -char * +static char * pdkim_encode_base64(char *str, int num) { -int dlen = 0; -char *res; - -base64_encode(NULL, &dlen, (unsigned char *)str, num); +char * ret; +int old_pool = store_pool; -if (!(res = malloc(dlen+1))) - return NULL; -if (base64_encode((unsigned char *)res, &dlen, (unsigned char *)str, num) != 0) - { - free(res); - return NULL; - } -return res; +store_pool = POOL_PERM; +ret = CS b64encode(US str, num); +store_pool = old_pool; +return ret; } @@ -610,7 +601,7 @@ return res; #define PDKIM_HDR_TAG 1 #define PDKIM_HDR_VALUE 2 -pdkim_signature * +static pdkim_signature * pdkim_parse_sig_header(pdkim_ctx *ctx, char *raw_hdr) { pdkim_signature *sig ; @@ -692,10 +683,7 @@ for (p = raw_hdr; ; p++) { pdkim_strtrim(cur_val); -#ifdef PDKIM_DEBUG - if (ctx->debug_stream) - fprintf(ctx->debug_stream, " %s=%s\n", cur_tag->str, cur_val->str); -#endif + DEBUG(D_acl) debug_printf(" %s=%s\n", cur_tag->str, cur_val->str); switch (cur_tag->str[0]) { @@ -755,10 +743,7 @@ for (p = raw_hdr; ; p++) case 'z': sig->copiedheaders = pdkim_decode_qp(cur_val->str); break; default: -#ifdef PDKIM_DEBUG - if (ctx->debug_stream) - fprintf(ctx->debug_stream, " Unknown tag encountered\n"); -#endif + DEBUG(D_acl) debug_printf(" Unknown tag encountered\n"); break; } } @@ -797,20 +782,28 @@ q--; while (q > sig->rawsig_no_b_val && (*q == '\r' || *q == '\n')) *q = '\0'; q--; /*XXX questionable code layout; possible bug */ -#ifdef PDKIM_DEBUG -if (ctx->debug_stream) +DEBUG(D_acl) { - fprintf(ctx->debug_stream, + debug_printf( "PDKIM >> Raw signature w/o b= tag value >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); - pdkim_quoteprint(ctx->debug_stream, - sig->rawsig_no_b_val, - strlen(sig->rawsig_no_b_val), 1); - fprintf(ctx->debug_stream, + pdkim_quoteprint(sig->rawsig_no_b_val, strlen(sig->rawsig_no_b_val), 1); + debug_printf( "PDKIM >> Sig size: %4d bits\n", sig->sigdata_len*8); - fprintf(ctx->debug_stream, + debug_printf( "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); } -#endif + +#ifdef SHA_OPENSSL + +SHA1_Init (&sig->sha1_body); +SHA256_Init(&sig->sha2_body); + +#elif defined(SHA_GNUTLS) + +gnutls_hash_init(&sig->sha_body, + sig->algo == PDKIM_ALGO_RSA_SHA1 ? GNUTLS_DIG_SHA1 : GNUTLS_DIG_SHA256); + +#elif defined(SHA_POLARSSL) if ( !(sig->sha1_body = malloc(sizeof(sha1_context))) || !(sig->sha2_body = malloc(sizeof(sha2_context))) @@ -823,13 +816,15 @@ if ( !(sig->sha1_body = malloc(sizeof(sha1_context))) sha1_starts(sig->sha1_body); sha2_starts(sig->sha2_body, 0); +#endif /* SHA impl */ + return sig; } /* -------------------------------------------------------------------------- */ -pdkim_pubkey * +static pdkim_pubkey * pdkim_parse_pubkey_record(pdkim_ctx *ctx, char *raw_record) { pdkim_pubkey *pub; @@ -886,10 +881,7 @@ for (p = raw_record; ; p++) if (cur_tag->len > 0) { pdkim_strtrim(cur_val); -#ifdef PDKIM_DEBUG - if (ctx->debug_stream) - fprintf(ctx->debug_stream, " %s=%s\n", cur_tag->str, cur_val->str); -#endif + DEBUG(D_acl) debug_printf(" %s=%s\n", cur_tag->str, cur_val->str); switch (cur_tag->str[0]) { @@ -916,10 +908,7 @@ for (p = raw_record; ; p++) if (strchr(cur_val->str, 's') != NULL) pub->no_subdomaining = 1; break; default: -#ifdef PDKIM_DEBUG - if (ctx->debug_stream) - fprintf(ctx->debug_stream, " Unknown tag encountered\n"); -#endif + DEBUG(D_acl) debug_printf(" Unknown tag encountered\n"); break; } } @@ -952,7 +941,7 @@ return NULL; /* -------------------------------------------------------------------------- */ -int +static int pdkim_update_bodyhash(pdkim_ctx *ctx, const char *data, int len) { pdkim_signature *sig = ctx->sig; @@ -1013,16 +1002,23 @@ while (sig) if (canon_len > 0) { +#ifdef SHA_GNUTLS + gnutls_hash(sig->sha_body, canon_data, canon_len); +#else if (sig->algo == PDKIM_ALGO_RSA_SHA1) - sha1_update(sig->sha1_body, (unsigned char *)canon_data, canon_len); +# ifdef SHA_OPENSSL + SHA1_Update (&sig->sha1_body, canon_data, canon_len); else - sha2_update(sig->sha2_body, (unsigned char *)canon_data, canon_len); + SHA256_Update(&sig->sha2_body, canon_data, canon_len); +# elif defined(SHA_POLARSSL) + sha1_update(sig->sha1_body, US canon_data, canon_len); + else + sha2_update(sig->sha2_body, US canon_data, canon_len); +# endif +#endif sig->signed_body_bytes += canon_len; -#ifdef PDKIM_DEBUG - if (ctx->debug_stream) - pdkim_quoteprint(ctx->debug_stream, canon_data, canon_len, 1); -#endif + DEBUG(D_acl) pdkim_quoteprint(canon_data, canon_len, 1); } sig = sig->next; @@ -1035,40 +1031,44 @@ return PDKIM_OK; /* -------------------------------------------------------------------------- */ -int +static int pdkim_finish_bodyhash(pdkim_ctx *ctx) { -pdkim_signature *sig = ctx->sig; +pdkim_signature *sig; /* Traverse all signatures */ -while (sig) +for (sig = ctx->sig; sig; sig = sig->next) { /* Finish hashes */ - unsigned char bh[32]; /* SHA-256 = 32 Bytes, SHA-1 = 20 Bytes */ + uschar bh[32]; /* SHA-256 = 32 Bytes, SHA-1 = 20 Bytes */ +#ifdef SHA_GNUTLS + gnutls_hash_output(sig->sha_body, bh); +#else if (sig->algo == PDKIM_ALGO_RSA_SHA1) +# ifdef SHA_OPENSSL + SHA1_Final (bh, &sig->sha1_body); + else + SHA256_Final(bh, &sig->sha2_body); +# elif defined(SHA_POLARSSL) sha1_finish(sig->sha1_body, bh); else sha2_finish(sig->sha2_body, bh); +# endif +#endif -#ifdef PDKIM_DEBUG - if (ctx->debug_stream) + DEBUG(D_acl) { - fprintf(ctx->debug_stream, "PDKIM [%s] Body bytes hashed: %lu\n", - sig->domain, sig->signed_body_bytes); - fprintf(ctx->debug_stream, "PDKIM [%s] bh computed: ", sig->domain); - pdkim_hexprint(ctx->debug_stream, (char *)bh, - (sig->algo == PDKIM_ALGO_RSA_SHA1)?20:32, 1); + debug_printf("PDKIM [%s] Body bytes hashed: %lu\n" + "PDKIM [%s] bh computed: ", + sig->domain, sig->signed_body_bytes, sig->domain); + pdkim_hexprint((char *)bh, sig->algo == PDKIM_ALGO_RSA_SHA1 ? 20 : 32, 1); } -#endif /* SIGNING -------------------------------------------------------------- */ if (ctx->mode == PDKIM_MODE_SIGN) { - sig->bodyhash_len = (sig->algo == PDKIM_ALGO_RSA_SHA1)?20:32; - - if (!(sig->bodyhash = malloc(sig->bodyhash_len))) - return PDKIM_ERR_OOM; - memcpy(sig->bodyhash, bh, sig->bodyhash_len); + sig->bodyhash_len = sig->algo == PDKIM_ALGO_RSA_SHA1 ? 20:32; + sig->bodyhash = CS string_copyn(US bh, sig->bodyhash_len); /* If bodylength limit is set, and we have received less bytes than the requested amount, effectively remove the limit tag. */ @@ -1083,30 +1083,21 @@ while (sig) if (memcmp(bh, sig->bodyhash, (sig->algo == PDKIM_ALGO_RSA_SHA1)?20:32) == 0) { -#ifdef PDKIM_DEBUG - if (ctx->debug_stream) - fprintf(ctx->debug_stream, "PDKIM [%s] Body hash verified OK\n", - sig->domain); -#endif + DEBUG(D_acl) debug_printf("PDKIM [%s] Body hash verified OK\n", sig->domain); } else { -#ifdef PDKIM_DEBUG - if (ctx->debug_stream) + DEBUG(D_acl) { - fprintf(ctx->debug_stream, "PDKIM [%s] bh signature: ", sig->domain); - pdkim_hexprint(ctx->debug_stream, sig->bodyhash, - (sig->algo == PDKIM_ALGO_RSA_SHA1)?20:32, 1); - fprintf(ctx->debug_stream, "PDKIM [%s] Body hash did NOT verify\n", - sig->domain); + debug_printf("PDKIM [%s] bh signature: ", sig->domain); + pdkim_hexprint(sig->bodyhash, + sig->algo == PDKIM_ALGO_RSA_SHA1 ? 20 : 32, 1); + debug_printf("PDKIM [%s] Body hash did NOT verify\n", sig->domain); } -#endif sig->verify_status = PDKIM_VERIFY_FAIL; sig->verify_ext_status = PDKIM_VERIFY_FAIL_BODY; } } - - sig = sig->next; } return PDKIM_OK; @@ -1117,39 +1108,41 @@ return PDKIM_OK; /* -------------------------------------------------------------------------- */ /* Callback from pdkim_feed below for processing complete body lines */ -int +static int pdkim_bodyline_complete(pdkim_ctx *ctx) { char *p = ctx->linebuf; int n = ctx->linebuf_offset; +pdkim_signature *sig = ctx->sig; /*XXX assumes only one sig */ /* Ignore extra data if we've seen the end-of-data marker */ if (ctx->seen_eod) goto BAIL; /* We've always got one extra byte to stuff a zero ... */ -ctx->linebuf[(ctx->linebuf_offset)] = '\0'; +ctx->linebuf[ctx->linebuf_offset] = '\0'; -if (ctx->input_mode == PDKIM_INPUT_SMTP) +/* Terminate on EOD marker */ +if (memcmp(p, ".\r\n", 3) == 0) { - /* Terminate on EOD marker */ - if (memcmp(p, ".\r\n", 3) == 0) - { - /* In simple body mode, if any empty lines were buffered, - replace with one. rfc 4871 3.4.3 */ - if ( ctx->sig && ctx->sig->canon_body == PDKIM_CANON_SIMPLE - && ctx->num_buffered_crlf > 0 - ) - pdkim_update_bodyhash(ctx, "\r\n", 2); + /* In simple body mode, if any empty lines were buffered, + replace with one. rfc 4871 3.4.3 */ + /*XXX checking the signed-body-bytes is a gross hack; I think + it indicates that all linebreaks should be buffered, including + the one terminating a text line */ + if ( sig && sig->canon_body == PDKIM_CANON_SIMPLE + && sig->signed_body_bytes == 0 + && ctx->num_buffered_crlf > 0 + ) + pdkim_update_bodyhash(ctx, "\r\n", 2); - ctx->seen_eod = 1; - goto BAIL; - } - /* Unstuff dots */ - if (memcmp(p, "..", 2) == 0) - { - p++; - n--; - } + ctx->seen_eod = TRUE; + goto BAIL; + } +/* Unstuff dots */ +if (memcmp(p, "..", 2) == 0) + { + p++; + n--; } /* Empty lines need to be buffered until we find a non-empty line */ @@ -1159,9 +1152,7 @@ if (memcmp(p, "\r\n", 2) == 0) goto BAIL; } -if ( ctx->sig - && ctx->sig->canon_body == PDKIM_CANON_RELAXED - ) +if (sig && sig->canon_body == PDKIM_CANON_RELAXED) { /* Lines with just spaces need to be buffered too */ char *check = p; @@ -1198,11 +1189,9 @@ return PDKIM_OK; /* Callback from pdkim_feed below for processing complete headers */ #define DKIM_SIGNATURE_HEADERNAME "DKIM-Signature:" -int +static int pdkim_header_complete(pdkim_ctx *ctx) { -pdkim_signature *sig = ctx->sig; - /* Special case: The last header can have an extra \r appended */ if ( (ctx->cur_header->len > 1) && (ctx->cur_header->str[(ctx->cur_header->len)-1] == '\r') ) @@ -1216,7 +1205,10 @@ if (ctx->num_headers > PDKIM_MAX_HEADERS) goto BAIL; /* SIGNING -------------------------------------------------------------- */ if (ctx->mode == PDKIM_MODE_SIGN) - for ( ; sig; sig = sig->next) /* Traverse all signatures */ + { + pdkim_signature *sig; + + for (sig = ctx->sig; sig; sig = sig->next) /* Traverse all signatures */ if (header_name_match(ctx->cur_header->str, sig->sign_headers? sig->sign_headers: @@ -1230,7 +1222,9 @@ if (ctx->mode == PDKIM_MODE_SIGN) return PDKIM_ERR_OOM; sig->headers = list; } + } +/* VERIFICATION ----------------------------------------------------------- */ /* DKIM-Signature: headers are added to the verification list */ if (ctx->mode == PDKIM_MODE_VERIFY) { @@ -1241,11 +1235,8 @@ if (ctx->mode == PDKIM_MODE_VERIFY) pdkim_signature *new_sig; /* Create and chain new signature block */ -#ifdef PDKIM_DEBUG - if (ctx->debug_stream) - fprintf(ctx->debug_stream, + DEBUG(D_acl) debug_printf( "PDKIM >> Found sig, trying to parse >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); -#endif if ((new_sig = pdkim_parse_sig_header(ctx, ctx->cur_header->str))) { @@ -1258,15 +1249,10 @@ if (ctx->mode == PDKIM_MODE_VERIFY) last_sig->next = new_sig; } } -#ifdef PDKIM_DEBUG else - if (ctx->debug_stream) - { - fprintf(ctx->debug_stream, "Error while parsing signature header\n"); - fprintf(ctx->debug_stream, + DEBUG(D_acl) debug_printf( + "Error while parsing signature header\n" "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); - } -#endif } /* every other header is stored for signature verification */ @@ -1302,7 +1288,7 @@ for (p = 0; ppast_headers) { /* Processing body byte */ - ctx->linebuf[(ctx->linebuf_offset)++] = c; + ctx->linebuf[ctx->linebuf_offset++] = c; if (c == '\n') { int rc = pdkim_bodyline_complete(ctx); /* End of line */ @@ -1323,17 +1309,14 @@ for (p = 0; ppast_headers = 1; + ctx->past_headers = TRUE; ctx->seen_lf = 0; -#ifdef PDKIM_DEBUG - if (ctx->debug_stream) - fprintf(ctx->debug_stream, + DEBUG(D_acl) debug_printf( "PDKIM >> Hashed body data, canonicalized >>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); -#endif continue; } else - ctx->seen_lf = 1; + ctx->seen_lf = TRUE; } else if (ctx->seen_lf) { @@ -1342,7 +1325,7 @@ for (p = 0; pseen_lf = 0; + ctx->seen_lf = FALSE; } } @@ -1376,7 +1359,7 @@ return PDKIM_OK; * "pad" * * no guarantees are made for output given out-of range input. like tag - * names loinger than 78, or bogus col. Input is assumed to be free of line breaks. + * names longer than 78, or bogus col. Input is assumed to be free of line breaks. */ static char * @@ -1482,7 +1465,7 @@ return str->str; /* -------------------------------------------------------------------------- */ -char * +static char * pdkim_create_header(pdkim_signature *sig, int final) { char *rc = NULL; @@ -1607,8 +1590,6 @@ rc = strdup(hdr->str); BAIL: pdkim_strfree(hdr); if (canon_all) pdkim_strfree(canon_all); -if (base64_bh) free(base64_bh); -if (base64_b ) free(base64_b); return rc; } @@ -1631,21 +1612,8 @@ if (ctx->cur_header && ctx->cur_header->len) pdkim_update_bodyhash(ctx, "\r\n", 2); } else - { - /* For non-smtp input, check if there's an unfinished line in the - body line buffer. If that is the case, we must add a CRLF to the - hash to properly terminate the message. */ - if ((ctx->input_mode == PDKIM_INPUT_NORMAL) && ctx->linebuf_offset) - { - pdkim_update_bodyhash(ctx, ctx->linebuf, ctx->linebuf_offset); - pdkim_update_bodyhash(ctx, "\r\n", 2); - } -#ifdef PDKIM_DEBUG - if (ctx->debug_stream) - fprintf(ctx->debug_stream, + DEBUG(D_acl) debug_printf( "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); -#endif - } /* Build (and/or evaluate) body hash */ if (pdkim_finish_bodyhash(ctx) != PDKIM_OK) @@ -1659,22 +1627,44 @@ if (ctx->mode == PDKIM_MODE_SIGN) while (sig) { +#ifdef SHA_OPENSSL + SHA_CTX sha1_headers; + SHA256_CTX sha2_headers; +#elif defined(SHA_GNUTLS) + gnutls_hash_hd_t sha_headers; +#elif defined(SHA_POLARSSL) sha1_context sha1_headers; sha2_context sha2_headers; +#endif + char *sig_hdr; char headerhash[32]; +#ifdef RSA_GNUTLS + uschar * hdata = NULL; + int hdata_alloc = 0; + int hdata_size = 0; +#endif + +#ifdef SHA_GNUTLS + gnutls_hash_init(&sha_headers, + sig->algo == PDKIM_ALGO_RSA_SHA1 ? GNUTLS_DIG_SHA1 : GNUTLS_DIG_SHA256); +#else if (sig->algo == PDKIM_ALGO_RSA_SHA1) +# ifdef SHA_OPENSSL + SHA1_Init(&sha1_headers); + else + SHA256_Init(&sha2_headers); +# elif defined(SHA_POLARSSL) sha1_starts(&sha1_headers); else sha2_starts(&sha2_headers, 0); - -#ifdef PDKIM_DEBUG - if (ctx->debug_stream) - fprintf(ctx->debug_stream, - "PDKIM >> Hashed header data, canonicalized, in sequence >>>>>>>>>>>>>>\n"); +# endif #endif + DEBUG(D_acl) debug_printf( + "PDKIM >> Hashed header data, canonicalized, in sequence >>>>>>>>>>>>>>\n"); + /* SIGNING ---------------------------------------------------------------- */ /* When signing, walk through our header list and add them to the hash. As we go, construct a list of the header's names to use for the h= parameter. */ @@ -1700,15 +1690,27 @@ while (sig) return PDKIM_ERR_OOM; /* Feed header to the hash algorithm */ +#ifdef SHA_GNUTLS + gnutls_hash(sha_headers, rh, strlen(rh)); +#else if (sig->algo == PDKIM_ALGO_RSA_SHA1) - sha1_update(&(sha1_headers), (unsigned char *)rh, strlen(rh)); +# ifdef SHA_OPENSSL + SHA1_Update (&sha1_headers, rh, strlen(rh)); else - sha2_update(&(sha2_headers), (unsigned char *)rh, strlen(rh)); + SHA256_Update(&sha2_headers, rh, strlen(rh)); +# elif defined(SHA_POLARSSL) + sha1_update(&sha1_headers, US rh, strlen(rh)); + else + sha2_update(&sha2_headers, US rh, strlen(rh)); +# endif +#endif -#ifdef PDKIM_DEBUG - if (ctx->debug_stream) - pdkim_quoteprint(ctx->debug_stream, rh, strlen(rh), 1); +#ifdef RSA_GNUTLS + /* Remember headers block for signing */ + hdata = string_append(hdata, &hdata_alloc, &hdata_size, 1, rh); #endif + + DEBUG(D_acl) pdkim_quoteprint(rh, strlen(rh), 1); free(rh); } } @@ -1749,15 +1751,22 @@ while (sig) return PDKIM_ERR_OOM; /* Feed header to the hash algorithm */ +#ifdef SHA_GNUTLS + gnutls_hash(sha_headers, rh, strlen(rh)); +#else if (sig->algo == PDKIM_ALGO_RSA_SHA1) - sha1_update(&sha1_headers, (unsigned char *)rh, strlen(rh)); +# ifdef SHA_OPENSSL + SHA1_Update (&sha1_headers, rh, strlen(rh)); else - sha2_update(&sha2_headers, (unsigned char *)rh, strlen(rh)); - -#ifdef PDKIM_DEBUG - if (ctx->debug_stream) - pdkim_quoteprint(ctx->debug_stream, rh, strlen(rh), 1); + SHA256_Update(&sha2_headers, rh, strlen(rh)); +# elif defined(SHA_POLARSSL) + sha1_update(&sha1_headers, US rh, strlen(rh)); + else + sha2_update(&sha2_headers, US rh, strlen(rh)); +# endif #endif + + DEBUG(D_acl) pdkim_quoteprint(rh, strlen(rh), 1); free(rh); hdrs->tag = 1; break; @@ -1769,11 +1778,8 @@ while (sig) free(b); } -#ifdef PDKIM_DEBUG - if (ctx->debug_stream) - fprintf(ctx->debug_stream, + DEBUG(D_acl) debug_printf( "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); -#endif /* SIGNING ---------------------------------------------------------------- */ if (ctx->mode == PDKIM_MODE_SIGN) @@ -1805,81 +1811,156 @@ while (sig) sig_hdr = relaxed_hdr; } -#ifdef PDKIM_DEBUG - if (ctx->debug_stream) + DEBUG(D_acl) { - fprintf(ctx->debug_stream, + debug_printf( "PDKIM >> Signed DKIM-Signature header, canonicalized >>>>>>>>>>>>>>>>>\n"); - pdkim_quoteprint(ctx->debug_stream, sig_hdr, strlen(sig_hdr), 1); - fprintf(ctx->debug_stream, + pdkim_quoteprint(sig_hdr, strlen(sig_hdr), 1); + debug_printf( "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); } -#endif /* Finalize header hash */ +#ifdef SHA_GNUTLS + gnutls_hash(sha_headers, sig_hdr, strlen(sig_hdr)); + gnutls_hash_output(sha_headers, headerhash); +#else if (sig->algo == PDKIM_ALGO_RSA_SHA1) +# ifdef SHA_OPENSSL { - sha1_update(&sha1_headers, (unsigned char *)sig_hdr, strlen(sig_hdr)); - sha1_finish(&sha1_headers, (unsigned char *)headerhash); - -#ifdef PDKIM_DEBUG - if (ctx->debug_stream) - { - fprintf(ctx->debug_stream, "PDKIM [%s] hh computed: ", sig->domain); - pdkim_hexprint(ctx->debug_stream, headerhash, 20, 1); - } -#endif + SHA1_Update(&sha1_headers, sig_hdr, strlen(sig_hdr)); + SHA1_Final(US headerhash, &sha1_headers); } else { - sha2_update(&sha2_headers, (unsigned char *)sig_hdr, strlen(sig_hdr)); - sha2_finish(&sha2_headers, (unsigned char *)headerhash); - -#ifdef PDKIM_DEBUG - if (ctx->debug_stream) - { - fprintf(ctx->debug_stream, "PDKIM [%s] hh computed: ", sig->domain); - pdkim_hexprint(ctx->debug_stream, headerhash, 32, 1); - } + SHA256_Update(&sha2_headers, sig_hdr, strlen(sig_hdr)); + SHA256_Final(US headerhash, &sha2_headers); + } +# elif defined(SHA_POLARSSL) + { + sha1_update(&sha1_headers, US sig_hdr, strlen(sig_hdr)); + sha1_finish(&sha1_headers, US headerhash); + } + else + { + sha2_update(&sha2_headers, US sig_hdr, strlen(sig_hdr)); + sha2_finish(&sha2_headers, US headerhash); + } +# endif #endif + + DEBUG(D_acl) + { + debug_printf("PDKIM [%s] hh computed: ", sig->domain); + pdkim_hexprint(headerhash, sig->algo == PDKIM_ALGO_RSA_SHA1 ? 20:32, 1); } +#ifdef RSA_GNUTLS + if (ctx->mode == PDKIM_MODE_SIGN) + hdata = string_append(hdata, &hdata_alloc, &hdata_size, 1, sig_hdr); +#endif + free(sig_hdr); /* SIGNING ---------------------------------------------------------------- */ if (ctx->mode == PDKIM_MODE_SIGN) { - rsa_context rsa; +#ifdef RSA_OPENSSL + RSA * rsa; + uschar * p, * q; + int len; +#elif defined(RSA_GNUTLS) + gnutls_x509_privkey_t rsa; + gnutls_datum_t k; + int rc; + size_t sigsize; +#endif - rsa_init(&rsa, RSA_PKCS_V15, 0); + /* Import private key */ +#ifdef RSA_OPENSSL - /* Perform private key operation */ - if (rsa_parse_key(&rsa, (unsigned char *)sig->rsa_privkey, - strlen(sig->rsa_privkey), NULL, 0) != 0) + if ( !(p = Ustrstr(sig->rsa_privkey, "-----BEGIN RSA PRIVATE KEY-----")) + || !(q = Ustrstr(p+=31, "-----END RSA PRIVATE KEY-----")) + ) + return PDKIM_SIGN_PRIVKEY_WRAP; + *q = '\0'; + if ((len = b64decode(p, &p)) < 0) + { + DEBUG(D_acl) debug_printf("b64decode failed\n"); + return PDKIM_SIGN_PRIVKEY_B64D; + } + if (!(rsa = d2i_RSAPrivateKey(NULL, CUSS &p, len))) + { + DEBUG(D_acl) + { + char ssl_errstring[256]; + ERR_error_string(ERR_get_error(), ssl_errstring); + debug_printf("d2i_RSAPrivateKey: %s\n", ssl_errstring); + } return PDKIM_ERR_RSA_PRIVKEY; + } - sig->sigdata_len = mpi_size(&(rsa.N)); - if (!(sig->sigdata = malloc(sig->sigdata_len))) - return PDKIM_ERR_OOM; +#elif defined(RSA_GNUTLS) + + k.data = sig->rsa_privkey; + k.size = strlen(sig->rsa_privkey); + if ( (rc = gnutls_x509_privkey_init(&rsa)) != GNUTLS_E_SUCCESS + || (rc = gnutls_x509_privkey_import2(rsa, &k, + GNUTLS_X509_FMT_PEM, NULL, GNUTLS_PKCS_PLAIN)) != GNUTLS_E_SUCCESS + ) + { + DEBUG(D_acl) debug_printf("gnutls_x509_privkey_import2: %s\n", + gnutls_strerror(rc)); + return PDKIM_ERR_RSA_PRIVKEY; + } + +#endif + + + /* Allocate mem for signature */ +#ifdef RSA_OPENSSL + sig->sigdata = store_get(RSA_size(rsa)); +#elif defined(RSA_GNUTLS) + k.data = hdata; + k.size = hdata_size; + (void) gnutls_x509_privkey_sign_data(rsa, + sig->algo == PDKIM_ALGO_RSA_SHA1 ? GNUTLS_DIG_SHA1 : GNUTLS_DIG_SHA256, + 0, &k, NULL, &sigsize); + sig->sigdata = store_get(sig->sigdata_len = sigsize); +#endif - if (rsa_pkcs1_sign( &rsa, RSA_PRIVATE, - ((sig->algo == PDKIM_ALGO_RSA_SHA1)? - SIG_RSA_SHA1:SIG_RSA_SHA256), - 0, - (unsigned char *)headerhash, - (unsigned char *)sig->sigdata ) != 0) + /* Do signing */ +#ifdef RSA_OPENSSL + + if (RSA_sign(sig->algo == PDKIM_ALGO_RSA_SHA1 ? NID_sha1 : NID_sha256, + CUS headerhash, sig->algo == PDKIM_ALGO_RSA_SHA1 ? 20 : 32, + US sig->sigdata, (unsigned int *)&sig->sigdata_len, + rsa) != 1) return PDKIM_ERR_RSA_SIGNING; + RSA_free(rsa); - rsa_free(&rsa); +#elif defined(RSA_GNUTLS) -#ifdef PDKIM_DEBUG - if (ctx->debug_stream) + if ((rc = gnutls_x509_privkey_sign_data(rsa, + sig->algo == PDKIM_ALGO_RSA_SHA1 ? GNUTLS_DIG_SHA1 : GNUTLS_DIG_SHA256, + 0, &k, sig->sigdata, &sigsize)) != GNUTLS_E_SUCCESS + ) { - fprintf(ctx->debug_stream, "PDKIM [%s] b computed: ", sig->domain); - pdkim_hexprint(ctx->debug_stream, sig->sigdata, sig->sigdata_len, 1); + DEBUG(D_acl) debug_printf("gnutls_x509_privkey_sign_data: %s\n", + gnutls_strerror(rc)); + return PDKIM_ERR_RSA_SIGNING; } + gnutls_x509_privkey_deinit(rsa); + #endif + + DEBUG(D_acl) + { + debug_printf( "PDKIM [%s] b computed: ", sig->domain); + pdkim_hexprint(sig->sigdata, sig->sigdata_len, 1); + } + if (!(sig->signature_header = pdkim_create_header(ctx->sig, 1))) return PDKIM_ERR_OOM; } @@ -1887,10 +1968,21 @@ while (sig) /* VERIFICATION ----------------------------------------------------------- */ else { - rsa_context rsa; +#ifdef RSA_OPENSSL + RSA * rsa; + const unsigned char * p; +#elif defined(RSA_GNUTLS) + gnutls_pubkey_t rsa; + gnutls_datum_t k, s; + int rc; +#endif char *dns_txt_name, *dns_txt_reply; - rsa_init(&rsa, RSA_PKCS_V15, 0); +#ifdef RSA_GNUTLS + gnutls_pubkey_init(&rsa); +#endif + + /* Fetch public key for signing domain, from DNS */ if (!(dns_txt_name = malloc(PDKIM_DNS_TXT_MAX_NAMELEN))) return PDKIM_ERR_OOM; @@ -1921,56 +2013,84 @@ while (sig) goto NEXT_VERIFY; } -#ifdef PDKIM_DEBUG - if (ctx->debug_stream) + DEBUG(D_acl) { - fprintf(ctx->debug_stream, - "PDKIM >> Parsing public key record >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); - fprintf(ctx->debug_stream, " Raw record: "); - pdkim_quoteprint(ctx->debug_stream, dns_txt_reply, strlen(dns_txt_reply), 1); + debug_printf( + "PDKIM >> Parsing public key record >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n" + " Raw record: "); + pdkim_quoteprint(dns_txt_reply, strlen(dns_txt_reply), 1); } -#endif if (!(sig->pubkey = pdkim_parse_pubkey_record(ctx, dns_txt_reply))) { sig->verify_status = PDKIM_VERIFY_INVALID; - sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_PARSING; + sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD; -#ifdef PDKIM_DEBUG - if (ctx->debug_stream) - { - fprintf(ctx->debug_stream, " Error while parsing public key record\n"); - fprintf(ctx->debug_stream, + DEBUG(D_acl) debug_printf( + " Error while parsing public key record\n" "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); - } -#endif goto NEXT_VERIFY; } -#ifdef PDKIM_DEBUG - if (ctx->debug_stream) - fprintf(ctx->debug_stream, + DEBUG(D_acl) debug_printf( "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); -#endif - if (rsa_parse_public_key(&rsa, - (unsigned char *)sig->pubkey->key, - sig->pubkey->key_len) != 0) + /* Import public key */ +#ifdef RSA_OPENSSL + + p = CUS sig->pubkey->key; + if (!(rsa = d2i_RSA_PUBKEY(NULL, &p, (long) sig->pubkey->key_len))) + +#elif defined(RSA_GNUTLS) + + k.data = sig->pubkey->key; + k.size = sig->pubkey->key_len; + if ((rc = gnutls_pubkey_import(rsa, &k, GNUTLS_X509_FMT_DER)) + != GNUTLS_E_SUCCESS) + +#endif { + DEBUG(D_acl) + { +#ifdef RSA_OPENSSL + long e; + ERR_load_crypto_strings(); /*XXX move to a startup routine */ + while ((e = ERR_get_error())) + debug_printf("Az: %.120s\n", ERR_error_string(e, NULL)); +#elif defined(RSA_GNUTLS) + debug_printf("gnutls_pubkey_import: %s\n", gnutls_strerror(rc)); +#endif + } + sig->verify_status = PDKIM_VERIFY_INVALID; - sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_PARSING; + sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_IMPORT; goto NEXT_VERIFY; } /* Check the signature */ - if (rsa_pkcs1_verify(&rsa, - RSA_PUBLIC, - ((sig->algo == PDKIM_ALGO_RSA_SHA1)? - SIG_RSA_SHA1:SIG_RSA_SHA256), - 0, - (unsigned char *)headerhash, - (unsigned char *)sig->sigdata) != 0) +#ifdef RSA_OPENSSL + + if (RSA_verify(sig->algo == PDKIM_ALGO_RSA_SHA1 ? NID_sha1 : NID_sha256, + CUS headerhash, sig->algo == PDKIM_ALGO_RSA_SHA1 ? 20 : 32, + US sig->sigdata, (unsigned int)sig->sigdata_len, + rsa) != 1) + +#elif defined(RSA_GNUTLS) + + k.data = headerhash; + k.size = sig->algo == PDKIM_ALGO_RSA_SHA1 ? 20 : 32; + s.data = sig->sigdata; + s.size = sig->sigdata_len; + if ((rc = gnutls_pubkey_verify_hash2(rsa, + sig->algo == PDKIM_ALGO_RSA_SHA1 + ? GNUTLS_SIGN_RSA_SHA1 : GNUTLS_SIGN_RSA_SHA256, + 0, &k, &s)) < 0) + +#endif { +#if defined(RSA_GNUTLS) + debug_printf("gnutls_pubkey_verify_hash2: %s\n", gnutls_strerror(rc)); +#endif sig->verify_status = PDKIM_VERIFY_FAIL; sig->verify_ext_status = PDKIM_VERIFY_FAIL_MESSAGE; goto NEXT_VERIFY; @@ -1982,20 +2102,20 @@ while (sig) NEXT_VERIFY: -#ifdef PDKIM_DEBUG - if (ctx->debug_stream) + DEBUG(D_acl) { - fprintf(ctx->debug_stream, "PDKIM [%s] signature status: %s", + debug_printf("PDKIM [%s] signature status: %s", sig->domain, pdkim_verify_status_str(sig->verify_status)); if (sig->verify_ext_status > 0) - fprintf(ctx->debug_stream, " (%s)\n", + debug_printf(" (%s)\n", pdkim_verify_ext_status_str(sig->verify_ext_status)); else - fprintf(ctx->debug_stream, "\n"); + debug_printf("\n"); } -#endif - rsa_free(&rsa); +#ifdef RSA_GNUTLS + gnutls_pubkey_deinit(rsa); +#endif free(dns_txt_name); free(dns_txt_reply); } @@ -2014,7 +2134,7 @@ return PDKIM_OK; /* -------------------------------------------------------------------------- */ DLLEXPORT pdkim_ctx * -pdkim_init_verify(int input_mode, int(*dns_txt_callback)(char *, char *)) +pdkim_init_verify(int(*dns_txt_callback)(char *, char *)) { pdkim_ctx *ctx = malloc(sizeof(pdkim_ctx)); @@ -2029,7 +2149,6 @@ if (!(ctx->linebuf = malloc(PDKIM_MAX_BODY_LINE_LEN))) } ctx->mode = PDKIM_MODE_VERIFY; -ctx->input_mode = input_mode; ctx->dns_txt_callback = dns_txt_callback; return ctx; @@ -2039,7 +2158,7 @@ return ctx; /* -------------------------------------------------------------------------- */ DLLEXPORT pdkim_ctx * -pdkim_init_sign(int input_mode, char *domain, char *selector, char *rsa_privkey) +pdkim_init_sign(char *domain, char *selector, char *rsa_privkey, int algo) { pdkim_ctx *ctx; pdkim_signature *sig; @@ -2068,16 +2187,25 @@ memset(sig, 0, sizeof(pdkim_signature)); sig->bodylength = -1; ctx->mode = PDKIM_MODE_SIGN; -ctx->input_mode = input_mode; ctx->sig = sig; ctx->sig->domain = strdup(domain); ctx->sig->selector = strdup(selector); ctx->sig->rsa_privkey = strdup(rsa_privkey); +ctx->sig->algo = algo; if (!ctx->sig->domain || !ctx->sig->selector || !ctx->sig->rsa_privkey) goto BAIL; +#ifdef SHA_OPENSSL +SHA1_Init (&ctx->sig->sha1_body); +SHA256_Init(&ctx->sig->sha2_body); + +#elif defined(SHA_GNUTLS) +gnutls_hash_init(&ctx->sig->sha_body, + algo == PDKIM_ALGO_RSA_SHA1 ? GNUTLS_DIG_SHA1 : GNUTLS_DIG_SHA256); + +#elif defined(SHA_POLARSSL) if (!(ctx->sig->sha1_body = malloc(sizeof(sha1_context)))) goto BAIL; sha1_starts(ctx->sig->sha1_body); @@ -2086,6 +2214,8 @@ if (!(ctx->sig->sha2_body = malloc(sizeof(sha2_context)))) goto BAIL; sha2_starts(ctx->sig->sha2_body, 0); +#endif + return ctx; BAIL: @@ -2093,6 +2223,7 @@ BAIL: return NULL; } + /* -------------------------------------------------------------------------- */ DLLEXPORT int @@ -2102,11 +2233,9 @@ pdkim_set_optional(pdkim_ctx *ctx, int canon_headers, int canon_body, long bodylength, - int algo, unsigned long created, unsigned long expires) { - if (identity) if (!(ctx->sig->identity = strdup(identity))) return PDKIM_ERR_OOM; @@ -2118,20 +2247,11 @@ if (sign_headers) ctx->sig->canon_headers = canon_headers; ctx->sig->canon_body = canon_body; ctx->sig->bodylength = bodylength; -ctx->sig->algo = algo; ctx->sig->created = created; ctx->sig->expires = expires; return PDKIM_OK; } -/* -------------------------------------------------------------------------- */ - -#ifdef PDKIM_DEBUG -DLLEXPORT void -pdkim_set_debug_stream(pdkim_ctx *ctx, FILE *debug_stream) -{ -ctx->debug_stream = debug_stream; -} -#endif +#endif /*DISABLE_DKIM*/