Index: doc/tls.html ================================================================== --- doc/tls.html +++ doc/tls.html @@ -30,11 +30,11 @@
tls::connection channel
tls::import channel ?options?
tls::unimport channel
 
tls::ciphers ?protocol? ?verbose? ?supported?
-
tls::digests
+
tls::digests ?name?
tls::macs
tls::protocols
tls::version
 
tls::digest -digest name ?options?
@@ -74,11 +74,11 @@ tls::handshake channel
tls::import channel ?options?
tls::unimport channel

tls::ciphers ?protocol? ?verbose? ?supported?
-tls::digests
+tls::digests ?name?
tls::macs
tls::protocols
tls::version

tls::digest -digest name ?options?
@@ -444,12 +444,15 @@ verbose is specified as true then a verbose, human readable list is returned with additional information on the cipher. If supported is specified as true, then only the ciphers supported for protocol will be listed. -
tls::digests
-
Returns a list of the hash algorithms for tls::digest command.
+
tls::digests ?name?
+
Without name, returns a list of the supported hash algorithms + for tls::digest command. With name, returns a list of + property names and values describing digest name. Properties + include name, description, size, block_size, type, and flags list.
tls::macs
Returns a list of the available Message Authentication Codes (MAC) for the tls::digest command.
Index: generic/tlsInfo.c ================================================================== --- generic/tlsInfo.c +++ generic/tlsInfo.c @@ -249,10 +249,60 @@ } /* *------------------------------------------------------------------- * + * DigestInfo -- + * + * Return a list of properties and values for digestName. + * + * Results: + * A standard Tcl list. + * + * Side effects: + * None. + * + *------------------------------------------------------------------- + */ +int DigestInfo(Tcl_Interp *interp, char *digestName) { + Tcl_Obj *objPtr, *listPtr; + EVP_MD *md = EVP_get_digestbyname(digestName); + unsigned long flags; + + if (md == NULL) { + Tcl_AppendResult(interp, "Invalid digest \"", digestName, "\"", NULL); + return TCL_ERROR; + } + + /* Get properties */ + objPtr = Tcl_NewListObj(0, NULL); + LAPPEND_STR(interp, objPtr, "name", EVP_MD_name(md), -1); + LAPPEND_STR(interp, objPtr, "description", "", -1); + LAPPEND_INT(interp, objPtr, "size", EVP_MD_size(md)); + LAPPEND_INT(interp, objPtr, "block_size", EVP_MD_block_size(md)); + LAPPEND_STR(interp, objPtr, "provider", "", -1); + LAPPEND_STR(interp, objPtr, "type", OBJ_nid2ln(EVP_MD_type(md)), -1); + LAPPEND_STR(interp, objPtr, "pkey_type", OBJ_nid2ln(EVP_MD_pkey_type(md)), -1); + flags = EVP_MD_flags(md); + + /* Flags */ + listPtr = Tcl_NewListObj(0, NULL); + LAPPEND_BOOL(interp, listPtr, "One-shot", flags & EVP_MD_FLAG_ONESHOT); + LAPPEND_BOOL(interp, listPtr, "XOF", flags & EVP_MD_FLAG_XOF); + LAPPEND_BOOL(interp, listPtr, "DigestAlgorithmId_NULL", flags & EVP_MD_FLAG_DIGALGID_NULL); + LAPPEND_BOOL(interp, listPtr, "DigestAlgorithmId_Abscent", flags & EVP_MD_FLAG_DIGALGID_ABSENT); + LAPPEND_BOOL(interp, listPtr, "DigestAlgorithmId_Custom", flags & EVP_MD_FLAG_DIGALGID_CUSTOM); + LAPPEND_BOOL(interp, listPtr, "FIPS", flags & EVP_MD_FLAG_FIPS); + LAPPEND_OBJ(interp, objPtr, "flags", listPtr); + + Tcl_SetObjResult(interp, objPtr); + return TCL_OK; +} + +/* + *------------------------------------------------------------------- + * * DigestsObjCmd -- * * Return a list of all valid hash algorithms or message digests. * * Results: @@ -271,12 +321,15 @@ #if OPENSSL_VERSION_NUMBER < 0x10100000L OpenSSL_add_all_digests(); /* Make sure they're loaded */ #endif /* Validate arg count */ - if (objc != 1) { - Tcl_WrongNumArgs(interp, 1, objv, NULL); + if (objc == 2) { + char *digestName = Tcl_GetStringFromObj(objv[1],NULL); + return DigestInfo(interp, digestName); + } else if (objc > 2) { + Tcl_WrongNumArgs(interp, 1, objv, "?name?"); return TCL_ERROR; } /* List all digests */ objPtr = Tcl_NewListObj(0, NULL);