Index: doc/cryptography.html
==================================================================
--- doc/cryptography.html
+++ doc/cryptography.html
@@ -122,21 +122,21 @@
-iv string
Initialization vector (IV) to use. Required for some ciphers and GMAC.
Cipher modes CBC, CFB, OFB and CTR all need an IV while ECB mode does not.
A new, random IV should be created for each use. Think of the IV as a nonce
(number used once), it's public but random and unpredictable. See the
- tls::cipher command for iv size and
- when required.
+ tls::cipher for iv_length and
+ when required (length > 0). If not set, it will default to \x00 fill data.
- -key string
- Encryption key to use for cryptography function. Can be a binary or
text string. Longer keys provide better protection. Used by ciphers, HMAC,
- some CMAC, and some KDF implementations. Key lengths less than key_length
- size may be padded or rejected. See the
- tls::cipher command for key size.
+ some CMAC, and some KDF implementations. If the length of the key is <
+ key_length it will be padded. If > key_length, it will be rejected.
+ See the tls::cipher for key_length.
- -mac name
- Name of Message Authentication Code (MAC) to use.
@@ -287,11 +287,12 @@
Info Commands
- tls::cipher name
- Return a list of property names and values describing cipher
name. Properties include name, description, block_size,
- key_length, iv_length, type, and mode list.
+ key_length, iv_length, type, and mode list. If block-size is 1,
+ then it's a stream cipher, otherwise it's a block cipher.
- tls::ciphers
?protocol? ?verbose? ?supported?
- Without any args, returns a list of all symmetric ciphers for use with
the -cipher option. With protocol,
@@ -394,11 +395,11 @@
Encryption and Decryption Commands
- tls::encrypt
- -cipher name -key key ?-iv string?
+ ?-cipher? name -key key ?-iv string?
[-chan channelId | -command cmdName |
-infile filename -outfile filename |
-data data]
- Encrypt the data using cipher cipher and output the result per
the I/O options. Ciphers are used to create the cipher text from the
@@ -406,11 +407,11 @@
info. Option -iv is only used for some ciphers. See the
"tls::cipher cipher" command for key and iv
sizes and when the iv is used (iv_length > 0).
- tls::decrypt
- -cipher name -key key ?-iv string?
+ ?-cipher? name -key key ?-iv string?
[-chan channelId | -command cmdName |
-infile filename -outfile filename |
-data data]
- Decrypt the data using cipher cipher and output the result per
the I/O options. This command is the opposite of the tls::encrypt
Index: generic/tls.c
==================================================================
--- generic/tls.c
+++ generic/tls.c
@@ -2043,11 +2043,11 @@
the rest of the bits are fixed, i.e. for limited export ciphers (bits < 56) */
/* Indicates which SSL/TLS protocol version first defined the cipher */
LAPPEND_STR(interp, objPtr, "min_version", SSL_CIPHER_get_version(cipher), -1);
- /* Cipher NID */
+ /* Cipher NID, digest NID (none for AEAD cipher suites), Key Exchange NID, and authentication NID */
LAPPEND_STR(interp, objPtr, "cipherNID", (char *)OBJ_nid2ln(SSL_CIPHER_get_cipher_nid(cipher)), -1);
LAPPEND_STR(interp, objPtr, "digestNID", (char *)OBJ_nid2ln(SSL_CIPHER_get_digest_nid(cipher)), -1);
LAPPEND_STR(interp, objPtr, "keyExchangeNID", (char *)OBJ_nid2ln(SSL_CIPHER_get_kx_nid(cipher)), -1);
LAPPEND_STR(interp, objPtr, "authenticationNID", (char *)OBJ_nid2ln(SSL_CIPHER_get_auth_nid(cipher)), -1);
@@ -2059,11 +2059,12 @@
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));
- /* Textual description of the cipher */
+ /* Textual description of the cipher. Includes: cipher name, protocol version, key
+ exchange, authentication, symmetric encryption method, message authentication code */
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. */
Index: generic/tlsInfo.c
==================================================================
--- generic/tlsInfo.c
+++ generic/tlsInfo.c
@@ -51,11 +51,11 @@
/*******************************************************************/
/*
*-------------------------------------------------------------------
*
- * CipherInfo --
+ * CipherObjCmd --
*
* Return a list of properties and values for cipherName.
*
* Results:
* A standard Tcl list.
@@ -69,13 +69,11 @@
Tcl_Obj *objPtr, *listPtr;
unsigned char *cipherName = NULL, *modeName = NULL;
const EVP_CIPHER *cipher;
unsigned long flags, mode;
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
- OpenSSL_add_all_ciphers(); /* Make sure they're loaded */
-#endif
+ dprintf("Called");
/* Clear errors */
Tcl_ResetResult(interp);
ERR_clear_error();
@@ -94,10 +92,13 @@
return TCL_ERROR;
}
/* Get properties */
objPtr = Tcl_NewListObj(0, NULL);
+ if (objPtr == NULL) {
+ return TCL_ERROR;
+ }
LAPPEND_STR(interp, objPtr, "nid", OBJ_nid2ln(EVP_CIPHER_nid(cipher)), -1);
LAPPEND_STR(interp, objPtr, "name", EVP_CIPHER_name(cipher), -1);
LAPPEND_STR(interp, objPtr, "description", "", -1);
LAPPEND_INT(interp, objPtr, "block_size", EVP_CIPHER_block_size(cipher));
LAPPEND_INT(interp, objPtr, "key_length", EVP_CIPHER_key_length(cipher));
@@ -165,10 +166,36 @@
}
/*
*-------------------------------------------------------------------
*
+ * CipherList --
+ *
+ * Return a list of all cipher algorithms
+ *
+ * Results:
+ * A standard Tcl list.
+ *
+ * Side effects:
+ * None.
+ *
+ *-------------------------------------------------------------------
+ */
+int CipherList(Tcl_Interp *interp) {
+ Tcl_Obj *objPtr = Tcl_NewListObj(0, NULL);
+ if (objPtr == NULL) {
+ return TCL_ERROR;
+ }
+
+ OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, NamesCallback, (void *) objPtr);
+ Tcl_SetObjResult(interp, objPtr);
+ return TCL_OK;
+}
+
+/*
+ *-------------------------------------------------------------------
+ *
* CiphersObjCmd --
*
* This procedure is invoked to process the "tls::ciphers" command
* to list available ciphers, based upon protocol selected.
*
@@ -182,19 +209,15 @@
*/
static int CiphersObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) {
SSL_CTX *ctx = NULL;
SSL *ssl = NULL;
STACK_OF(SSL_CIPHER) *sk = NULL;
- int index, verbose = 0, use_supported = 0;
+ int index, verbose = 0, use_supported = 0, res = TCL_OK;
int min_version, max_version;
dprintf("Called");
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
- OpenSSL_add_all_ciphers(); /* Make sure they're loaded */
-#endif
-
/* Clear errors */
Tcl_ResetResult(interp);
ERR_clear_error();
/* Validate arg count */
@@ -203,16 +226,11 @@
return TCL_ERROR;
}
/* List all ciphers */
if (objc == 1) {
- Tcl_Obj *objPtr = Tcl_NewListObj(0, NULL);
-
- OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, NamesCallback, (void *) objPtr);
- Tcl_SetObjResult(interp, objPtr);
- return TCL_OK;
-
+ return CipherList(interp);
}
/* Get options */
if (Tcl_GetIndexFromObj(interp, objv[1], protocols, "protocol", 0, &index) != TCL_OK ||
(objc > 2 && Tcl_GetBooleanFromObj(interp, objv[2], &verbose) != TCL_OK) ||
@@ -307,10 +325,14 @@
Tcl_Obj *objPtr = NULL;
if (!verbose) {
char *cp;
objPtr = Tcl_NewListObj(0, NULL);
+ if (objPtr == NULL) {
+ res = TCL_ERROR;
+ goto done;
+ }
for (int i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
const SSL_CIPHER *c = sk_SSL_CIPHER_value(sk, i);
if (c == NULL) continue;
@@ -321,10 +343,14 @@
}
} else {
char buf[BUFSIZ];
objPtr = Tcl_NewStringObj("",0);
+ if (objPtr == NULL) {
+ res = TCL_ERROR;
+ goto done;
+ }
for (int i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
const SSL_CIPHER *c = sk_SSL_CIPHER_value(sk, i);
if (c == NULL) continue;
@@ -342,13 +368,14 @@
sk_SSL_CIPHER_free(sk);
}
Tcl_SetObjResult(interp, objPtr);
}
+done:
SSL_free(ssl);
SSL_CTX_free(ctx);
- return TCL_OK;
+ return res;
clientData = clientData;
}
/*******************************************************************/
@@ -377,10 +404,13 @@
return TCL_ERROR;
}
/* Get properties */
objPtr = Tcl_NewListObj(0, NULL);
+ if (objPtr == NULL) {
+ return TCL_ERROR;
+ }
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);
@@ -403,10 +433,36 @@
}
/*
*-------------------------------------------------------------------
*
+ * DigestList --
+ *
+ * Return a list of all digest algorithms
+ *
+ * Results:
+ * A standard Tcl list.
+ *
+ * Side effects:
+ * None.
+ *
+ *-------------------------------------------------------------------
+ */
+int DigestList(Tcl_Interp *interp) {
+ Tcl_Obj *objPtr = Tcl_NewListObj(0, NULL);
+ if (objPtr == NULL) {
+ return TCL_ERROR;
+ }
+
+ OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, NamesCallback, (void *) objPtr);
+ Tcl_SetObjResult(interp, objPtr);
+ return TCL_OK;
+}
+
+/*
+ *-------------------------------------------------------------------
+ *
* DigestsObjCmd --
*
* Return a list of all valid hash algorithms or message digests.
*
* Results:
@@ -416,36 +472,74 @@
* None.
*
*-------------------------------------------------------------------
*/
int DigestsObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) {
- Tcl_Obj *objPtr;
-
dprintf("Called");
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
- OpenSSL_add_all_digests(); /* Make sure they're loaded */
-#endif
-
/* Validate arg count */
- if (objc == 2) {
- char *digestName = Tcl_GetStringFromObj(objv[1],NULL);
- return DigestInfo(interp, digestName);
- } else if (objc > 2) {
+ if (objc == 1) {
+ return DigestList(interp);
+
+ } else if (objc == 2) {
+ return DigestInfo(interp, Tcl_GetStringFromObj(objv[1],NULL));
+
+ } else {
Tcl_WrongNumArgs(interp, 1, objv, "?name?");
return TCL_ERROR;
}
-
- /* List all digests */
- objPtr = Tcl_NewListObj(0, NULL);
- OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, NamesCallback, (void *) objPtr);
- Tcl_SetObjResult(interp, objPtr);
return TCL_OK;
clientData = clientData;
}
/*******************************************************************/
+
+/*
+ *-------------------------------------------------------------------
+ *
+ * MacInfo --
+ *
+ * Return a list of properties and values for macName.
+ *
+ * Results:
+ * A standard Tcl list.
+ *
+ * Side effects:
+ * None.
+ *
+ *-------------------------------------------------------------------
+ */
+int MacInfo(Tcl_Interp *interp, char *macName) {
+ return TCL_OK;
+}
+
+/*
+ *-------------------------------------------------------------------
+ *
+ * MacList --
+ *
+ * Return a list of all MAC algorithms
+ *
+ * Results:
+ * A standard Tcl list.
+ *
+ * Side effects:
+ * None.
+ *
+ *-------------------------------------------------------------------
+ */
+int MacList(Tcl_Interp *interp) {
+ Tcl_Obj *objPtr = Tcl_NewListObj(0, NULL);
+ if (objPtr == NULL) {
+ return TCL_ERROR;
+ }
+
+ Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("cmac", -1));
+ Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("hmac", -1));
+ Tcl_SetObjResult(interp, objPtr);
+ return TCL_OK;
+}
/*
*-------------------------------------------------------------------
*
* MacsObjCmd --
@@ -459,25 +553,120 @@
* None.
*
*-------------------------------------------------------------------
*/
int MacsObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) {
- Tcl_Obj *objPtr;
+ dprintf("Called");
+
+ /* Clear errors */
+ Tcl_ResetResult(interp);
+ ERR_clear_error();
+
+ /* Validate arg count */
+ if (objc == 1) {
+ return MacList(interp);
+
+ } else if (objc == 2) {
+ return MacInfo(interp, Tcl_GetStringFromObj(objv[1],NULL));
+
+ } else {
+ Tcl_WrongNumArgs(interp, 1, objv, "?name?");
+ return TCL_ERROR;
+ }
+ return TCL_OK;
+ clientData = clientData;
+}
+
+/*******************************************************************/
+
+/*
+ *-------------------------------------------------------------------
+ *
+ * PkeyInfo --
+ *
+ * Return a list of properties and values for pkeyName.
+ *
+ * Results:
+ * A standard Tcl list.
+ *
+ * Side effects:
+ * None.
+ *
+ *-------------------------------------------------------------------
+ */
+int PkeyInfo(Tcl_Interp *interp, char *pkeyName) {
+ return TCL_OK;
+}
+
+/*
+ *-------------------------------------------------------------------
+ *
+ * PkeyList --
+ *
+ * Return a list of all public key methods
+ *
+ * Results:
+ * A standard Tcl list.
+ *
+ * Side effects:
+ * None.
+ *
+ *-------------------------------------------------------------------
+ */
+int PkeyList(Tcl_Interp *interp) {
+ Tcl_Obj *objPtr = Tcl_NewListObj(0, NULL);
+ if (objPtr == NULL) {
+ return TCL_ERROR;
+ }
+
+ for (size_t i = 0; i < EVP_PKEY_meth_get_count(); i++) {
+ const EVP_PKEY_METHOD *pmeth = EVP_PKEY_meth_get0(i);
+ int pkey_id, pkey_flags;
+
+ EVP_PKEY_meth_get0_info(&pkey_id, &pkey_flags, pmeth);
+ /*LAPPEND_STR(interp, objPtr, "name", OBJ_nid2ln(pkey_id), -1);
+ LAPPEND_STR(interp, objPtr, "type", pkey_flags & ASN1_PKEY_DYNAMIC ? "External" : "Built-in", -1);*/
+
+ Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(OBJ_nid2ln(pkey_id), -1));
+ }
+ Tcl_SetObjResult(interp, objPtr);
+ return TCL_OK;
+}
+/*
+ *-------------------------------------------------------------------
+ *
+ * PkeysObjCmd --
+ *
+ * Return a list of all valid hash algorithms or message digests.
+ *
+ * Results:
+ * A standard Tcl list.
+ *
+ * Side effects:
+ * None.
+ *
+ *-------------------------------------------------------------------
+ */
+int PkeysObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) {
dprintf("Called");
+
+ /* Clear errors */
+ Tcl_ResetResult(interp);
+ ERR_clear_error();
/* Validate arg count */
- if (objc != 1) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ if (objc == 1) {
+ return PkeyList(interp);
+
+ } else if (objc == 2) {
+ return PkeyInfo(interp, Tcl_GetStringFromObj(objv[1],NULL));
+
+ } else {
+ Tcl_WrongNumArgs(interp, 1, objv, "?name?");
return TCL_ERROR;
}
-
- /* List all MACs */
- objPtr = Tcl_NewListObj(0, NULL);
- Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("cmac", -1));
- Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("hmac", -1));
- Tcl_SetObjResult(interp, objPtr);
return TCL_OK;
clientData = clientData;
}
/*******************************************************************/
@@ -500,19 +689,26 @@
static int
ProtocolsObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) {
Tcl_Obj *objPtr;
dprintf("Called");
+
+ /* Clear errors */
+ Tcl_ResetResult(interp);
+ ERR_clear_error();
/* Validate arg count */
if (objc != 1) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return TCL_ERROR;
}
- /* List all MACs */
+ /* List all protocols */
objPtr = Tcl_NewListObj(0, NULL);
+ if (objPtr == NULL) {
+ return TCL_ERROR;
+ }
#if OPENSSL_VERSION_NUMBER < 0x10100000L && !defined(NO_SSL2) && !defined(OPENSSL_NO_SSL2)
Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(protocols[TLS_SSL2], -1));
#endif
#if !defined(NO_SSL3) && !defined(OPENSSL_NO_SSL3) && !defined(OPENSSL_NO_SSL3_METHOD)
Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(protocols[TLS_SSL3], -1));
@@ -585,13 +781,21 @@
* Creates commands
*
*-------------------------------------------------------------------
*/
int Tls_InfoCommands(Tcl_Interp *interp) {
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+ OpenSSL_add_all_ciphers();
+ OpenSSL_add_all_digests();
+ OpenSSL_add_all_algorithms();
+#endif
+
Tcl_CreateObjCommand(interp, "tls::cipher", CipherObjCmd, (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "tls::ciphers", CiphersObjCmd, (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "tls::digests", DigestsObjCmd, (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "tls::macs", MacsObjCmd, (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
+ Tcl_CreateObjCommand(interp, "tls::pkeys", PkeysObjCmd, (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "tls::protocols", ProtocolsObjCmd, (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "tls::version", VersionObjCmd, (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
return TCL_OK;
}
Index: tests/info.csv
==================================================================
--- tests/info.csv
+++ tests/info.csv
@@ -10,10 +10,11 @@
command,# Helper functions,,,,,,,,,
command,"proc lcompare {list1 list2} {set m """";set u """";foreach i $list1 {if {$i ni $list2} {lappend m $i}};foreach i $list2 {if {$i ni $list1} {lappend u $i}};return [list ""missing"" $m ""unexpected"" $u]}",,,,,,,,,
command,proc exec_get {delim args} {return [split [exec openssl {*}$args] $delim]},,,,,,,,,
command,"proc exec_get_ciphers {} {set list [list];set data [exec openssl list -cipher-algorithms];foreach line [split $data ""\n""] {foreach {cipher null alias} [split [string trim $line]] {lappend list [string tolower $cipher]}};return [lsort -unique $list]}",,,,,,,,,
command,"proc exec_get_digests {} {set list [list];set data [exec openssl dgst -list];foreach line [split $data ""\n""] {foreach digest $line {if {[string match ""-*"" $digest]} {lappend list [string trimleft $digest ""-""]}}};return [lsort $list]}",,,,,,,,,
+command,"proc exec_get_pkeys {} {set list [list];set data [exec openssl list -public-key-methods];foreach line [split $data ""\n""] {if {![string match ""*Type:*"" $line]} {lappend list [string trim $line]}};return $list}",,,,,,,,,
command,proc exec_get_macs {} {return [list cmac hmac]},,,,,,,,,
command,proc list_tolower {list} {set result [list];foreach element $list {lappend result [string tolower $element]};return $result},,,,,,,,,
,,,,,,,,,,
command,# Test list ciphers,,,,,,,,,
Ciphers List,All,,,lcompare [lsort [exec_get_ciphers]] [list_tolower [lsort [::tls::ciphers]]],,,missing {rc5 rc5-cbc rc5-cfb rc5-ecb rc5-ofb} unexpected {aes-128-ccm aes-128-gcm aes-192-ccm aes-192-gcm aes-256-ccm aes-256-gcm},,,
@@ -64,10 +65,13 @@
Digest Info,md5,,,tls::digests md5,,,name MD5 description {} size 16 block_size 64 provider {} type md5 pkey_type md5WithRSAEncryption flags {One-shot 0 XOF 0 DigestAlgorithmId_NULL 0 DigestAlgorithmId_Abscent 0 DigestAlgorithmId_Custom 0 FIPS 0},,,
,,,,,,,,,,
command,# Test list MACs,,,,,,,,,
MAC List,All,,,lcompare [exec_get_macs] [tls::macs],,,missing {} unexpected {},,,
,,,,,,,,,,
+command,# Test list Pkeys,,,,,,,,,
+Pkey List,All,,,lcompare [exec_get_pkeys] [tls::pkeys],,,missing {} unexpected {},,,
+,,,,,,,,,,
command,# Test list protocols,,,,,,,,,
Protocols,All,,,lcompare $::protocols [::tls::protocols],,,missing {ssl2 ssl3} unexpected {},,,
,,,,,,,,,,
command,# Test show version,,,,,,,,,
Version,All,,,::tls::version,,glob,*,,,
@@ -75,8 +79,9 @@
,,,,,,,,,,
command,# Error Cases,,,,,,,,,
Error Cases,Cipher Too few args,,,::tls::cipher,,,"wrong # args: should be ""::tls::cipher name""",,,1
Error Cases,Cipher Too many args,,,::tls::cipher too many args,,,"wrong # args: should be ""::tls::cipher name""",,,1
Error Cases,Digests Too many args,,,::tls::digests too many args,,,"wrong # args: should be ""::tls::digests ?name?""",,,1
-Error Cases,MACs Too many args,,,::tls::macs too many args,,,"wrong # args: should be ""::tls::macs""",,,1
+Error Cases,MACs Too many args,,,::tls::macs too many args,,,"wrong # args: should be ""::tls::macs ?name?""",,,1
+Error Cases,Pkeys Too many args,,,::tls::pkeys too many args,,,"wrong # args: should be ""::tls::pkeys ?name?""",,,1
Error Cases,Protocols Too many args,,,::tls::protocols too many args,,,"wrong # args: should be ""::tls::protocols""",,,1
Error Cases,Version Too many args,,,::tls::version too many args,,,"wrong # args: should be ""::tls::version""",,,1
Index: tests/info.test
==================================================================
--- tests/info.test
+++ tests/info.test
@@ -19,11 +19,11 @@
# Helper functions
proc lcompare {list1 list2} {set m "";set u "";foreach i $list1 {if {$i ni $list2} {lappend m $i}};foreach i $list2 {if {$i ni $list1} {lappend u $i}};return [list "missing" $m "unexpected" $u]}
proc exec_get {delim args} {return [split [exec openssl {*}$args] $delim]}
proc exec_get_ciphers {} {set list [list];set data [exec openssl list -cipher-algorithms];foreach line [split $data "\n"] {foreach {cipher null alias} [split [string trim $line]] {lappend list [string tolower $cipher]}};return [lsort -unique $list]}
proc exec_get_digests {} {set list [list];set data [exec openssl dgst -list];foreach line [split $data "\n"] {foreach digest $line {if {[string match "-*" $digest]} {lappend list [string trimleft $digest "-"]}}};return [lsort $list]}
-proc exec_get_pks {} {set list [list];set data [exec openssl list -public-key-methods];foreach line [split $data "\n"] {if {![string match "*Type:*" $line]} {lappend list [string trim $line]}};return $list}
+proc exec_get_pkeys {} {set list [list];set data [exec openssl list -public-key-methods];foreach line [split $data "\n"] {if {![string match "*Type:*" $line]} {lappend list [string trim $line]}};return $list}
proc exec_get_macs {} {return [list cmac hmac]}
proc list_tolower {list} {set result [list];foreach element $list {lappend result [string tolower $element]};return $result}
# Test list ciphers
@@ -182,53 +182,64 @@
test MAC_List-9.1 {All} -body {
lcompare [exec_get_macs] [tls::macs]
} -result {missing {} unexpected {}}
+# Test list Pkeys
+
+
+test Pkey_List-10.1 {All} -body {
+ lcompare [exec_get_pkeys] [tls::pkeys]
+ } -result {missing {} unexpected {}}
+
# Test list protocols
-test Protocols-10.1 {All} -body {
+test Protocols-11.1 {All} -body {
lcompare $::protocols [::tls::protocols]
} -result {missing {ssl2 ssl3} unexpected {}}
# Test show version
-test Version-11.1 {All} -body {
+test Version-12.1 {All} -body {
::tls::version
} -match {glob} -result {*}
-test Version-11.2 {OpenSSL} -constraints {OpenSSL} -body {
+test Version-12.2 {OpenSSL} -constraints {OpenSSL} -body {
::tls::version
} -match {glob} -result {OpenSSL*}
# Error Cases
-test Error_Cases-12.1 {Cipher Too few args} -body {
+test Error_Cases-13.1 {Cipher Too few args} -body {
::tls::cipher
} -result {wrong # args: should be "::tls::cipher name"} -returnCodes {1}
-test Error_Cases-12.2 {Cipher Too many args} -body {
+test Error_Cases-13.2 {Cipher Too many args} -body {
::tls::cipher too many args
} -result {wrong # args: should be "::tls::cipher name"} -returnCodes {1}
-test Error_Cases-12.3 {Digests Too many args} -body {
+test Error_Cases-13.3 {Digests Too many args} -body {
::tls::digests too many args
} -result {wrong # args: should be "::tls::digests ?name?"} -returnCodes {1}
-test Error_Cases-12.4 {MACs Too many args} -body {
+test Error_Cases-13.4 {MACs Too many args} -body {
::tls::macs too many args
- } -result {wrong # args: should be "::tls::macs"} -returnCodes {1}
+ } -result {wrong # args: should be "::tls::macs ?name?"} -returnCodes {1}
+
+test Error_Cases-13.5 {Pkeys Too many args} -body {
+ ::tls::pkeys too many args
+ } -result {wrong # args: should be "::tls::pkeys ?name?"} -returnCodes {1}
-test Error_Cases-12.5 {Protocols Too many args} -body {
+test Error_Cases-13.6 {Protocols Too many args} -body {
::tls::protocols too many args
} -result {wrong # args: should be "::tls::protocols"} -returnCodes {1}
-test Error_Cases-12.6 {Version Too many args} -body {
+test Error_Cases-13.7 {Version Too many args} -body {
::tls::version too many args
} -result {wrong # args: should be "::tls::version"} -returnCodes {1}
# Cleanup
::tcltest::cleanupTests
return