commit 37df18b613e7509c3960626974187bc8e0ac409e from: Martijn van Duren date: Sat Apr 6 16:00:39 2019 UTC Replace custom hash functions with context based. minus 51 LoC commit - d0322b67902773163df220dc362c73e77726fcf1 commit + 37df18b613e7509c3960626974187bc8e0ac409e blob - 10efb31617b948c80ec03385746bb97e85842145 blob + 153f7827cf12557f240963b50c48d147fb242243 --- main.c +++ main.c @@ -44,14 +44,11 @@ struct dkim_session { int parsing_headers; char **headers; int lastheader; - union { - SHA_CTX sha1; - SHA256_CTX sha256; - }; size_t body_whitelines; int has_body; struct dkim_signature signature; EVP_MD_CTX *b; + EVP_MD_CTX *bh; RB_ENTRY(dkim_session) entry; }; @@ -120,9 +117,6 @@ int dkim_signature_printf(struct dkim_session *, char int dkim_signature_normalize(struct dkim_session *); int dkim_signature_need(struct dkim_session *, size_t); int dkim_sign_init(struct dkim_session *); -int dkim_hash_init(struct dkim_session *); -int dkim_hash_update(struct dkim_session *, char *, size_t); -int dkim_hash_final(struct dkim_session *, char *); int main(int argc, char *argv[]) @@ -228,8 +222,8 @@ dkim_dataline(char *type, int version, struct timespec struct dkim_session *session, search; struct dkim_signature sig; /* Use largest hash size her */ - char bbh[SHA256_DIGEST_LENGTH]; - char bh[(((SHA256_DIGEST_LENGTH + 2) / 3) * 4) + 1]; + char bbh[EVP_MAX_MD_SIZE]; + char bh[(((sizeof(bbh) + 2) / 3) * 4) + 1]; char *b; ssize_t i, j; size_t linelen; @@ -254,25 +248,23 @@ dkim_dataline(char *type, int version, struct timespec } else if (linelen == 0 && session->parsing_headers) { session->parsing_headers = 0; } else if (line[0] == '.' && line[1] =='\0') { + /* This entire section needs an error handling revamp */ if (canonbody == CANON_SIMPLE && !session->has_body) { - if (dkim_hash_update(session, "\r\n", 2) == 0) + if (EVP_DigestUpdate(session->bh, "\r\n", 2) <= 0) { + dkim_err(session, "Can't update hash context"); return; + } } - if (dkim_hash_final(session, bbh) == 0) + if (EVP_DigestFinal_ex(session->bh, bbh, NULL) == 0) { + dkim_err(session, "Can't finalize hash context"); return; - EVP_EncodeBlock(bh, bbh, hashalg == HASH_SHA1 ? - SHA_DIGEST_LENGTH : SHA256_DIGEST_LENGTH); + } + EVP_EncodeBlock(bh, bbh, EVP_MD_CTX_size(session->bh)); if (!dkim_signature_printf(session, "bh=%s; h=", bh)) return; /* Reverse order for ease of use of RFC6367 section 5.4.2 */ for (i = 0; session->headers[i] != NULL; i++) continue; - if (EVP_DigestSignInit(session->b, NULL, hash_md, NULL, - pkey) <= 0) { - dkim_errx(session, - "Failed to initialize digest context"); - return; - } for (i--; i >= 0; i--) { if (EVP_DigestSignUpdate(session->b, session->headers[i], @@ -372,8 +364,6 @@ dkim_session_new(uint64_t reqid) } session->parsing_headers = 1; - if (!dkim_hash_init(session)) - return NULL; session->body_whitelines = 0; session->headers = calloc(1, sizeof(*(session->headers))); if (session->headers == NULL) { @@ -394,10 +384,16 @@ dkim_session_new(uint64_t reqid) domain, selector)) return NULL; - if ((session->b = EVP_MD_CTX_new()) == NULL) { + if ((session->b = EVP_MD_CTX_new()) == NULL || + (session->bh = EVP_MD_CTX_new()) == NULL) { dkim_errx(session, "Can't create hash context"); return NULL; } + if (EVP_DigestSignInit(session->b, NULL, hash_md, NULL, pkey) <= 0 || + EVP_DigestInit_ex(session->bh, hash_md, NULL) == 0) { + dkim_errx(session, "Failed to initialize hash context"); + return NULL; + } if (RB_INSERT(dkim_sessions, &dkim_sessions, session) != NULL) fatalx("session already registered"); return session; @@ -411,6 +407,7 @@ dkim_session_free(struct dkim_session *session) RB_REMOVE(dkim_sessions, &dkim_sessions, session); fclose(session->origf); EVP_MD_CTX_free(session->b); + EVP_MD_CTX_free(session->bh); free(session->signature.signature); for (i = 0; session->headers[i] != NULL; i++) free(session->headers[i]); @@ -590,8 +587,10 @@ dkim_parse_body(struct dkim_session *session, char *li } while (session->body_whitelines--) { - if (dkim_hash_update(session, "\r\n", 2) == 0) + if (EVP_DigestUpdate(session->bh, "\r\n", 2) == 0) { + dkim_err(session, "Can't update hash context"); return; + } } session->body_whitelines = 0; @@ -611,10 +610,11 @@ dkim_parse_body(struct dkim_session *session, char *li } else linelen = strlen(line); - if (dkim_hash_update(session, line, linelen) == 0) + if (EVP_DigestUpdate(session->bh, line, linelen) == 0 || + EVP_DigestUpdate(session->bh, "\r\n", 2) == 0) { + dkim_err(session, "Can't update hash context"); return; - if (dkim_hash_update(session, "\r\n", 2) == 0) - return; + } } int @@ -696,57 +696,6 @@ dkim_signature_normalize(struct dkim_session *session) } int -dkim_hash_init(struct dkim_session *session) -{ - if (hashalg == HASH_SHA1) { - if (SHA1_Init(&(session->sha1)) == 0) { - dkim_errx(session, "Unable to init hash"); - return 0; - } - } else { - if (SHA256_Init(&(session->sha256)) == 0) { - dkim_errx(session, "Unable to init hash"); - return 0; - } - } - return 1; -} - -int -dkim_hash_update(struct dkim_session *session, char *buf, size_t len) -{ - if (hashalg == HASH_SHA1) { - if (SHA1_Update(&(session->sha1), buf, len) == 0) { - dkim_errx(session, "Unable to update hash"); - return 0; - } - } else { - if (SHA256_Update(&(session->sha256), buf, len) == 0) { - dkim_errx(session, "Unable to update hash"); - return 0; - } - } - return 1; -} - -int -dkim_hash_final(struct dkim_session *session, char *dest) -{ - if (hashalg == HASH_SHA1) { - if (SHA1_Final(dest, &(session->sha1)) == 0) { - dkim_errx(session, "Unable to finalize hash"); - return 0; - } - } else { - if (SHA256_Final(dest, &(session->sha256)) == 0) { - dkim_errx(session, "Unable to finalize hash"); - return 0; - } - } - return 1; -} - -int dkim_signature_printf(struct dkim_session *session, char *fmt, ...) { struct dkim_signature *sig = &(session->signature);