summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2016-06-02 22:59:54 +0100
committerJeremy Harris <jgh146exb@wizmail.org>2016-06-02 23:05:44 +0100
commit6e773413c0c0d4bb52b7a9af4c23ab83e26aa26b (patch)
tree16f3888ac9c906c8221d1024887fa73149c7bb23
parentcfab9d68aba4f5cc5218b1619b4469880c4d6cc5 (diff)
Expansions: add ${sha3:<string>} item
-rw-r--r--doc/doc-docbook/spec.xfpt21
-rw-r--r--doc/doc-txt/NewStuff4
-rw-r--r--src/src/expand.c38
-rw-r--r--src/src/hash.c30
-rw-r--r--src/src/hash.h6
-rw-r--r--src/src/sha_ver.h3
-rw-r--r--test/scripts/2000-GnuTLS/200011
-rw-r--r--test/stdout/200011
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_<n>:*&<&'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:<string>} / ${sha3_<N>:<string>}.
+ 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 <openssl/rsa.h>
-# include <openssl/ssl.h>
-# include <openssl/err.h>
-#elif defined(RSA_GNUTLS)
-# include <gnutls/gnutls.h>
-# include <gnutls/x509.h>
-# ifdef RSA_VERIFY_GNUTLS
-# include <gnutls/abstract.h>
-# 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 +
>