Index: doc/tls.html ================================================================== --- doc/tls.html +++ doc/tls.html @@ -125,11 +125,11 @@
This is a helper function that utilizes the underlying commands (tls::import). It behaves exactly the same as the native Tcl socket command except that the options can include any of the applicable tls:import - options with one additional option: + options with one additional option:
-autoservername bool
Automatically send the -servername as the host argument (default is false)
@@ -205,11 +205,11 @@ (default is true)
-require bool
Require a valid certificate from peer during SSL handshake. If this is set to true, then -request must also be set to true. (default is false)
-
-securitylevel integer
+
-security_level integer
Set security level. Must be 0 to 5. The security level affects cipher suite encryption algorithms, supported ECC curves, supported signature algorithms, DH parameter sizes, certificate key sizes and signature algorithms. The default is 1. Level 3 and higher disable support for session tickets and only @@ -254,15 +254,15 @@ handshake is still in progress (non-blocking), or 1 if the handshake was successful. If the handshake failed this routine will throw an error.
 
tls::status - ?-local? channel
+ ?-local? channel
Returns the current status of the certificate for an SSL channel. The result is a list of key-value pairs describing - the certificate. If the result is an empty list then the - SSL handshake has not yet completed. If -local is + the certificate. If the SSL handshake has not yet completed, + an empty list is returned. If -local is specified, then the local certificate is used.
SSL Status
alpn protocol
@@ -376,41 +376,48 @@
servername name
The name of the connected to server.
protocol version
The protocol version used for the connection: SSL2, SSL3, TLS1, TLS1.1, TLS1.2, TLS1.3, or unknown.
-
renegotiation boolean
+
renegotiation_allowed boolean
Whether protocol renegotiation is supported or not.
-
securitylevel level
+
security_level level
The security level used for selection of ciphers, key size, etc.
session_reused boolean
Whether the session has been reused or not.
is_server boolean
Whether the connection is configured as a server (1) or client (0).
compression mode
Compression method.
expansion mode
Expansion method.
+
caList list
+
List of Certificate Authorities (CA) for X.509 certificate.
Cipher Info
cipher cipher
The current cipher in use for the connection.
standard_name name
The standard RFC name of cipher.
-
bits n
+
algorithm_bits n
The number of processed bits used for cipher.
secret_bits n
The number of secret bits used for cipher.
min_version version
The minimum protocol version for cipher.
-
id id
+
cipher_is_aead boolean
+
Whether the cipher is Authenticated encryption with associated + data (AEAD).
+
cipher_id id
The OpenSSL cipher id.
description string
A text description of the cipher.
+
handshake_digest boolean
+
Digest used during handshake.
Session Info
@@ -472,53 +479,76 @@
tls::version
Returns the OpenSSL version string.

tls::digest -digest - name ?-bin|-hex? [-file filename | -command cmdName | - -chan channelId | -data data]
-
Calculate the message digest for data using digest hash - function. Returns value as a hex string (default) or as a binary value - with -bin or -binary option. Digest can be any OpenSSL - supported hash function including: md4, md5, sha1, + name ?-bin|-hex? [-file filename | -command cmdName | + -chan channelId | -data data] +
Calculate the message digest (MD) of data using name hash + function and return the resulting hash value as a hex string (default) + or as a binary value with -bin or -binary option. MDs + are used to ensure the integrity of data. The hash function can be any + supported OpenSSL algorithm such as md4, md5, sha1, sha256, sha512, sha3-256, etc. See - tls::digests command for a full list. + tls::digests command for a full list. In OpenSSL 3.0+, older + algorithms may reside in the legacy provider.
Using the -data option will immediately return the message - digest for data in the specified format. -
+ digest for data in the specified format. Example code: +
+ set md [::tls::digest sha256 "Some example data."]
+
Using the -file or -filename option will open file filename, read the file data, close the file, and return the message digest in the specified format. This uses the TCL APIs, so VFS - files are supported. -
+ files are supported. Example code: +
+ set md [::tls::digest -digest sha256 -file test_file.txt]
+
Using the -chan or -channel option, a stacked channel is created for channelId and data read from the channel is used to calculate a message digest with the result returned with the last read operation before EOF. Channel is automatically set to binary mode. -
+ Example code: +
+ set ch [open test_file.txt r]
+ ::tls::digest -digest sha256 -chan $ch
+ while {![eof $ch]} {set md [read $ch 4096]}
+ close $ch +
Using the -command option, a new command cmdName is created and returned. To add data to the hash function, call "cmdName update data", where data is the data to add. When done, call "cmdName finalize" - to return the message digest. + to return the message digest. Example code: +
+ set cmd [::tls::digest -digest sha256 -command ::tls::temp]
+ $cmd update "Some data. "
+ $cmd update "More data."
+ set md [$cmd finalize] +
tls::cmac -cipher name - -key key ?-bin|-hex? [-file filename | -command cmdName | - -chan channelId | -data data]
-
Calculate the Cipher-based Message Authentication Code (CMAC). Same arguments - as tls::digest with additional option -cipher to specify the - cipher to use and for certain ciphers, -key to specify the key.
+ -key key ?-bin|-hex? [-file filename | -command cmdName | + -chan channelId | -data data] +
Calculate the Cipher-based Message Authentication Code (CMAC). MACs + are used to ensure authenticity and the integrity of data. It uses the + same options as tls::digest, plus the additional option + -cipher to specify the cipher to use and for certain ciphers, + -key to specify the key.
tls::hmac -digest name - -key key ?-bin|-hex? [-file filename | -command cmdName | - -chan channelId | -data data]
-
Calculate the Hashed Message Authentication Code (HMAC). Same arguments - as tls::digest with additional option -key to specify the - key to use. To salt a password, append or prepend the salt - data to the password.
+ -key key ?-bin|-hex? [-file filename | -command cmdName | + -chan channelId | -data data] +
Calculate the Hash-based Message Authentication Code (HMAC). HMACs are + used to ensure the data integrity and authenticity of a message using a + shared secret key. The cryptographic strength depends upon the size of + the key and the security of the hash function used. It uses the same + options as tls::digest, plus additional option -key to + specify the key to use. To salt a password, append or prepend the salt + data to the password.
tls::md4 data
Returns the MD4 message-digest for data as a hex string.
tls::md5 data
Index: generic/tls.c ================================================================== --- generic/tls.c +++ generic/tls.c @@ -1112,11 +1112,11 @@ OPTSTR("-model", model); OPTOBJ("-password", password); OPTBOOL("-post_handshake", post_handshake); OPTBOOL("-request", request); OPTBOOL("-require", require); - OPTINT("-securitylevel", level); + OPTINT("-security_level", level); OPTBOOL("-server", server); OPTSTR("-servername", servername); OPTSTR("-session_id", session_id); OPTBOOL("-ssl2", ssl2); OPTBOOL("-ssl3", ssl3); @@ -1125,11 +1125,11 @@ OPTBOOL("-tls1.2", tls1_2); OPTBOOL("-tls1.3", tls1_3); OPTOBJ("-validatecommand", vcmd); OPTOBJ("-vcmd", vcmd); - OPTBAD("option", "-alpn, -cadir, -cafile, -cert, -certfile, -cipher, -ciphersuites, -command, -dhparams, -key, -keyfile, -model, -password, -post_handshake, -request, -require, -securitylevel, -server, -servername, -session_id, -ssl2, -ssl3, -tls1, -tls1.1, -tls1.2, -tls1.3, or -validatecommand"); + OPTBAD("option", "-alpn, -cadir, -cafile, -cert, -certfile, -cipher, -ciphersuites, -command, -dhparams, -key, -keyfile, -model, -password, -post_handshake, -request, -require, -security_level, -server, -servername, -session_id, -ssl2, -ssl3, -tls1, -tls1.1, -tls1.2, -tls1.3, or -validatecommand"); return TCL_ERROR; } if (request) verify |= SSL_VERIFY_CLIENT_ONCE | SSL_VERIFY_PEER; if (request && require) verify |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; @@ -2006,11 +2006,11 @@ /* Renegotiation allowed */ LAPPEND_BOOL(interp, objPtr, "renegotiation_allowed", SSL_get_secure_renegotiation_support(ssl)); /* Get security level */ - LAPPEND_INT(interp, objPtr, "securitylevel", SSL_get_security_level(ssl)); + LAPPEND_INT(interp, objPtr, "security_level", SSL_get_security_level(ssl)); /* Session info */ LAPPEND_BOOL(interp, objPtr, "session_reused", SSL_session_reused(ssl)); /* Is server info */ @@ -2053,14 +2053,10 @@ /* message authentication code - Cipher is AEAD (e.g. GCM or ChaCha20/Poly1305) or not */ /* Authenticated Encryption with associated data (AEAD) check */ LAPPEND_BOOL(interp, objPtr, "cipher_is_aead", SSL_CIPHER_is_aead(cipher)); - /* Digest used during the SSL/TLS handshake when using the cipher. */ - md = SSL_CIPHER_get_handshake_digest(cipher); - LAPPEND_STR(interp, objPtr, "handshake_digest", (char *)EVP_MD_name(md), -1); - /* Get OpenSSL-specific ID, not IANA ID */ LAPPEND_INT(interp, objPtr, "cipher_id", (int) SSL_CIPHER_get_id(cipher)); /* Two-byte ID used in the TLS protocol of the given cipher */ LAPPEND_INT(interp, objPtr, "protocol_id", (int) SSL_CIPHER_get_protocol_id(cipher)); @@ -2067,10 +2063,14 @@ /* Textual description of the cipher */ if (SSL_CIPHER_description(cipher, buf, sizeof(buf)) != NULL) { LAPPEND_STR(interp, objPtr, "description", buf, -1); } + + /* Digest used during the SSL/TLS handshake when using the cipher. */ + md = SSL_CIPHER_get_handshake_digest(cipher); + LAPPEND_STR(interp, objPtr, "handshake_digest", (char *)EVP_MD_name(md), -1); } /* Session info */ session = SSL_get_session(ssl); if (session != NULL) { Index: generic/tlsDigest.c ================================================================== --- generic/tlsDigest.c +++ generic/tlsDigest.c @@ -26,10 +26,11 @@ #define READ_DELAY 5 /* Digest format and operation */ #define BIN_FORMAT 0x01 #define HEX_FORMAT 0x02 +#define IS_XOF 0x08 #define TYPE_MD 0x10 #define TYPE_HMAC 0x20 #define TYPE_CMAC 0x40 /* @@ -237,13 +238,19 @@ unsigned int md_len; int res = 0; /* Finalize hash function and calculate message digest */ if (statePtr->format & TYPE_MD) { - res = EVP_DigestFinal_ex(statePtr->ctx, md_buf, &md_len); + if (!(statePtr->format & IS_XOF)) { + res = EVP_DigestFinal_ex(statePtr->ctx, md_buf, &md_len); + } else { + res = EVP_DigestFinalXOF(statePtr->ctx, md_buf, EVP_MAX_MD_SIZE); + } + } else if (statePtr->format & TYPE_HMAC) { res = HMAC_Final(statePtr->hctx, md_buf, &md_len); + } else if (statePtr->format & TYPE_CMAC) { size_t len; res = CMAC_Final(statePtr->cctx, md_buf, &len); md_len = (unsigned int) len; } @@ -895,11 +902,11 @@ * * Returns: * Nothing * * Side effects: - * Destroys struct + * Destroys state info structure * *------------------------------------------------------------------- */ void InstanceDelCallback(ClientData clientData) { DigestState *statePtr = (DigestState *) clientData; @@ -1162,10 +1169,12 @@ if (digestName != NULL) { md = EVP_get_digestbyname(digestName); if (md == NULL) { Tcl_AppendResult(interp, "Invalid digest \"", digestName, "\"", NULL); return TCL_ERROR; + } else if (md == EVP_shake128() || md == EVP_shake256()) { + format |= IS_XOF; } } else if (type == TYPE_MD || type == TYPE_HMAC) { Tcl_AppendResult(interp, "No digest specified", NULL); return TCL_ERROR; }