Index: src/th_main.c
==================================================================
--- src/th_main.c
+++ src/th_main.c
@@ -935,10 +935,11 @@
** "markdown" = FOSSIL_ENABLE_MARKDOWN
** "unicodeCmdLine" = !BROKEN_MINGW_CMDLINE
** "dynamicBuild" = FOSSIL_DYNAMIC_BUILD
** "mman" = USE_MMAN_H
** "see" = USE_SEE
+** "hardenedSha1" = FOSSIL_HARDENED_SHA1
**
** Specifying an unknown feature will return a value of false, it will not
** raise a script error.
*/
static int hasfeatureCmd(
@@ -951,11 +952,11 @@
int rc = 0;
const char *zArg;
if( argc!=2 ){
return Th_WrongNumArgs(interp, "hasfeature STRING");
}
- zArg = (const char *)argv[1];
+ zArg = argv[1];
if(NULL==zArg){
/* placeholder for following ifdefs... */
}
#if defined(FOSSIL_ENABLE_SSL)
else if( 0 == fossil_strnicmp( zArg, "ssl\0", 4 ) ){
@@ -1022,10 +1023,15 @@
#endif
#if defined(USE_SEE)
else if( 0 == fossil_strnicmp( zArg, "see\0", 4 ) ){
rc = 1;
}
+#endif
+#if FOSSIL_HARDENED_SHA1
+ else if( 0 == fossil_strnicmp( zArg, "hardenedSha1\0", 13 ) ){
+ rc = 1;
+ }
#endif
else if( 0 == fossil_strnicmp( zArg, "markdown\0", 9 ) ){
rc = 1;
}
if( g.thTrace ){
@@ -1032,10 +1038,64 @@
Th_Trace("[hasfeature %#h] => %d
\n", argl[1], zArg, rc);
}
Th_SetResultInt(interp, rc);
return TH_OK;
}
+
+/*
+** TH1 command: hash STRING ?ALGORITHM?
+**
+** Returns the cryptographic hash of the specified string. Possible values
+** for the ALGORITHM argument are:
+**
+** "md5"
+** "sha1"
+** "sha3-224"
+** "sha3-256"
+** "sha3-384"
+** "sha3-512"
+**
+** The default algorithm is "sha3-256". Specifying an unknown algorithm
+** will raise a script error.
+*/
+static int hashCmd(
+ Th_Interp *interp,
+ void *p,
+ int argc,
+ const char **argv,
+ int *argl
+){
+ Blob content;
+ Blob cksum;
+ const char *zAlgorithm = "sha3-256";
+ if( argc<2 || argc>3 ){
+ return Th_WrongNumArgs(interp, "hash STRING ?ALGORITHM?");
+ }
+ blob_init(&content, argv[1], argl[1]);
+ blob_zero(&cksum);
+ if( argc>=3 ){
+ zAlgorithm = argv[2];
+ }
+ if( 0 == fossil_strnicmp( zAlgorithm, "md5\0", 4 ) ){
+ md5sum_blob(&content, &cksum);
+ }else if( 0 == fossil_strnicmp( zAlgorithm, "sha1\0", 5 ) ){
+ sha1sum_blob(&content, &cksum);
+ }else if( 0 == fossil_strnicmp( zAlgorithm, "sha3-224\0", 9 ) ){
+ sha3sum_blob(&content, 224, &cksum);
+ }else if( 0 == fossil_strnicmp( zAlgorithm, "sha3-256\0", 9 ) ){
+ sha3sum_blob(&content, 256, &cksum);
+ }else if( 0 == fossil_strnicmp( zAlgorithm, "sha3-384\0", 9 ) ){
+ sha3sum_blob(&content, 384, &cksum);
+ }else if( 0 == fossil_strnicmp( zAlgorithm, "sha3-512\0", 9 ) ){
+ sha3sum_blob(&content, 512, &cksum);
+ }else{
+ Th_SetResult(interp, "unknown hash algorithm", -1);
+ return TH_ERROR;
+ }
+ Th_SetResult(interp, blob_str(&cksum), -1);
+ return TH_OK;
+}
/*
** TH1 command: tclReady
**
@@ -2341,10 +2401,11 @@
{"glob_match", globMatchCmd, 0},
{"globalState", globalStateCmd, 0},
{"httpize", httpizeCmd, 0},
{"hascap", hascapCmd, (void*)&zeroInt},
{"hasfeature", hasfeatureCmd, 0},
+ {"hash", hashCmd, 0},
{"html", putsCmd, (void*)&aFlags[0]},
{"htmlize", htmlizeCmd, 0},
{"http", httpCmd, 0},
{"insertCsrf", insertCsrfCmd, 0},
{"linecount", linecntCmd, 0},
Index: test/th1.test
==================================================================
--- test/th1.test
+++ test/th1.test
@@ -1696,9 +1696,62 @@
# unversioned content
fossil test-th-eval --open-config \
{string length [unversioned content ten.txt]}
test th1-unversioned-2 {$RESULT eq {10}}
+
+###############################################################################
+
+fossil test-th-eval {hash foo}
+test th1-hash-1 {$RESULT eq \
+"76d3bc41c9f588f7fcd0d5bf4718f8f84b1c41b20882703100b9eb9413807c01"}
+
+###############################################################################
+
+fossil test-th-eval {hash foo bad}
+test th1-hash-2 {$RESULT eq "TH_ERROR: unknown hash algorithm"}
+
+###############################################################################
+
+fossil test-th-eval {hash foo md5}
+test th1-hash-3 {$RESULT eq "acbd18db4cc2f85cedef654fccc4a4d8"}
+
+###############################################################################
+
+fossil test-th-eval {hash foo md5 bad}
+test th1-hash-4 {$RESULT eq \
+"TH_ERROR: wrong # args: should be \"hash STRING ?ALGORITHM?\""}
+
+###############################################################################
+
+fossil test-th-eval {hash foo sha1}
+test th1-hash-5 {$RESULT eq "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"}
+
+###############################################################################
+
+fossil test-th-eval {hash foo sha3-224}
+test th1-hash-6 {$RESULT eq \
+"f4f6779e153c391bbd29c95e72b0708e39d9166c7cea51d1f10ef58a"}
+
+###############################################################################
+
+fossil test-th-eval {hash foo sha3-256}
+test th1-hash-7 {$RESULT eq \
+"76d3bc41c9f588f7fcd0d5bf4718f8f84b1c41b20882703100b9eb9413807c01"}
+
+###############################################################################
+
+fossil test-th-eval {hash foo sha3-384}
+test th1-hash-8 {$RESULT eq [appendArgs \
+665551928d13b7d84ee02734502b018d896a0fb87eed5adb4c87ba91bbd6489410e11b0fbcc06 \
+ed7d0ebad559e5d3bb5]}
+
+###############################################################################
+
+fossil test-th-eval {hash foo sha3-512}
+test th1-hash-9 {$RESULT eq [appendArgs \
+4bca2b137edc580fe50a88983ef860ebaca36c857b1f492839d6d7392452a63c82cbebc68e3b7 \
+0a2a1480b4bb5d437a7cba6ecf9d89f9ff3ccd14cd6146ea7e7]}
###############################################################################
test_cleanup
Index: win/fossil.rc
==================================================================
--- win/fossil.rc
+++ win/fossil.rc
@@ -98,10 +98,17 @@
VALUE "DynamicBuild", "Yes\0"
#else
VALUE "DynamicBuild", "No\0"
#endif
VALUE "ZlibVersion", "zlib " ZLIB_VERSION "\0"
+#if FOSSIL_HARDENED_SHA1
+ VALUE "Sha1", "Hardened-SHA1 by Marc Stevens and Dan Shumow\0"
+#elif defined(FOSSIL_ENABLE_SSL)
+ VALUE "Sha1", "OpenSSL-SHA1\0"
+#else
+ VALUE "Sha1", "Legacy-SHA1\0"
+#endif /* FOSSIL_HARDENED_SHA1 */
#if defined(BROKEN_MINGW_CMDLINE)
VALUE "CommandLineIsUnicode", "No\0"
#else
VALUE "CommandLineIsUnicode", "Yes\0"
#endif /* defined(BROKEN_MINGW_CMDLINE) */
Index: www/th1.md
==================================================================
--- www/th1.md
+++ www/th1.md
@@ -190,10 +190,11 @@
* [getParameter](#getParameter)
* [glob\_match](#glob_match)
* [globalState](#globalState)
* [hascap](#hascap)
* [hasfeature](#hasfeature)
+ * [hash](#hash)
* [html](#html)
* [htmlize](#htmlize)
* [http](#http)
* [httpize](#httpize)
* [insertCsrf](#insertCsrf)
@@ -519,13 +520,32 @@
1. **markdown** -- _Support for Markdown documentation format._
1. **unicodeCmdLine** -- _The command line arguments are Unicode._
1. **dynamicBuild** -- _Dynamically linked to libraries._
1. **mman** -- _Uses POSIX memory APIs from "sys/mman.h"._
1. **see** -- _Uses the SQLite Encryption Extension._
+ 1. **hardenedSha1** -- _Uses the Hardened-SHA1 implementation._
Specifying an unknown feature will return a value of false, it will not
raise a script error.
+
+TH1 hash Command
+---------------------------------
+
+ * hash STRING ?ALGORITHM?
+
+Returns the cryptographic hash of the specified string. Possible values
+for the ALGORITHM argument are:
+
+ 1. **md5**
+ 1. **sha1**
+ 1. **sha3-224**
+ 1. **sha3-256**
+ 1. **sha3-384**
+ 1. **sha3-512**
+
+The default algorithm is "sha3-256". Specifying an unknown algorithm
+will raise a script error.
TH1 html Command
-----------------------------------
* html STRING