Index: doc/tls.html ================================================================== --- doc/tls.html +++ doc/tls.html @@ -29,13 +29,19 @@
tls::status ?-local? channel
tls::connection channel
tls::import channel ?options?
tls::unimport channel
 
-
tls::ciphers protocol ?verbose? ?supported?
+
tls::ciphers protocol ?verbose? ?supported?
tls::protocols
tls::version
+
 
+
tls::hash type data
+
tls::md4 data
+
tls::md5 data
+
tls::sha1 data
+
tls::sha256 data
COMMANDS
CALLBACK OPTIONS
HTTPS EXAMPLE
@@ -50,11 +56,11 @@

tls - binding to OpenSSL toolkit.

SYNOPSIS

-

package require Tcl 8.4
+

package require Tcl 8.5
package require tls

tls::init ?options?
tls::socket ?options? host port
tls::socket ?-server command? ?options? port
@@ -63,12 +69,18 @@ tls::handshake channel
tls::import channel ?options?
tls::unimport channel

tls::ciphers protocol ?verbose? ?supported?
-tls::protocols -tls::version +tls::protocols
+tls::version
+
+tls::hash type data
+tls::md4 data
+tls::md5 data
+tls::sha1 data
+tls::sha256 data

DESCRIPTION

This extension provides a generic binding to tls1.3. Exact list depends on OpenSSL version and compile time flags.

tls::version
Returns the OpenSSL version string.
+ +
+
tls::hash type data
+
Calculate the hash for data using type digest. + Returns value as a hex string. Type cam be any OpenSSL supported + hash digest including: md4, md5, sha1, + sha2 (sha224, sha256, sha384, sha512, + sha512-224, and sha512-256), + sha3 (sha3-224, sha3-256, sha3-384, and sha3-512), etc.
+ +
tls::md4 data
+
Calculate the hash for data using the MD4 message-digest algorithm.
+ +
tls::md5 data
+
Calculate the hash for data using the MD5 message-digest algorithm.
+ +
tls::sha1 data
+
Calculate the hash for data using the SHA-1 secure hash algorithm.
+ +
tls::sha256 data
+
Calculate the hash for data using the SHA-2 SHA-256 secure hash algorithm.

CALLBACK OPTIONS

Index: generic/tls.c ================================================================== --- generic/tls.c +++ generic/tls.c @@ -926,10 +926,125 @@ /********************/ /* *------------------------------------------------------------------- * + * Hash Calc -- return hash hex string for message digest + * + * Results: + * A standard Tcl result. + * + * Side effects: + * None. + * + *------------------------------------------------------------------- + */ +int +HashCalc(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], const EVP_MD *type) { + char *data; + int len; + unsigned int mdlen; + unsigned char mdbuf[EVP_MAX_MD_SIZE]; + unsigned char hashbuf[EVP_MAX_MD_SIZE*2+1]; + const char *hex = "0123456789ABCDEF"; + + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "data"); + return TCL_ERROR; + } + + data = Tcl_GetByteArrayFromObj(objv[1], &len); + if (data == NULL) { + return TCL_ERROR; + } + + /* Calc hash, convert to hex string, and write to result */ + if (EVP_Digest(data, (size_t) len, mdbuf, &mdlen, type, NULL)) { + unsigned char *mptr = mdbuf; + unsigned char *hptr = &hashbuf[0]; + + for (unsigned int i = 0; i < mdlen; i++) { + *hptr++ = hex[(*mptr>>4)&0xF]; + *hptr++ = hex[(*mptr++)&0xF]; + } + *hptr = 0; + Tcl_SetObjResult(interp, Tcl_NewStringObj(hashbuf, mdlen*2)); + } else { + Tcl_SetResult(interp, "Hash calculation error", NULL); + return TCL_ERROR; + } + return TCL_OK; +} + +/* + *------------------------------------------------------------------- + * + * Hash Commands -- Return hash hex string for message digest + * + * Results: + * A standard Tcl result. + * + * Side effects: + * None. + * + *------------------------------------------------------------------- + */ +HashCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { + int len; + const char *name; + const EVP_MD *type; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "type data"); + return TCL_ERROR; + } + + name = Tcl_GetStringFromObj(objv[1],&len); + if (name == NULL || (type = EVP_get_digestbyname(name)) == NULL) { + Tcl_AppendResult(interp, "Invalid digest type \"", name, "\"", NULL); + return TCL_ERROR; + } + objc--; + objv++; + return HashCalc(interp, objc, objv, type); +} + +/* + * Command to Calculate MD4 Hash + */ +int +HashMD4Cmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { + return HashCalc(interp, objc, objv, EVP_md4()); +} + +/* + * Command to Calculate MD5 Hash + */ +int +HashMD5Cmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { + return HashCalc(interp, objc, objv, EVP_md5()); +} + +/* + * Command to Calculate SHA-1 Hash + */ +int +HashSHA1Cmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { + return HashCalc(interp, objc, objv, EVP_sha1()); +} + +/* + * Command to Calculate SHA-256 Hash + */ +int +HashSHA256Cmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { + return HashCalc(interp, objc, objv, EVP_sha256()); +} + +/* + *------------------------------------------------------------------- + * * CiphersObjCmd -- list available ciphers * * This procedure is invoked to process the "tls::ciphers" command * to list available ciphers, based upon protocol selected. * @@ -2782,10 +2897,16 @@ Tcl_CreateObjCommand(interp, "tls::status", StatusObjCmd, (ClientData) 0, (Tcl_CmdDeleteProc *) NULL); Tcl_CreateObjCommand(interp, "tls::version", VersionObjCmd, (ClientData) 0, (Tcl_CmdDeleteProc *) NULL); Tcl_CreateObjCommand(interp, "tls::misc", MiscObjCmd, (ClientData) 0, (Tcl_CmdDeleteProc *) NULL); Tcl_CreateObjCommand(interp, "tls::protocols", ProtocolsObjCmd, (ClientData) 0, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateObjCommand(interp, "tls::hash", HashCmd, (ClientData) 0, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateObjCommand(interp, "tls::md4", HashMD4Cmd, (ClientData) 0, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateObjCommand(interp, "tls::md5", HashMD5Cmd, (ClientData) 0, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateObjCommand(interp, "tls::sha1", HashSHA1Cmd, (ClientData) 0, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateObjCommand(interp, "tls::sha256", HashSHA256Cmd, (ClientData) 0, (Tcl_CmdDeleteProc *) NULL); + if (interp) { Tcl_Eval(interp, tlsTclInitScript); } return Tcl_PkgProvide(interp, PACKAGE_NAME, PACKAGE_VERSION);