Expansions: add ${sha3:<string>} item
authorJeremy Harris <jgh146exb@wizmail.org>
Thu, 2 Jun 2016 21:59:54 +0000 (22:59 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Thu, 2 Jun 2016 22:05:44 +0000 (23:05 +0100)
doc/doc-docbook/spec.xfpt
doc/doc-txt/NewStuff
src/src/expand.c
src/src/hash.c
src/src/hash.h
src/src/sha_ver.h
test/scripts/2000-GnuTLS/2000
test/stdout/2000

index 1e5b72e..c46b503 100644 (file)
@@ -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"
index 1a7ea70..90aefc4 100644 (file)
@@ -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
 ------------
index d23e15f..1484a30 100644 (file)
@@ -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:
index a0d69c2..c2be85d 100644 (file)
@@ -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;
   }
 }
 
index f1ebac4..9e91f1a 100644 (file)
 /* 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 {
index 630c78d..fd1a4d0 100644 (file)
@@ -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
index 5e26e43..8717892 100644 (file)
@@ -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}
 ****
index effaada..2279f2e 100644 (file)
@@ -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 +
 >