From 9c29c48f8327fc20b3840ce2fb4dad4a6c8003b2 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Thu, 1 Feb 2018 23:03:25 +0000 Subject: [PATCH] String expansions: support sha3 under OpenSSL (1.1.1+) --- doc/doc-docbook/spec.xfpt | 5 ++++- doc/doc-txt/NewStuff | 3 +++ src/src/expand.c | 2 +- src/src/hash.c | 27 +++++++++++++++++++++++++++ src/src/hash.h | 3 +++ src/src/sha_ver.h | 6 +++++- test/scripts/2100-OpenSSL/2100 | 7 +++++++ test/stdout/2000 | 12 ++++++------ test/stdout/2100 | 7 +++++++ 9 files changed, 63 insertions(+), 9 deletions(-) diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index ad3a34214..c4209659a 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -10645,7 +10645,10 @@ the output length. Values of 224, 256, 384 and 512 are accepted; with 256 being the default. The &%sha3%& expansion item is only supported if Exim has been -compiled with GnuTLS 3.5.0 or later. +compiled with GnuTLS 3.5.0 or later, +.new +or OpenSSL 1.1.1 or later. +.wen .vitem &*${stat:*&<&'string'&>&*}*& diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index 2a72852bb..c3f013ee8 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -30,6 +30,9 @@ Version 4.91 7. Options "ipv4_only" and "ipv4_prefer" on the dnslookup router and on routing rules in the manualroute router. + 8. Expansion item ${sha3:} / ${sha3_:} now also supported + under OpenSSL version 1.1.1 or later. + Version 4.90 ------------ diff --git a/src/src/expand.c b/src/src/expand.c index 2b40823c9..f6fef84ef 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -6495,7 +6495,7 @@ while (*s != 0) } continue; #else - expand_string_message = US"sha3 only supported with GnuTLS 3.5.0 +"; + expand_string_message = US"sha3 only supported with GnuTLS 3.5.0 + or OpenSSL 1.1.1 +"; goto EXPAND_FAILED; #endif diff --git a/src/src/hash.c b/src/src/hash.c index ee4379648..1e25bdbe1 100644 --- a/src/src/hash.c +++ b/src/src/hash.c @@ -40,6 +40,20 @@ switch (h->method = m) case HASH_SHA2_256: h->hashlen = 32; SHA256_Init(&h->u.sha2_256); break; case HASH_SHA2_384: h->hashlen = 48; SHA384_Init(&h->u.sha2_512); break; case HASH_SHA2_512: h->hashlen = 64; SHA512_Init(&h->u.sha2_512); break; +#ifdef EXIM_HAVE_SHA3 + case HASH_SHA3_224: h->hashlen = 28; + EVP_DigestInit(h->u.mctx = EVP_MD_CTX_new(), EVP_sha3_224()); + break; + case HASH_SHA3_256: h->hashlen = 32; + EVP_DigestInit(h->u.mctx = EVP_MD_CTX_new(), EVP_sha3_256()); + break; + case HASH_SHA3_384: h->hashlen = 48; + EVP_DigestInit(h->u.mctx = EVP_MD_CTX_new(), EVP_sha3_384()); + break; + case HASH_SHA3_512: h->hashlen = 64; + EVP_DigestInit(h->u.mctx = EVP_MD_CTX_new(), EVP_sha3_512()); + break; +#endif default: h->hashlen = 0; return FALSE; } return TRUE; @@ -55,6 +69,12 @@ switch (h->method) case HASH_SHA2_256: SHA256_Update(&h->u.sha2_256, data, len); break; case HASH_SHA2_384: SHA384_Update(&h->u.sha2_512, data, len); break; case HASH_SHA2_512: SHA512_Update(&h->u.sha2_512, data, len); break; +#ifdef EXIM_HAVE_SHA3 + case HASH_SHA3_224: + case HASH_SHA3_256: + case HASH_SHA3_384: + case HASH_SHA3_512: EVP_DigestUpdate(h->u.mctx, data, len); break; +#endif /* should be blocked by init not handling these, but be explicit to guard against accidents later (and hush up clang -Wswitch) */ default: assert(0); @@ -72,6 +92,12 @@ switch (h->method) case HASH_SHA2_256: SHA256_Final(b->data, &h->u.sha2_256); break; case HASH_SHA2_384: SHA384_Final(b->data, &h->u.sha2_512); break; case HASH_SHA2_512: SHA512_Final(b->data, &h->u.sha2_512); break; +#ifdef EXIM_HAVE_SHA3 + case HASH_SHA3_224: + case HASH_SHA3_256: + case HASH_SHA3_384: + case HASH_SHA3_512: EVP_DigestFinal(h->u.mctx, b->data, NULL); break; +#endif default: assert(0); } } @@ -92,6 +118,7 @@ switch (h->method = m) case HASH_SHA2_384: h->hashlen = 48; gnutls_hash_init(&h->sha, GNUTLS_DIG_SHA384); break; case HASH_SHA2_512: h->hashlen = 64; gnutls_hash_init(&h->sha, GNUTLS_DIG_SHA512); break; #ifdef EXIM_HAVE_SHA3 + case HASH_SHA3_224: h->hashlen = 28; gnutls_hash_init(&h->sha, GNUTLS_DIG_SHA3_224); break; case HASH_SHA3_256: h->hashlen = 32; gnutls_hash_init(&h->sha, GNUTLS_DIG_SHA3_256); break; case HASH_SHA3_384: h->hashlen = 48; gnutls_hash_init(&h->sha, GNUTLS_DIG_SHA3_384); break; case HASH_SHA3_512: h->hashlen = 64; gnutls_hash_init(&h->sha, GNUTLS_DIG_SHA3_512); break; diff --git a/src/src/hash.h b/src/src/hash.h index 79521f027..585237fa8 100644 --- a/src/src/hash.h +++ b/src/src/hash.h @@ -51,6 +51,9 @@ typedef struct { SHA_CTX sha1; /* SHA1 block */ SHA256_CTX sha2_256; /* SHA256 or 224 block */ SHA512_CTX sha2_512; /* SHA512 or 384 block */ +#ifdef EXIM_HAVE_SHA3 + EVP_MD_CTX * mctx; /* SHA3 block */ +#endif } u; #elif defined(SHA_GNUTLS) diff --git a/src/src/sha_ver.h b/src/src/sha_ver.h index 387ac52c1..2428e52d6 100644 --- a/src/src/sha_ver.h +++ b/src/src/sha_ver.h @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) Jeremy Harris 2016 */ +/* Copyright (c) Jeremy Harris 2018 */ /* See the file NOTICE for conditions of use and distribution. */ /* SHA routine selection */ @@ -34,6 +34,10 @@ # else # define SHA_OPENSSL +# include +# if OPENSSL_VERSION_NUMBER >= 0x10101000L +# define EXIM_HAVE_SHA3 +# endif # endif #else diff --git a/test/scripts/2100-OpenSSL/2100 b/test/scripts/2100-OpenSSL/2100 index 27c6c84d6..37ba66fb5 100644 --- a/test/scripts/2100-OpenSSL/2100 +++ b/test/scripts/2100-OpenSSL/2100 @@ -13,4 +13,11 @@ no_msglog_check exim -be sha256: ${sha256:} sha256: ${sha256:abc} + +sha3: ${sha3:} +sha3: ${sha3:abc} +sha3_256: ${sha3_256:} +sha3_256: ${sha3_256:abc} +sha3_512: ${sha3_512:} +sha3_512: ${sha3_512:abc} **** diff --git a/test/stdout/2000 b/test/stdout/2000 index 2279f2e7d..939df1b9e 100644 --- a/test/stdout/2000 +++ b/test/stdout/2000 @@ -1,10 +1,10 @@ > sha256: E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 > sha256: BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD > -> Failed: sha3 only supported with GnuTLS 3.5.0 + -> Failed: sha3 only supported with GnuTLS 3.5.0 + -> Failed: sha3 only supported with GnuTLS 3.5.0 + -> Failed: sha3 only supported with GnuTLS 3.5.0 + -> Failed: sha3 only supported with GnuTLS 3.5.0 + -> Failed: sha3 only supported with GnuTLS 3.5.0 + +> Failed: sha3 only supported with GnuTLS 3.5.0 + or OpenSSL 1.1.1 + +> Failed: sha3 only supported with GnuTLS 3.5.0 + or OpenSSL 1.1.1 + +> Failed: sha3 only supported with GnuTLS 3.5.0 + or OpenSSL 1.1.1 + +> Failed: sha3 only supported with GnuTLS 3.5.0 + or OpenSSL 1.1.1 + +> Failed: sha3 only supported with GnuTLS 3.5.0 + or OpenSSL 1.1.1 + +> Failed: sha3 only supported with GnuTLS 3.5.0 + or OpenSSL 1.1.1 + > diff --git a/test/stdout/2100 b/test/stdout/2100 index effaada83..f349c70be 100644 --- a/test/stdout/2100 +++ b/test/stdout/2100 @@ -1,3 +1,10 @@ > sha256: E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 > sha256: BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD > +> Failed: sha3 only supported with GnuTLS 3.5.0 + or OpenSSL 1.1.1 + +> Failed: sha3 only supported with GnuTLS 3.5.0 + or OpenSSL 1.1.1 + +> Failed: sha3 only supported with GnuTLS 3.5.0 + or OpenSSL 1.1.1 + +> Failed: sha3 only supported with GnuTLS 3.5.0 + or OpenSSL 1.1.1 + +> Failed: sha3 only supported with GnuTLS 3.5.0 + or OpenSSL 1.1.1 + +> Failed: sha3 only supported with GnuTLS 3.5.0 + or OpenSSL 1.1.1 + +> -- 2.25.1