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);