From 6e773413c0c0d4bb52b7a9af4c23ab83e26aa26b Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Thu, 2 Jun 2016 22:59:54 +0100 Subject: [PATCH] Expansions: add ${sha3:} item --- doc/doc-docbook/spec.xfpt | 21 ++++++++++++++++++- doc/doc-txt/NewStuff | 4 ++++ src/src/expand.c | 38 ++++++++++++++++++++++++++++++++++- src/src/hash.c | 30 ++++++--------------------- src/src/hash.h | 6 +++++- src/src/sha_ver.h | 3 +++ test/scripts/2000-GnuTLS/2000 | 11 ++++++++-- test/stdout/2000 | 11 ++++++++-- 8 files changed, 93 insertions(+), 31 deletions(-) diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index 1e5b72e87..c46b50307 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -10482,7 +10482,7 @@ variables or headers inside regular expressions. .cindex "SHA-1 hash" .cindex "expansion" "SHA-1 hashing" .cindex certificate fingerprint -.cindex "&%sha2%& expansion item" +.cindex "&%sha1%& expansion item" The &%sha1%& operator computes the SHA-1 hash value of the string, and returns it as a 40-digit hexadecimal number, in which any letters are in upper case. @@ -10505,6 +10505,25 @@ If the string is a single variable of type certificate, returns the SHA-256 hash fingerprint of the certificate. +.new +.vitem &*${sha3:*&<&'string'&>&*}*& +.vitem &*${sha3_:*&<&'string'&>&*}*& +.cindex "SHA3 hash" +.cindex "expansion" "SHA3 hashing" +.cindex "&%sha3%& expansion item" +The &%sha3%& operator computes the SHA3-256 hash value of the string +and returns +it as a 64-digit hexadecimal number, in which any letters are in upper case. + +If a number is appended, separated by an underbar, it specifies +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. +.wen + + .vitem &*${stat:*&<&'string'&>&*}*& .cindex "expansion" "statting a file" .cindex "file" "extracting characteristics" diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index 1a7ea70a0..90aefc4fe 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -17,6 +17,10 @@ Version 4.88 3. Speculative debugging, via a "kill" option to the "control=debug" ACL modifier. + 4. New expansion item ${sha3:} / ${sha3_:}. + N can be 224, 256 (default), 384, 512. + With GnuTLS 3.5.0 or later, only. + Version 4.87 ------------ diff --git a/src/src/expand.c b/src/src/expand.c index d23e15fa7..1484a3027 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -231,6 +231,7 @@ static uschar *op_table_main[] = { US"s", US"sha1", US"sha256", + US"sha3", US"stat", US"str2b64", US"strlen", @@ -273,6 +274,7 @@ enum { EOP_S, EOP_SHA1, EOP_SHA256, + EOP_SHA3, EOP_STAT, EOP_STR2B64, EOP_STRLEN, @@ -6367,7 +6369,7 @@ while (*s != 0) continue; case EOP_SHA256: -#ifdef SUPPORT_TLS +#ifdef EXIM_HAVE_SHA2 if (vp && *(void **)vp->value) { uschar * cp = tls_cert_fprt_sha256(*(void **)vp->value); @@ -6393,6 +6395,40 @@ while (*s != 0) #endif continue; + case EOP_SHA3: +#ifdef EXIM_HAVE_SHA3 + { + hctx h; + blob b; + char st[3]; + hashmethod m = !arg ? HASH_SHA3_256 + : Ustrcmp(arg, "224") == 0 ? HASH_SHA3_224 + : Ustrcmp(arg, "256") == 0 ? HASH_SHA3_256 + : Ustrcmp(arg, "384") == 0 ? HASH_SHA3_384 + : Ustrcmp(arg, "512") == 0 ? HASH_SHA3_512 + : HASH_BADTYPE; + + if (m == HASH_BADTYPE) + { + expand_string_message = US"unrecognised sha3 variant"; + goto EXPAND_FAILED; + } + + exim_sha_init(&h, m); + exim_sha_update(&h, sub, Ustrlen(sub)); + exim_sha_finish(&h, &b); + while (b.len-- > 0) + { + sprintf(st, "%02X", *b.data++); + yield = string_catn(yield, &size, &ptr, US st, 2); + } + } + continue; +#else + expand_string_message = US"sha3 only supported with GnuTLS 3.5.0 +"; + goto EXPAND_FAILED; +#endif + /* Convert hex encoding to base64 encoding */ case EOP_HEX2B64: diff --git a/src/src/hash.c b/src/src/hash.c index a0d69c2f0..c2be85d17 100644 --- a/src/src/hash.c +++ b/src/src/hash.c @@ -27,27 +27,6 @@ sha1; -#ifndef SUPPORT_TLS -# error Need SUPPORT_TLS for DKIM -#endif - - - -#ifdef notdef -#ifdef RSA_OPENSSL -# include -# include -# include -#elif defined(RSA_GNUTLS) -# include -# include -# ifdef RSA_VERIFY_GNUTLS -# include -# endif -#endif -#endif - - /******************************************************************************/ #ifdef SHA_OPENSSL @@ -95,9 +74,12 @@ exim_sha_init(hctx * h, hashmethod m) { switch (h->method = m) { - case HASH_SHA1: h->hashlen = 20; gnutls_hash_init(&h->sha, GNUTLS_DIG_SHA1); break; - case HASH_SHA256: h->hashlen = 32; gnutls_hash_init(&h->sha, GNUTLS_DIG_SHA256); break; - default: h->hashlen = 0; break; + case HASH_SHA1: h->hashlen = 20; gnutls_hash_init(&h->sha, GNUTLS_DIG_SHA1); break; + case HASH_SHA256: h->hashlen = 32; gnutls_hash_init(&h->sha, GNUTLS_DIG_SHA256); break; +#ifdef EXIM_HAVE_SHA3 + case HASH_SHA3_256: h->hashlen = 32; gnutls_hash_init(&h->sha, GNUTLS_DIG_SHA3_256); break; +#endif + default: h->hashlen = 0; break; } } diff --git a/src/src/hash.h b/src/src/hash.h index f1ebac467..9e91f1aad 100644 --- a/src/src/hash.h +++ b/src/src/hash.h @@ -30,9 +30,13 @@ /* Hash context for the exim_sha_* routines */ typedef enum hashmethod { + HASH_BADTYPE, HASH_SHA1, HASH_SHA256, - HASH_SHA3 + HASH_SHA3_224, + HASH_SHA3_256, + HASH_SHA3_384, + HASH_SHA3_512, } hashmethod; typedef struct { diff --git a/src/src/sha_ver.h b/src/src/sha_ver.h index 630c78d41..fd1a4d083 100644 --- a/src/src/sha_ver.h +++ b/src/src/sha_ver.h @@ -18,6 +18,9 @@ # if GNUTLS_VERSION_NUMBER >= 0x020a00 # define SHA_GNUTLS +# if GNUTLS_VERSION_NUMBER >= 0x030500 +# define EXIM_HAVE_SHA3 +# endif # else # define SHA_GCRYPT # endif diff --git a/test/scripts/2000-GnuTLS/2000 b/test/scripts/2000-GnuTLS/2000 index 5e26e4332..8717892f2 100644 --- a/test/scripts/2000-GnuTLS/2000 +++ b/test/scripts/2000-GnuTLS/2000 @@ -16,6 +16,13 @@ no_msglog_check # # exim -be -sha256: ${sha256:} -sha256: ${sha256:abc} +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 effaada83..2279f2e7d 100644 --- a/test/stdout/2000 +++ b/test/stdout/2000 @@ -1,3 +1,10 @@ -> sha256: E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 -> sha256: BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD +> 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 + > -- 2.25.1