summaryrefslogtreecommitdiffstats
path: root/pki/base/native-tools/src/tkstool/tkstool.c
diff options
context:
space:
mode:
Diffstat (limited to 'pki/base/native-tools/src/tkstool/tkstool.c')
-rw-r--r--pki/base/native-tools/src/tkstool/tkstool.c2660
1 files changed, 2660 insertions, 0 deletions
diff --git a/pki/base/native-tools/src/tkstool/tkstool.c b/pki/base/native-tools/src/tkstool/tkstool.c
new file mode 100644
index 000000000..5368b2e7b
--- /dev/null
+++ b/pki/base/native-tools/src/tkstool/tkstool.c
@@ -0,0 +1,2660 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#include "tkstool.h"
+
+
+static char *progName;
+
+
+/* tkstool commands */
+enum {
+ cmd_DeleteKey = 0,
+ cmd_PrintHelp,
+ cmd_InputGenTransportKey,
+ cmd_DisplayKCV,
+ cmd_ListKeys,
+ cmd_GenMasterKey,
+ cmd_NewDBs,
+ cmd_ChangePassword,
+ cmd_RenameKey,
+ cmd_ListSecModules,
+ cmd_GenTransportKey,
+ cmd_UnWrapMasterKey,
+ cmd_Version,
+ cmd_WrapMasterKey
+};
+
+
+/* tkstool options */
+enum {
+ opt_DBDir = 0,
+ opt_PasswordFile,
+ opt_TokenName,
+ opt_InFile,
+ opt_Keyname,
+ opt_OutFile,
+ opt_DBPrefix,
+ opt_NewKeyname,
+ opt_TransportKeyname,
+ opt_RW,
+ opt_NoiseFile
+};
+
+
+static secuCommandFlag tkstool_commands[] = {
+ { /* cmd_DeleteKey */ 'D', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_PrintHelp */ 'H', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_InputGenTransportKey */ 'I', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_DisplayKCV */ 'K', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_ListKeys */ 'L', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_GenMasterKey */ 'M', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_NewDBs */ 'N', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_ChangePassword */ 'P', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_RenameKey */ 'R', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_ListSecModules */ 'S', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_GenTransportKey */ 'T', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_UnWrapMasterKey */ 'U', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_Version */ 'V', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_WrapMasterKey */ 'W', PR_FALSE, 0, PR_FALSE }
+};
+
+
+static secuCommandFlag tkstool_options[] = {
+ { /* opt_DBDir */ 'd', PR_TRUE, 0, PR_FALSE },
+ { /* opt_PasswordFile */ 'f', PR_TRUE, 0, PR_FALSE },
+ { /* opt_TokenName */ 'h', PR_TRUE, 0, PR_FALSE },
+ { /* opt_InFile */ 'i', PR_TRUE, 0, PR_FALSE },
+ { /* opt_Keyname */ 'n', PR_TRUE, 0, PR_FALSE },
+ { /* opt_OutFile */ 'o', PR_TRUE, 0, PR_FALSE },
+ { /* opt_DBPrefix */ 'p', PR_TRUE, 0, PR_FALSE },
+ { /* opt_NewKeyname */ 'r', PR_TRUE, 0, PR_FALSE },
+ { /* opt_TransportKeyname */ 't', PR_TRUE, 0, PR_FALSE },
+ { /* opt_RW */ 'x', PR_FALSE, 0, PR_FALSE },
+ { /* opt_NoiseFile */ 'z', PR_TRUE, 0, PR_FALSE },
+};
+
+
+int
+main( int argc, char **argv )
+{
+ CK_KEY_DERIVATION_STRING_DATA secondDerivationData = { NULL,
+ 0 };
+ CK_KEY_DERIVATION_STRING_DATA thirdDerivationData = { NULL,
+ 0 };
+ PK11SlotInfo *internalSlot = NULL;
+ PK11SlotInfo *slot = NULL;
+ PK11SymKey *symmetricKey = NULL;
+ PK11SymKey *masterKey = NULL;
+ PK11SymKey *temporaryMasterKey = NULL;
+ PK11SymKey *firstSymmetricKey = NULL;
+ PK11SymKey *secondSymmetricKey = NULL;
+ PK11SymKey *thirdSymmetricKey = NULL;
+ PK11SymKey *transportKey = NULL;
+ PRBool readOnly = PR_FALSE;
+ PRIntn KCVLen = KCV_LENGTH;
+ PRUint8 *KCV = NULL;
+ SECItem firstSessionKeyShare = { siBuffer,
+ NULL,
+ 0 };
+ SECItem secondSessionKeyShare = { siBuffer,
+ NULL,
+ 0 };
+ SECItem thirdSessionKeyShare = { siBuffer,
+ NULL,
+ 0 };
+#if defined(PAD_DES2_KEY_LENGTH)
+ SECItem paddedFirstSessionKeyShare = { siBuffer,
+ NULL,
+ 0 };
+ SECItem paddedSecondSessionKeyShare = { siBuffer,
+ NULL,
+ 0 };
+ SECItem paddedThirdSessionKeyShare = { siBuffer,
+ NULL,
+ 0 };
+#endif
+ SECItem hexInternalKeyKCV = { siBuffer,
+ NULL,
+ 0 };
+ SECItem wrappedMasterKey = { siBuffer,
+ NULL,
+ 0 };
+ SECStatus rvKCV = SECFailure;
+ SECStatus rvParse = SECSuccess;
+ SECStatus rvNSSinit = SECSuccess;
+ SECStatus rvFindSymKey = SECSuccess;
+ SECStatus rvSeedRNG = SECSuccess;
+ SECStatus rvFirstSessionKeyShare = SECFailure;
+ SECStatus rvSecondSessionKeyShare = SECFailure;
+ SECStatus rvThirdSessionKeyShare = SECFailure;
+ SECStatus rvSaveWrappedMasterKey = SECSuccess;
+ SECStatus rvSymmetricKeyname = SECSuccess;
+ SECStatus rvWrappedMasterKey = SECSuccess;
+ SECStatus rvMasterKeyname = SECSuccess;
+ SECStatus rv = SECSuccess;
+ SECStatus status = PR_FALSE;
+ char commandToRun = '\0';
+ char *DBDir = NULL;
+ char *DBPrefix = "";
+ char *input = NULL;
+ char *keyname = NULL;
+ char *new_keyname = NULL;
+ char *output = NULL;
+ char *SeedNoise = NULL;
+ char *slotname = "internal";
+ char *transport_keyname = NULL;
+ int commandsEntered = 0;
+ int i = 0;
+ int optionsEntered = 0;
+ secuPWData pwdata = { PW_NONE,
+ 0 };
+
+
+ /**************************/
+ /* Parse the command line */
+ /**************************/
+
+ secuCommand tkstool;
+ tkstool.numCommands = sizeof( tkstool_commands ) /
+ sizeof( secuCommandFlag );
+ tkstool.numOptions = sizeof( tkstool_options ) /
+ sizeof( secuCommandFlag );
+ tkstool.commands = tkstool_commands;
+ tkstool.options = tkstool_options;
+
+ /* retrieve name of command */
+ progName = strrchr( argv[0], '/' );
+ progName = progName ? ( progName + 1 ) : argv[0];
+
+ /* parse command line (command(s) and options) from command line */
+ rvParse = SECU_ParseCommandLine( argc, argv, progName, &tkstool );
+ if( rvParse != SECSuccess ) {
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+
+ /*********************************************************/
+ /* Check the number of command line "command(s)" entered */
+ /*********************************************************/
+
+ commandsEntered = 0;
+ for( i = 0 ; i < tkstool.numCommands ; i++ ) {
+ if( tkstool.commands[i].activated ) {
+ commandToRun = tkstool.commands[i].flag;
+ commandsEntered++;
+ }
+
+ if( commandsEntered > 1 ) {
+ break;
+ }
+ }
+
+ if( commandsEntered > 1 ) {
+ PR_fprintf( PR_STDERR,
+ "%s: only one command at a time!\n",
+ progName );
+
+ PR_fprintf( PR_STDERR,
+ "You entered: " );
+
+ for( i = 0 ; i < tkstool.numCommands ; i++ ) {
+ if( tkstool.commands[i].activated ) {
+ PR_fprintf( PR_STDERR,
+ " -%c",
+ tkstool.commands[i].flag );
+ }
+ }
+
+ PR_fprintf( PR_STDERR,
+ "\n" );
+ return 255;
+ }
+
+ if( commandsEntered == 0 ) {
+ PR_fprintf( PR_STDERR,
+ "%s: you must enter one of the following commands:\n\n",
+ progName );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+
+ /********************************************************/
+ /* Check the number of command line "option(s)" entered */
+ /********************************************************/
+
+ optionsEntered = 0;
+ for( i = 0 ; i < tkstool.numOptions ; i++ ) {
+ if( tkstool.options[i].activated ) {
+ optionsEntered++;
+ }
+
+ if( optionsEntered > 1 ) {
+ break;
+ }
+ }
+
+ if( optionsEntered == 0 &&
+ ! ( tkstool.commands[cmd_PrintHelp].activated ||
+ tkstool.commands[cmd_Version].activated ) ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: you must enter the following options "
+ "for this command:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+
+ /***************************************************/
+ /* Check that command line "options" correspond to */
+ /* one of their specified command line "commands" */
+ /***************************************************/
+
+ /* the "-d DBDir" command option may ONLY be used with */
+ /* the "-D", "-I", "-K", "-L", "-M", "-N", "-P", "-R", */
+ /* "-S", "-T", "-U", and "-W" commands */
+ if( tkstool.options[opt_DBDir].activated &&
+ ! ( tkstool.commands[cmd_DeleteKey].activated ||
+ tkstool.commands[cmd_InputGenTransportKey].activated ||
+ tkstool.commands[cmd_DisplayKCV].activated ||
+ tkstool.commands[cmd_ListKeys].activated ||
+ tkstool.commands[cmd_GenMasterKey].activated ||
+ tkstool.commands[cmd_NewDBs].activated ||
+ tkstool.commands[cmd_ChangePassword].activated ||
+ tkstool.commands[cmd_RenameKey].activated ||
+ tkstool.commands[cmd_ListSecModules].activated ||
+ tkstool.commands[cmd_GenTransportKey].activated ||
+ tkstool.commands[cmd_UnWrapMasterKey].activated ||
+ tkstool.commands[cmd_WrapMasterKey].activated ) ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-d DBDir\" option may only be "
+ "specified with one of the following command(s):\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* the "-f pwfile" command option may ONLY be used with */
+ /* the "-D", "-I", "-K", "-L", "-M", "-N", "-P", "-R", */
+ /* "-T", "-U", and "-W" commands */
+ if( tkstool.options[opt_PasswordFile].activated &&
+ ! ( tkstool.commands[cmd_DeleteKey].activated ||
+ tkstool.commands[cmd_InputGenTransportKey].activated ||
+ tkstool.commands[cmd_DisplayKCV].activated ||
+ tkstool.commands[cmd_ListKeys].activated ||
+ tkstool.commands[cmd_GenMasterKey].activated ||
+ tkstool.commands[cmd_NewDBs].activated ||
+ tkstool.commands[cmd_ChangePassword].activated ||
+ tkstool.commands[cmd_RenameKey].activated ||
+ tkstool.commands[cmd_GenTransportKey].activated ||
+ tkstool.commands[cmd_UnWrapMasterKey].activated ||
+ tkstool.commands[cmd_WrapMasterKey].activated ) ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-f pwfile\" option may only be "
+ "specified with one of the following command(s):\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* the "-h token_name" command option may ONLY be used with */
+ /* the "-D", "-I", "-K", "-L", "-M", "-R", "-T", "-U", and */
+ /* "-W" commands */
+ if( tkstool.options[opt_TokenName].activated &&
+ ! ( tkstool.commands[cmd_DeleteKey].activated ||
+ tkstool.commands[cmd_InputGenTransportKey].activated ||
+ tkstool.commands[cmd_DisplayKCV].activated ||
+ tkstool.commands[cmd_ListKeys].activated ||
+ tkstool.commands[cmd_GenMasterKey].activated ||
+ tkstool.commands[cmd_RenameKey].activated ||
+ tkstool.commands[cmd_GenTransportKey].activated ||
+ tkstool.commands[cmd_UnWrapMasterKey].activated ||
+ tkstool.commands[cmd_WrapMasterKey].activated ) ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-h token_name\" option may only be "
+ "specified with one of the following command(s):\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* the "-i infile" command option may ONLY be used with */
+ /* the "-U" command */
+ if( tkstool.options[opt_InFile].activated &&
+ !tkstool.commands[cmd_UnWrapMasterKey].activated ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-i infile\" option may only be "
+ "specified with one of the following command(s):\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* the "-n keyname" command option may ONLY be used with the */
+ /* "-D", "-I", "-K", "-L", "-M", "-R", "-T", "-U", and "-W" */
+ /* commands */
+ if( tkstool.options[opt_Keyname].activated &&
+ ! ( tkstool.commands[cmd_DeleteKey].activated ||
+ tkstool.commands[cmd_InputGenTransportKey].activated ||
+ tkstool.commands[cmd_DisplayKCV].activated ||
+ tkstool.commands[cmd_ListKeys].activated ||
+ tkstool.commands[cmd_GenMasterKey].activated ||
+ tkstool.commands[cmd_RenameKey].activated ||
+ tkstool.commands[cmd_GenTransportKey].activated ||
+ tkstool.commands[cmd_UnWrapMasterKey].activated ||
+ tkstool.commands[cmd_WrapMasterKey].activated ) ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-n keyname\" option may only be "
+ "specified with one of the following command(s):\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* the "-o outfile" command option may ONLY be used with */
+ /* the "-W" command */
+ if( tkstool.options[opt_OutFile].activated &&
+ !tkstool.commands[cmd_WrapMasterKey].activated ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-o outfile\" option may only be "
+ "specified with one of the following command(s):\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* the "-p DBPrefix" command option may ONLY be used with */
+ /* the "-D", "-I", "-K", "-L", "-M", "-N", "-P", "-R", */
+ /* "-S", "-T", "-U", and "-W" commands */
+ if( tkstool.options[opt_DBPrefix].activated &&
+ ! ( tkstool.commands[cmd_DeleteKey].activated ||
+ tkstool.commands[cmd_InputGenTransportKey].activated ||
+ tkstool.commands[cmd_DisplayKCV].activated ||
+ tkstool.commands[cmd_ListKeys].activated ||
+ tkstool.commands[cmd_GenMasterKey].activated ||
+ tkstool.commands[cmd_NewDBs].activated ||
+ tkstool.commands[cmd_ChangePassword].activated ||
+ tkstool.commands[cmd_RenameKey].activated ||
+ tkstool.commands[cmd_ListSecModules].activated ||
+ tkstool.commands[cmd_GenTransportKey].activated ||
+ tkstool.commands[cmd_UnWrapMasterKey].activated ||
+ tkstool.commands[cmd_WrapMasterKey].activated ) ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-p DBPrefix\" option may only be "
+ "specified with one of the following command(s):\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* the "-r new_keyname" command option may */
+ /* ONLY be used with the "-R" command */
+ if( tkstool.options[opt_NewKeyname].activated &&
+ ! ( tkstool.commands[cmd_RenameKey].activated ) ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-r new_keyname\" option may only be "
+ "specified with one of the following command(s):\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* the "-t transport_keyname" command option may ONLY be used with */
+ /* the "-U", and "-W" commands */
+ if( tkstool.options[opt_TransportKeyname].activated &&
+ !( tkstool.commands[cmd_UnWrapMasterKey].activated ||
+ tkstool.commands[cmd_WrapMasterKey].activated ) ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-t transport_keyname\" option may only be "
+ "specified with one of the following command(s):\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* the "-x" command option may ONLY be used with */
+ /* the "-L", and "-S" commands */
+ if( tkstool.options[opt_RW].activated &&
+ ! ( tkstool.commands[cmd_ListKeys].activated ||
+ tkstool.commands[cmd_ListSecModules].activated ) ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-x\" option may only be "
+ "specified with one of the following command(s):\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* the "-z noisefile" command option may ONLY be used with */
+ /* the "-T" command */
+ if( tkstool.options[opt_NoiseFile].activated &&
+ !tkstool.commands[cmd_GenTransportKey].activated ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-z noisefile\" option may only be "
+ "specified with one of the following command(s):\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+
+ /********************************************************/
+ /* Perform special processing on command line "options" */
+ /********************************************************/
+
+ /* "-d DBDir" command option */
+ if( tkstool.options[opt_DBDir].activated ) {
+ if( tkstool.options[opt_DBDir].arg ) {
+ DBDir = SECU_ConfigDirectory( tkstool.options[opt_DBDir].arg );
+ } else {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-d\" option must contain a "
+ "\"DBDir\" argument:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+ }
+
+ /* "-f pwfile" command option */
+ if( tkstool.options[opt_PasswordFile].activated ) {
+ pwdata.source = PW_FROMFILE;
+ if( tkstool.options[opt_PasswordFile].arg ) {
+ pwdata.data = tkstool.options[opt_PasswordFile].arg;
+ } else {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-f\" option must contain a "
+ "\"pwfile\" argument:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+ }
+
+ /* "-i infile" command option */
+ if( tkstool.options[opt_InFile].activated ) {
+ if( tkstool.options[opt_InFile].arg ) {
+ input = tkstool.options[opt_InFile].arg;
+ } else {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-i\" option must contain an "
+ "\"infile\" argument:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+ }
+
+ /* "-h token_name" command option */
+ if( tkstool.options[opt_TokenName].activated ) {
+ if( tkstool.options[opt_TokenName].arg ) {
+ if( PL_strcmp( tkstool.options[opt_TokenName].arg, "all" ) == 0 ) {
+ slotname = NULL;
+ } else {
+ slotname = PL_strdup( tkstool.options[opt_TokenName].arg );
+ }
+ } else {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-h\" option must contain a "
+ "\"token_name\" argument:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+ }
+
+ /* "-n keyname" command option */
+ if( tkstool.options[opt_Keyname].activated ) {
+ if( tkstool.options[opt_Keyname].arg ) {
+ keyname = SECU_GetOptionArg( &tkstool,
+ opt_Keyname );
+ } else {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-n\" option must contain a "
+ "\"keyname\" argument:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+ }
+
+ /* "-o outfile" command option */
+ if( tkstool.options[opt_OutFile].activated ) {
+ if( tkstool.options[opt_OutFile].arg ) {
+ output = tkstool.options[opt_OutFile].arg;
+ } else {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-o\" option must contain an "
+ "\"outfile\" argument:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+ }
+
+ /* "-p DBPrefix" command option */
+ if( tkstool.options[opt_DBPrefix].activated ) {
+ if( tkstool.options[opt_DBPrefix].arg ) {
+ DBPrefix = strdup( tkstool.options[opt_DBPrefix].arg );
+ } else {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-p\" option must contain a "
+ "\"DBPrefix\" argument:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+ }
+
+ /* "-r new_keyname" command option */
+ if( tkstool.options[opt_NewKeyname].activated ) {
+ if( tkstool.options[opt_NewKeyname].arg ) {
+ new_keyname = SECU_GetOptionArg( &tkstool,
+ opt_NewKeyname );
+ } else {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-r\" option must contain a "
+ "\"new_keyname\" argument:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+ }
+
+ /* "-t transport_keyname" command option */
+ if( tkstool.options[opt_TransportKeyname].activated ) {
+ if( tkstool.options[opt_TransportKeyname].arg ) {
+ transport_keyname = SECU_GetOptionArg( &tkstool,
+ opt_TransportKeyname );
+ } else {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-t\" option must contain a "
+ "\"transport_keyname\" argument:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+ }
+
+ /* "-x" command option is processed below */
+ /* ONLY based upon specific commands */
+
+ /* "-z noisefile" command option */
+ if( tkstool.options[opt_NoiseFile].activated ) {
+ if( tkstool.options[opt_NoiseFile].arg ) {
+ SeedNoise = tkstool.options[opt_NoiseFile].arg;
+ } else {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-z\" option must contain a "
+ "\"noisefile\" argument:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+ }
+
+
+ /******************************************************************/
+ /* Perform special processing on specific command line "commands" */
+ /******************************************************************/
+
+ /* "-D", "-I", "-K", "-M", "-R", "-T", "-U" and "-W" */
+ /* commands require the "-n keyname" command line */
+ /* option to be specified */
+ if( ( tkstool.commands[cmd_DeleteKey].activated ||
+ tkstool.commands[cmd_InputGenTransportKey].activated ||
+ tkstool.commands[cmd_DisplayKCV].activated ||
+ tkstool.commands[cmd_GenMasterKey].activated ||
+ tkstool.commands[cmd_RenameKey].activated ||
+ tkstool.commands[cmd_GenTransportKey].activated ||
+ tkstool.commands[cmd_UnWrapMasterKey].activated ||
+ tkstool.commands[cmd_WrapMasterKey].activated ) &&
+ !tkstool.options[opt_Keyname].activated ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-n keyname\" option is required "
+ "for this command:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* "-D", "-I", "-K", "-L", "-M", "-N", "-P", "-R", "-S", */
+ /* "-T", "-U", and "-W" commands require the "-d DBDir" */
+ /* command line option to be specified */
+ if( ( tkstool.commands[cmd_DeleteKey].activated ||
+ tkstool.commands[cmd_InputGenTransportKey].activated ||
+ tkstool.commands[cmd_DisplayKCV].activated ||
+ tkstool.commands[cmd_ListKeys].activated ||
+ tkstool.commands[cmd_GenMasterKey].activated ||
+ tkstool.commands[cmd_NewDBs].activated ||
+ tkstool.commands[cmd_ChangePassword].activated ||
+ tkstool.commands[cmd_RenameKey].activated ||
+ tkstool.commands[cmd_ListSecModules].activated ||
+ tkstool.commands[cmd_GenTransportKey].activated ||
+ tkstool.commands[cmd_UnWrapMasterKey].activated ||
+ tkstool.commands[cmd_WrapMasterKey].activated ) &&
+ !tkstool.options[opt_DBDir].activated ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-d DBDir\" option is required "
+ "for this command:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* "-H", "-L", "-S", and "-V" commands require the "-x" */
+ /* command line option to be silently turned off */
+ if( tkstool.commands[cmd_PrintHelp].activated ||
+ tkstool.commands[cmd_ListKeys].activated ||
+ tkstool.commands[cmd_ListSecModules].activated ||
+ tkstool.commands[cmd_Version].activated ) {
+ readOnly = !tkstool.options[opt_RW].activated;
+ }
+
+ /* "-L" command is the ONLY command that allows */
+ /* the "-h all" command line option to be used */
+ /* */
+ /* NOTE: ONLY use "slotname == NULL" to */
+ /* LIST keys on all slots */
+ if( !tkstool.commands[cmd_ListKeys].activated && slotname == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: cannot use \"-h all\" for this command:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* "-R" commands require the "-r new_keyname" */
+ /* command line option to be specified */
+ if( ( tkstool.commands[cmd_RenameKey].activated ) &&
+ !tkstool.options[opt_NewKeyname].activated ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-r new_keyname\" option is required "
+ "for this command:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* "-U", and "-W" commands require the "-t transport_keyname" */
+ /* command line option to be specified */
+ if( ( tkstool.commands[cmd_UnWrapMasterKey].activated ||
+ tkstool.commands[cmd_WrapMasterKey].activated ) &&
+ !tkstool.options[opt_TransportKeyname].activated ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-t transport_keyname\" option is required "
+ "for this command:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* "-U" commands require the "-i infile" */
+ /* command line option to be specified */
+ if( tkstool.commands[cmd_UnWrapMasterKey].activated &&
+ !tkstool.options[opt_InFile].activated ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-i infile\" option is required "
+ "for this command:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* "-W" commands require the "-o outfile" */
+ /* command line option to be specified */
+ if( tkstool.commands[cmd_WrapMasterKey].activated &&
+ !tkstool.options[opt_OutFile].activated ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-o outfile\" option is required "
+ "for this command:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+
+ /*********************************/
+ /* Execute the "-H" help command */
+ /*********************************/
+
+ if( tkstool.commands[cmd_PrintHelp].activated ) {
+ TKS_PrintHelp( progName );
+
+ return 0;
+ }
+
+
+ /************************************/
+ /* Execute the "-V" version command */
+ /************************************/
+
+ /* "-V" version command */
+ if( tkstool.commands[cmd_Version].activated ) {
+ TKS_Version( progName );
+
+ return 0;
+ }
+
+
+ /************************************************/
+ /* Initialize PKCS #11 Security Module Password */
+ /************************************************/
+
+ PK11_SetPasswordFunc( /* password callback */ SECU_GetModulePassword );
+
+
+ /*******************/
+ /* Initialize NSPR */
+ /*******************/
+
+ PR_Init( PR_SYSTEM_THREAD,
+ PR_PRIORITY_NORMAL,
+ 1 );
+
+
+ /******************/
+ /* Initialize NSS */
+ /******************/
+
+ rvNSSinit = NSS_Initialize( DBDir,
+ DBPrefix,
+ DBPrefix,
+ "secmod.db",
+ readOnly ? NSS_INIT_READONLY : 0 );
+ if( rvNSSinit != SECSuccess ) {
+ char buffer[513];
+ PRInt32 errLen = PR_GetErrorTextLength();
+
+ if( errLen > 0 && errLen < sizeof buffer ) {
+ PR_GetErrorText( buffer );
+ }
+
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s",
+ progName,
+ commandToRun,
+ "NSS_Initialize() failed" );
+
+ if( errLen > 0 && errLen < sizeof buffer ) {
+ PR_fprintf( PR_STDERR, "\t%s\n", buffer );
+ } else {
+ PR_fprintf( PR_STDERR, "\n" );
+ }
+
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*****************************************************/
+ /* Initialize internal PKCS #11 software crypto slot */
+ /* as well as any specified PKCS #11 slot */
+ /*****************************************************/
+
+ /* Always initialize the internal software crypto slot */
+ internalSlot = PK11_GetInternalSlot();
+
+ /* If "slotname != NULL", initialize the slot based upon the slotname */
+ if( PL_strcmp( slotname, "internal" ) == 0 ) {
+ slot = PK11_GetInternalKeySlot();
+ } else if( slotname != NULL ) {
+ slot = PK11_FindSlotByName( /* slot name */ slotname );
+
+ /* Fixes Bugscape Bug #55178: tkstool dumps core if -h <token> */
+ /* specifies a nonexistent token */
+ if( slot == NULL ) {
+ char buffer[513];
+ PRInt32 errLen = PR_GetErrorTextLength();
+
+ if( errLen > 0 && errLen < sizeof buffer ) {
+ PR_GetErrorText( buffer );
+ }
+
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s%s%s",
+ progName,
+ commandToRun,
+ "no token called \"",
+ slotname,
+ "\" exists!" );
+
+ if( errLen > 0 && errLen < sizeof buffer ) {
+ PR_fprintf( PR_STDERR, "\t%s\n", buffer );
+ } else {
+ PR_fprintf( PR_STDERR, "\n" );
+ }
+
+ rv = SECFailure;
+ goto shutdown;
+ }
+ }
+
+
+ /****************************************/
+ /* Execute the "-D" delete keys command */
+ /* */
+ /* NOTE: This command is mutually */
+ /* exclusive from all others. */
+ /****************************************/
+
+ if( tkstool.commands[cmd_DeleteKey].activated ) {
+ rv = TKS_DeleteKeys( progName,
+ slot,
+ keyname,
+ &pwdata );
+ goto shutdown;
+ }
+
+
+ /*******************************************************************/
+ /* Execute the "-I" input shares to generate transport key command */
+ /* */
+ /* --- OR --- */
+ /* */
+ /* Execute the "-T" generate transport key command */
+ /* */
+ /* NOTE: Each of these commands is mutually */
+ /* exclusive from all others, including */
+ /* each other. */
+ /*******************************************************************/
+
+ if( tkstool.commands[cmd_InputGenTransportKey].activated ||
+ tkstool.commands[cmd_GenTransportKey].activated ) {
+
+ /**********************************************************/
+ /* Do not allow duplicate symmetric keys to be generated */
+ /* (i. e. - disallow symmetric keys specified */
+ /* by the same keyname) */
+ /* */
+ /* NOTE: The following code snippet effectively */
+ /* prohibits this tool from generating any */
+ /* symmetric key with a keyname that already */
+ /* resides in the specified token */
+ /**********************************************************/
+
+ rvFindSymKey = TKS_FindSymKey( slot,
+ keyname,
+ &pwdata );
+ if( rvFindSymKey == SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c:\tthe \"%s\" keyname specified by "
+ "\n\t\t\"-n %s\"\n\t\talready exists in the "
+ "specified token.\n\t\tPlease specify a "
+ "different keyname.\n\n",
+ progName,
+ commandToRun,
+ keyname,
+ keyname );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /**********************************************/
+ /* Seed the Random Number Generator (RNG). */
+ /* ("-T" generate transport key command ONLY) */
+ /**********************************************/
+
+ if( tkstool.commands[cmd_GenTransportKey].activated ) {
+ rvSeedRNG = TKS_SeedRNG( SeedNoise );
+ if( rvSeedRNG != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s",
+ progName,
+ commandToRun,
+ "unable to seed random number generator\n" );
+ rv = SECFailure;
+ goto shutdown;
+ }
+ }
+
+
+ /***********************************/
+ /* Clear screen and wait for user. */
+ /***********************************/
+
+ TKS_ClearScreen();
+
+ if( tkstool.commands[cmd_GenTransportKey].activated ) {
+ PR_fprintf( PR_STDOUT,
+ "\nThe next screen generates the "
+ "first session key share . . .\n" );
+ } else {
+ /* ( tkstool.commands[cmd_InputGenTransportKey].activated ) */
+ PR_fprintf( PR_STDOUT,
+ "\nUse the next screen to input the "
+ "first session key share . . .\n" );
+ }
+
+ TKS_TypeProceedToContinue();
+
+
+ /******************************************************************/
+ /* Input ("-I"), or Generate ("-T"), the first session key share. */
+ /******************************************************************/
+
+ firstSessionKeyShare.len = FIRST_SESSION_KEY_SHARE_LENGTH;
+ firstSessionKeyShare.data = ( unsigned char * )
+ PORT_ZAlloc( FIRST_SESSION_KEY_SHARE_LENGTH );
+
+ if( tkstool.commands[cmd_GenTransportKey].activated ) {
+ rvFirstSessionKeyShare = TKS_GenerateSessionKeyShare(
+ FIRST_SESSION_KEY_SHARE,
+ &firstSessionKeyShare );
+
+ if( rvFirstSessionKeyShare != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s",
+ progName,
+ commandToRun,
+ "unable to generate the ",
+ FIRST_SESSION_KEY_SHARE,
+ " session key share\n" );
+ rv = SECFailure;
+ goto shutdown;
+ }
+ } else {
+ /* ( tkstool.commands[cmd_InputGenTransportKey].activated ) */
+ while( rvFirstSessionKeyShare != SECSuccess ) {
+ rvFirstSessionKeyShare = TKS_InputSessionKeyShare(
+ FIRST_SESSION_KEY_SHARE,
+ &firstSessionKeyShare );
+ }
+ }
+
+#if defined(PAD_DES2_KEY_LENGTH)
+ /****************************************************************/
+ /* Since TKS uses double-DES keys instead of triple-DES keys, */
+ /* the final 8 bytes of this session key share must be padded */
+ /* in order to use the standard PKCS #11 triple-DES operations! */
+ /* */
+ /* Therefore, in order to perform this operation, the 16 bytes */
+ /* comprising the original buffer are first copied into the new */
+ /* buffer, and then the first 8 bytes of the original buffer */
+ /* are copied into the final 8 bytes of the new buffer. */
+ /****************************************************************/
+
+ paddedFirstSessionKeyShare.len = PADDED_FIRST_SESSION_KEY_SHARE_LENGTH;
+ paddedFirstSessionKeyShare.data = ( unsigned char * )
+ PORT_ZAlloc( PADDED_FIRST_SESSION_KEY_SHARE_LENGTH );
+
+ PORT_Memcpy( paddedFirstSessionKeyShare.data,
+ firstSessionKeyShare.data,
+ FIRST_SESSION_KEY_SHARE_LENGTH );
+ PORT_Memcpy( ( paddedFirstSessionKeyShare.data +
+ FIRST_SESSION_KEY_SHARE_LENGTH ),
+ firstSessionKeyShare.data,
+ DES_LENGTH );
+#endif
+
+
+ /***********************************/
+ /* Clear screen and wait for user. */
+ /***********************************/
+
+ TKS_ClearScreen();
+
+ if( tkstool.commands[cmd_GenTransportKey].activated ) {
+ PR_fprintf( PR_STDOUT,
+ "\nThe next screen generates the "
+ "second session key share . . .\n" );
+ } else {
+ /* ( tkstool.commands[cmd_InputGenTransportKey].activated ) */
+ PR_fprintf( PR_STDOUT,
+ "\nUse the next screen to input the "
+ "second session key share . . .\n" );
+ }
+
+ TKS_TypeProceedToContinue();
+
+
+ /*******************************************************************/
+ /* Input ("-I"), or Generate ("-T"), the second session key share. */
+ /*******************************************************************/
+
+ secondSessionKeyShare.len = SECOND_SESSION_KEY_SHARE_LENGTH;
+ secondSessionKeyShare.data = ( unsigned char * )
+ PORT_ZAlloc( SECOND_SESSION_KEY_SHARE_LENGTH );
+
+ if( tkstool.commands[cmd_GenTransportKey].activated ) {
+ rvSecondSessionKeyShare = TKS_GenerateSessionKeyShare(
+ SECOND_SESSION_KEY_SHARE,
+ &secondSessionKeyShare );
+
+ if( rvSecondSessionKeyShare != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s",
+ progName,
+ commandToRun,
+ "unable to generate the ",
+ SECOND_SESSION_KEY_SHARE,
+ " session key share\n" );
+ rv = SECFailure;
+ goto shutdown;
+ }
+ } else {
+ /* ( tkstool.commands[cmd_InputGenTransportKey].activated ) */
+ while( rvSecondSessionKeyShare != SECSuccess ) {
+ rvSecondSessionKeyShare = TKS_InputSessionKeyShare(
+ SECOND_SESSION_KEY_SHARE,
+ &secondSessionKeyShare );
+ }
+ }
+
+#if defined(PAD_DES2_KEY_LENGTH)
+ /****************************************************************/
+ /* Since TKS uses double-DES keys instead of triple-DES keys, */
+ /* the final 8 bytes of this session key share must be padded */
+ /* in order to use the standard PKCS #11 triple-DES operations! */
+ /* */
+ /* Therefore, in order to perform this operation, the 16 bytes */
+ /* comprising the original buffer are first copied into the new */
+ /* buffer, and then the first 8 bytes of the original buffer */
+ /* are copied into the final 8 bytes of the new buffer. */
+ /****************************************************************/
+
+ paddedSecondSessionKeyShare.len = PADDED_SECOND_SESSION_KEY_SHARE_LENGTH;
+ paddedSecondSessionKeyShare.data = ( unsigned char * )
+ PORT_ZAlloc( PADDED_SECOND_SESSION_KEY_SHARE_LENGTH );
+
+ PORT_Memcpy( paddedSecondSessionKeyShare.data,
+ secondSessionKeyShare.data,
+ SECOND_SESSION_KEY_SHARE_LENGTH );
+ PORT_Memcpy( ( paddedSecondSessionKeyShare.data +
+ SECOND_SESSION_KEY_SHARE_LENGTH ),
+ secondSessionKeyShare.data,
+ DES_LENGTH );
+
+
+ /**********************************************/
+ /* Prepare this key share to be used with the */
+ /* TKS_DeriveSymmetricKey() function . . . */
+ /**********************************************/
+
+ /* store a copy of the "original" padded second session key share */
+ secondDerivationData.ulLen = paddedSecondSessionKeyShare.len;
+ secondDerivationData.pData = ( unsigned char * )
+ PORT_ZAlloc( paddedSecondSessionKeyShare.len );
+ PORT_Memcpy( secondDerivationData.pData,
+ paddedSecondSessionKeyShare.data,
+ paddedSecondSessionKeyShare.len );
+
+ /* destroy the "original" padded second session key share */
+ if( paddedSecondSessionKeyShare.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ paddedSecondSessionKeyShare.data,
+ paddedSecondSessionKeyShare.len );
+ paddedSecondSessionKeyShare.data = NULL;
+ paddedSecondSessionKeyShare.len = 0;
+ }
+
+ /* create a "new" container for the padded second session key share */
+ paddedSecondSessionKeyShare.len = sizeof( CK_KEY_DERIVATION_STRING_DATA );
+ paddedSecondSessionKeyShare.data = ( unsigned char * )
+ PORT_ZAlloc( paddedSecondSessionKeyShare.len );
+
+ /* copy the "original" padded second session key share */
+ /* into the "new" container */
+ PORT_Memcpy( paddedSecondSessionKeyShare.data,
+ &secondDerivationData,
+ paddedSecondSessionKeyShare.len );
+#else
+ /**********************************************/
+ /* Prepare this key share to be used with the */
+ /* TKS_DeriveSymmetricKey() function . . . */
+ /**********************************************/
+
+ /* store a copy of the "original" second session key share */
+ secondDerivationData.ulLen = secondSessionKeyShare.len;
+ secondDerivationData.pData = ( unsigned char * )
+ PORT_ZAlloc( secondSessionKeyShare.len );
+ PORT_Memcpy( secondDerivationData.pData,
+ secondSessionKeyShare.data,
+ secondSessionKeyShare.len );
+
+ /* destroy the "original" second session key share */
+ if( secondSessionKeyShare.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ secondSessionKeyShare.data,
+ secondSessionKeyShare.len );
+ secondSessionKeyShare.data = NULL;
+ secondSessionKeyShare.len = 0;
+ }
+
+ /* create a "new" container for the second session key share */
+ secondSessionKeyShare.len = sizeof( CK_KEY_DERIVATION_STRING_DATA );
+ secondSessionKeyShare.data = ( unsigned char * )
+ PORT_ZAlloc( secondSessionKeyShare.len );
+
+ /* copy the "original" second session key share */
+ /* into the "new" container */
+ PORT_Memcpy( secondSessionKeyShare.data,
+ &secondDerivationData,
+ secondSessionKeyShare.len );
+#endif
+
+
+ /***********************************/
+ /* Clear screen and wait for user. */
+ /***********************************/
+
+ TKS_ClearScreen();
+
+ if( tkstool.commands[cmd_GenTransportKey].activated ) {
+ PR_fprintf( PR_STDOUT,
+ "\nThe next screen generates the "
+ "third session key share . . .\n" );
+ } else {
+ /* ( tkstool.commands[cmd_InputGenTransportKey].activated ) */
+ PR_fprintf( PR_STDOUT,
+ "\nUse the next screen to input the "
+ "third session key share . . .\n" );
+ }
+
+ TKS_TypeProceedToContinue();
+
+
+ /******************************************************************/
+ /* Input ("-I"), or Generate ("-T"), the third session key share. */
+ /******************************************************************/
+
+ thirdSessionKeyShare.len = THIRD_SESSION_KEY_SHARE_LENGTH;
+ thirdSessionKeyShare.data = ( unsigned char * )
+ PORT_ZAlloc( THIRD_SESSION_KEY_SHARE_LENGTH );
+
+ if( tkstool.commands[cmd_GenTransportKey].activated ) {
+ rvThirdSessionKeyShare = TKS_GenerateSessionKeyShare(
+ THIRD_SESSION_KEY_SHARE,
+ &thirdSessionKeyShare );
+
+ if( rvThirdSessionKeyShare != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s",
+ progName,
+ commandToRun,
+ "unable to generate the ",
+ THIRD_SESSION_KEY_SHARE,
+ " session key share\n" );
+ rv = SECFailure;
+ goto shutdown;
+ }
+ } else {
+ /* ( tkstool.commands[cmd_InputGenTransportKey].activated ) */
+ while( rvThirdSessionKeyShare != SECSuccess ) {
+ rvThirdSessionKeyShare = TKS_InputSessionKeyShare(
+ THIRD_SESSION_KEY_SHARE,
+ &thirdSessionKeyShare );
+ }
+ }
+
+#if defined(PAD_DES2_KEY_LENGTH)
+ /****************************************************************/
+ /* Since TKS uses double-DES keys instead of triple-DES keys, */
+ /* the final 8 bytes of this session key share must be padded */
+ /* in order to use the standard PKCS #11 triple-DES operations! */
+ /* */
+ /* Therefore, in order to perform this operation, the 16 bytes */
+ /* comprising the original buffer are first copied into the new */
+ /* buffer, and then the first 8 bytes of the original buffer */
+ /* are copied into the final 8 bytes of the new buffer. */
+ /****************************************************************/
+
+ paddedThirdSessionKeyShare.len = PADDED_THIRD_SESSION_KEY_SHARE_LENGTH;
+ paddedThirdSessionKeyShare.data = ( unsigned char * )
+ PORT_ZAlloc( PADDED_THIRD_SESSION_KEY_SHARE_LENGTH );
+
+ PORT_Memcpy( paddedThirdSessionKeyShare.data,
+ thirdSessionKeyShare.data,
+ THIRD_SESSION_KEY_SHARE_LENGTH );
+ PORT_Memcpy( ( paddedThirdSessionKeyShare.data +
+ THIRD_SESSION_KEY_SHARE_LENGTH ),
+ thirdSessionKeyShare.data,
+ DES_LENGTH );
+
+
+ /**********************************************/
+ /* Prepare this key share to be used with the */
+ /* TKS_DeriveSymmetricKey() function . . . */
+ /**********************************************/
+
+ /* store a copy of the "original" padded third session key share */
+ thirdDerivationData.ulLen = paddedThirdSessionKeyShare.len;
+ thirdDerivationData.pData = ( unsigned char * )
+ PORT_ZAlloc( paddedThirdSessionKeyShare.len );
+ PORT_Memcpy( thirdDerivationData.pData,
+ paddedThirdSessionKeyShare.data,
+ paddedThirdSessionKeyShare.len );
+
+ /* destroy the "original" padded third session key share */
+ if( paddedThirdSessionKeyShare.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ paddedThirdSessionKeyShare.data,
+ paddedThirdSessionKeyShare.len );
+ paddedThirdSessionKeyShare.data = NULL;
+ paddedThirdSessionKeyShare.len = 0;
+ }
+
+ /* create a "new" container for the padded third session key share */
+ paddedThirdSessionKeyShare.len = sizeof( CK_KEY_DERIVATION_STRING_DATA );
+ paddedThirdSessionKeyShare.data = ( unsigned char * )
+ PORT_ZAlloc( paddedThirdSessionKeyShare.len );
+
+ /* copy the "original" padded third session key share */
+ /* into the "new" container */
+ PORT_Memcpy( paddedThirdSessionKeyShare.data,
+ &thirdDerivationData,
+ paddedThirdSessionKeyShare.len );
+#else
+ /**********************************************/
+ /* Prepare this key share to be used with the */
+ /* TKS_DeriveSymmetricKey() function . . . */
+ /**********************************************/
+
+ /* store a copy of the "original" third session key share */
+ thirdDerivationData.ulLen = thirdSessionKeyShare.len;
+ thirdDerivationData.pData = ( unsigned char * )
+ PORT_ZAlloc( thirdSessionKeyShare.len );
+ PORT_Memcpy( thirdDerivationData.pData,
+ thirdSessionKeyShare.data,
+ thirdSessionKeyShare.len );
+
+ /* destroy the "original" third session key share */
+ if( thirdSessionKeyShare.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ thirdSessionKeyShare.data,
+ thirdSessionKeyShare.len );
+ thirdSessionKeyShare.data = NULL;
+ thirdSessionKeyShare.len = 0;
+ }
+
+ /* create a "new" container for the third session key share */
+ thirdSessionKeyShare.len = sizeof( CK_KEY_DERIVATION_STRING_DATA );
+ thirdSessionKeyShare.data = ( unsigned char * )
+ PORT_ZAlloc( thirdSessionKeyShare.len );
+
+ /* copy the "original" third session key share */
+ /* into the "new" container */
+ PORT_Memcpy( thirdSessionKeyShare.data,
+ &thirdDerivationData,
+ thirdSessionKeyShare.len );
+#endif
+
+
+ /***********************************/
+ /* Clear screen and wait for user. */
+ /***********************************/
+
+ TKS_ClearScreen();
+
+ PR_fprintf( PR_STDOUT,
+ "\nThe next screen uses the session key shares to "
+ "generate the transport key . . .\n" );
+
+ TKS_TypeProceedToContinue();
+
+ TKS_ClearScreen();
+
+
+ /**************************************/
+ /* Generate the first symmetric key */
+ /* using the first session key share. */
+ /**************************************/
+
+
+#if defined(PAD_DES2_KEY_LENGTH)
+ firstSymmetricKey = TKS_ImportSymmetricKey( FIRST_SYMMETRIC_KEY,
+ internalSlot,
+ CKM_DES3_KEY_GEN,
+ CKA_ENCRYPT,
+ &paddedFirstSessionKeyShare,
+ &pwdata );
+#else
+ firstSymmetricKey = TKS_ImportSymmetricKey( FIRST_SYMMETRIC_KEY,
+ internalSlot,
+ CKM_DES2_KEY_GEN,
+ CKA_ENCRYPT,
+ &firstSessionKeyShare,
+ &pwdata );
+#endif
+ if( firstSymmetricKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s:%d\n",
+ progName,
+ commandToRun,
+ "unable to generate the first (or initial) "
+ "symmetric key",
+ PR_GetError() );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*********************************************************/
+ /* Generate the second symmetric key using the */
+ /* first symmetric key and the second session key share. */
+ /*********************************************************/
+
+#if defined(PAD_DES2_KEY_LENGTH)
+ secondSymmetricKey = TKS_DeriveSymmetricKey( SECOND_SYMMETRIC_KEY,
+ firstSymmetricKey,
+ CKM_XOR_BASE_AND_DATA,
+ &paddedSecondSessionKeyShare,
+ CKM_DES3_ECB,
+ ( CKA_DERIVE |
+ CKA_ENCRYPT ),
+ PADDED_SECOND_SESSION_KEY_SHARE_LENGTH );
+#else
+ secondSymmetricKey = TKS_DeriveSymmetricKey( SECOND_SYMMETRIC_KEY,
+ firstSymmetricKey,
+ CKM_XOR_BASE_AND_DATA,
+ &secondSessionKeyShare,
+ CKM_DES3_ECB,
+ ( CKA_DERIVE |
+ CKA_ENCRYPT ),
+ SECOND_SESSION_KEY_SHARE_LENGTH );
+#endif
+ if( secondSymmetricKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s:%d\n",
+ progName,
+ commandToRun,
+ "unable to generate the second (or intermediate) "
+ "symmetric key",
+ PR_GetError() );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*********************************************************/
+ /* Generate the third symmetric key using the */
+ /* second symmetric key and the third session key share. */
+ /*********************************************************/
+
+#if defined(PAD_DES2_KEY_LENGTH)
+ thirdSymmetricKey = TKS_DeriveSymmetricKey( THIRD_SYMMETRIC_KEY,
+ secondSymmetricKey,
+ CKM_XOR_BASE_AND_DATA,
+ &paddedThirdSessionKeyShare,
+ CKM_DES3_ECB,
+ ( CKA_DERIVE |
+ CKA_ENCRYPT ),
+ PADDED_THIRD_SESSION_KEY_SHARE_LENGTH );
+#else
+ thirdSymmetricKey = TKS_DeriveSymmetricKey( THIRD_SYMMETRIC_KEY,
+ secondSymmetricKey,
+ CKM_XOR_BASE_AND_DATA,
+ &thirdSessionKeyShare,
+ CKM_DES3_ECB,
+ ( CKA_DERIVE |
+ CKA_ENCRYPT ),
+ THIRD_SESSION_KEY_SHARE_LENGTH );
+#endif
+ if( thirdSymmetricKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s:%d\n",
+ progName,
+ commandToRun,
+ "unable to generate the third (or final) "
+ "symmetric key",
+ PR_GetError() );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*******************************************************************/
+ /* Finally, store the third symmetric key (the transport key) into */
+ /* the specified slot, and provide a name for this transport key. */
+ /*******************************************************************/
+
+ rvSymmetricKeyname = TKS_StoreSymmetricKeyAndNameIt( TRANSPORT_KEY,
+ keyname,
+ slot,
+ ( CKA_ENCRYPT |
+ CKA_WRAP ),
+ ( CKF_ENCRYPT |
+ CKF_UNWRAP |
+ CKF_WRAP ),
+ thirdSymmetricKey );
+ if( rvSymmetricKeyname != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Failed to save/name the transport key!\n\n" );
+ rv = SECFailure;
+ goto shutdown;
+ } else {
+ PR_fprintf( PR_STDOUT,
+ "Successfully generated, stored, and named the "
+ "transport key!\n\n" );
+ }
+
+
+ /*********************************/
+ /* Cleanup and exit with success */
+ /*********************************/
+
+ rv = SECSuccess;
+ goto shutdown;
+ }
+
+
+ /****************************************/
+ /* Execute the "-K" display KCV command */
+ /* */
+ /* NOTE: This command is mutually */
+ /* exclusive from all others. */
+ /****************************************/
+
+ if( tkstool.commands[cmd_DisplayKCV].activated ) {
+
+ /*****************************************************/
+ /* Retrieve a handle to the specified symmetric key. */
+ /* This insures that the specified symmetric key */
+ /* already resides on the specified token. */
+ /*****************************************************/
+
+ symmetricKey = TKS_RetrieveSymKey( slot,
+ keyname,
+ &pwdata );
+ if( symmetricKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c:\tthe \"%s\" symmetric keyname specified by "
+ "\n\t\t\"-n %s\" does NOT exist on the specified "
+ "token.\n\t\tPlease specify a "
+ "different symmetric keyname.\n\n",
+ progName,
+ commandToRun,
+ keyname,
+ keyname );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*************************************************/
+ /* Compute and display this symmetric key's KCV. */
+ /*************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "\nComputing and displaying KCV of the symmetric key "
+ "on the specified token . . .\n\n" );
+
+ /* Calculate this symmetric key's KCV */
+ rvKCV = TKS_ComputeAndDisplayKCV( ( PRUint8 * ) NULL,
+ ( PRIntn ) 0,
+ ( PRUint8 * ) KCV,
+ ( PRIntn ) KCVLen,
+ symmetricKey,
+ keyname,
+ RESIDENT_KEY,
+ PR_TRUE,
+ NULL );
+ if( rvKCV != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Unable to compute/display KCV of "
+ "this symmetric key!\n\n" );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*********************************/
+ /* Cleanup and exit with success */
+ /*********************************/
+
+ rv = SECSuccess;
+ goto shutdown;
+ }
+
+
+ /**************************************/
+ /* Execute the "-L" list keys command */
+ /* */
+ /* NOTE: This command is mutually */
+ /* exclusive from all others. */
+ /**************************************/
+
+ if( tkstool.commands[cmd_ListKeys].activated ) {
+ rv = TKS_ListKeys( progName,
+ slot,
+ keyname,
+ 0 /*keyindex*/,
+ PR_FALSE /*dopriv*/,
+ &pwdata );
+ goto shutdown;
+ }
+
+
+ /************************************************/
+ /* Execute the "-M" generate master key command */
+ /* */
+ /* NOTE: This command is mutually */
+ /* exclusive from all others. */
+ /************************************************/
+
+ if( tkstool.commands[cmd_GenMasterKey].activated ) {
+
+ /**********************************************************/
+ /* Do not allow duplicate symmetric keys to be generated */
+ /* (i. e. - disallow symmetric keys specified */
+ /* by the same keyname) */
+ /* */
+ /* NOTE: The following code snippet effectively */
+ /* prohibits this tool from generating any */
+ /* symmetric key with a keyname that already */
+ /* resides in the specified token */
+ /**********************************************************/
+
+ rvFindSymKey = TKS_FindSymKey( slot,
+ keyname,
+ &pwdata );
+ if( rvFindSymKey == SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c:\tthe \"%s\" keyname specified by "
+ "\n\t\t\"-n %s\"\n\t\talready exists in the "
+ "specified token.\n\t\tPlease specify a "
+ "different keyname.\n\n",
+ progName,
+ commandToRun,
+ keyname,
+ keyname );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*****************************************************************/
+ /* Generate the master key and store it on the designated token. */
+ /*****************************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "\nGenerating and storing the master key "
+ "on the specified token . . .\n\n" );
+
+ if( MASTER_KEY_LENGTH == ( 2 * DES_LENGTH ) ) {
+ masterKey = PK11_TokenKeyGen(
+ /* slot */ slot,
+ /* mechanism */ CKM_DES2_KEY_GEN,
+ /* param */ 0,
+ /* keySize */ 0,
+ /* keyid */ 0,
+ /* isToken (i. e. - isPerm) */ PR_TRUE,
+ /* wincx */ &pwdata );
+ if( masterKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s:%d\n",
+ progName,
+ commandToRun,
+ "unable to generate/store this DES2 master key ",
+ PR_GetError() );
+ rv = SECFailure;
+ goto shutdown;
+ }
+ } else if( MASTER_KEY_LENGTH == ( 3 * DES_LENGTH ) ) {
+ masterKey = PK11_TokenKeyGen(
+ /* slot */ slot,
+ /* mechanism */ CKM_DES3_KEY_GEN,
+ /* param */ 0,
+ /* keySize */ 0,
+ /* keyid */ 0,
+ /* isToken (i. e. - isPerm) */ PR_TRUE,
+ /* wincx */ &pwdata );
+ if( masterKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s:%d\n",
+ progName,
+ commandToRun,
+ "unable to generate/store this DES3 master key ",
+ PR_GetError() );
+ rv = SECFailure;
+ goto shutdown;
+ }
+ } else {
+ /* invalid key size */
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s\n\n\n",
+ progName,
+ commandToRun,
+ "MASTER_KEY_LENGTH must be DES2 or DES3 length!" );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*****************************************************************/
+ /* Finally, name the master key with the specified name. */
+ /*****************************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Naming the master key \"%s\" . . .\n\n",
+ keyname );
+
+ rvMasterKeyname = PK11_SetSymKeyNickname(
+ /* symmetric key */ masterKey,
+ /* nickname */ keyname );
+ if( rvMasterKeyname != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Failed to name the master key!\n\n" );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*********************************************/
+ /* Compute and display the master key's KCV. */
+ /*********************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Computing and displaying KCV of the master key "
+ "on the specified token . . .\n\n" );
+
+ /* Calculate the master key's KCV */
+ rvKCV = TKS_ComputeAndDisplayKCV( ( PRUint8 * ) NULL,
+ ( PRIntn ) 0,
+ ( PRUint8 * ) KCV,
+ ( PRIntn ) KCVLen,
+ masterKey,
+ keyname,
+ RESIDENT_KEY,
+ PR_TRUE,
+ NULL );
+ if( rvKCV != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Unable to compute/display KCV of "
+ "the master key!\n\n" );
+ rv = SECFailure;
+ goto shutdown;
+ } else {
+ PR_fprintf( PR_STDOUT,
+ "Successfully generated, stored, and named the "
+ "master key\nincluding computing and displaying "
+ "its KCV!\n\n" );
+ }
+
+
+ /*********************************/
+ /* Cleanup and exit with success */
+ /*********************************/
+
+ rv = SECSuccess;
+ goto shutdown;
+ }
+
+
+ /**************************************************************/
+ /* Execute the "-N" new software database creation command */
+ /* */
+ /* NOTE: This command is mutually exclusive from all others. */
+ /* Always initialize the password when creating a new */
+ /* set of software databases */
+ /**************************************************************/
+
+ if( tkstool.commands[cmd_NewDBs].activated ) {
+ rv = SECU_ChangePW( slot,
+ 0,
+ pwdata.data );
+ goto shutdown;
+ }
+
+
+ /****************************************************/
+ /* Execute the "-P" change key DB password command */
+ /* */
+ /* NOTE: This command is mutually exclusive from */
+ /* all others. (future - change pw to slot?) */
+ /****************************************************/
+
+ if( tkstool.commands[cmd_ChangePassword].activated ) {
+ rv = SECU_ChangePW( slot,
+ 0,
+ pwdata.data );
+ goto shutdown;
+ }
+
+
+ /***************************************/
+ /* Execute the "-R" rename key command */
+ /* */
+ /* NOTE: This command is mutually */
+ /* exclusive from all others. */
+ /***************************************/
+
+ if( tkstool.commands[cmd_RenameKey].activated ) {
+
+ /*****************************************************/
+ /* Check that specified keynames are not identical. */
+ /*****************************************************/
+ if( PL_strcmp( keyname, new_keyname ) == 0 ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c:\tthe two keynames specified by "
+ "\n\t\t\"-n %s\" and \"-r %s\" are identical."
+ "\n\t\tPlease provide two non-identical keynames.\n\n",
+ progName,
+ commandToRun,
+ keyname,
+ new_keyname );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+ /*****************************************************/
+ /* Retrieve a handle to the specified symmetric key. */
+ /* This insures that the specified symmetric key */
+ /* already resides on the specified token. */
+ /*****************************************************/
+
+ symmetricKey = TKS_RetrieveSymKey( slot,
+ keyname,
+ &pwdata );
+ if( symmetricKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c:\tthe \"%s\" symmetric keyname specified by "
+ "\n\t\t\"-n %s\" does NOT exist on the specified "
+ "token.\n\t\tPlease specify a "
+ "different symmetric keyname.\n\n",
+ progName,
+ commandToRun,
+ keyname,
+ keyname );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /**********************************************************/
+ /* Do not allow the renamed key to overwrite a */
+ /* preexisting key of the same name */
+ /* */
+ /* NOTE: The following code snippet effectively */
+ /* prohibits this tool from renaming any */
+ /* symmetric key with a keyname that already */
+ /* resides in the specified token */
+ /**********************************************************/
+
+ rvFindSymKey = TKS_FindSymKey( slot,
+ new_keyname,
+ &pwdata );
+ if( rvFindSymKey == SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c:\tthe \"%s\" keyname specified by "
+ "\n\t\t\"-r %s\"\n\t\talready exists in the "
+ "specified token.\n\t\tPlease specify a "
+ "different keyname for renaming purposes.\n\n",
+ progName,
+ commandToRun,
+ new_keyname,
+ new_keyname );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+#if defined(DEBUG)
+ /*****************************************************************/
+ /* For convenience, compute and display the symmetric key's KCV. */
+ /*****************************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Computing and displaying KCV of the symmetric key "
+ "on the specified token . . .\n\n" );
+
+ /* Calculate the symmetric key's KCV */
+ rvKCV = TKS_ComputeAndDisplayKCV( ( PRUint8 * ) NULL,
+ ( PRIntn ) 0,
+ ( PRUint8 * ) KCV,
+ ( PRIntn ) KCVLen,
+ symmetricKey,
+ keyname,
+ RESIDENT_KEY,
+ PR_TRUE,
+ NULL );
+ if( rvKCV != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Unable to compute/display KCV of "
+ "the symmetric key!\n\n" );
+ rv = SECFailure;
+ goto shutdown;
+ }
+#endif
+
+
+ /********************************************************************/
+ /* Finally, rename the symmetric key with the newly specified name. */
+ /********************************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Renaming the symmetric key named \"%s\" to \"%s\" . . .\n\n",
+ keyname,
+ new_keyname );
+
+ rvSymmetricKeyname = PK11_SetSymKeyNickname(
+ /* symmetric key */ symmetricKey,
+ /* nickname */ new_keyname );
+ if( rvSymmetricKeyname != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Failed to rename the symmetric key!\n\n" );
+ rv = SECFailure;
+ goto shutdown;
+ } else {
+ PR_fprintf( PR_STDOUT,
+ "Successfully renamed the symmetric key named \"%s\" "
+ "to \"%s\"!\n\n",
+ keyname,
+ new_keyname );
+ }
+
+
+#if defined(DEBUG)
+ /********************************************************/
+ /* For convenience, compute and display the renamed */
+ /* symmetric key's KCV. */
+ /********************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Computing and displaying KCV of the renamed symmetric key "
+ "on the specified token . . .\n\n" );
+
+ /* Calculate the renamed symmetric key's KCV */
+ rvKCV = TKS_ComputeAndDisplayKCV( ( PRUint8 * ) NULL,
+ ( PRIntn ) 0,
+ ( PRUint8 * ) KCV,
+ ( PRIntn ) KCVLen,
+ symmetricKey,
+ new_keyname,
+ RESIDENT_KEY,
+ PR_TRUE,
+ NULL );
+ if( rvKCV != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Unable to compute/display KCV of "
+ "the renamed symmetric key!\n\n" );
+ rv = SECFailure;
+ goto shutdown;
+ }
+#endif
+
+
+ /*********************************/
+ /* Cleanup and exit with success */
+ /*********************************/
+
+ rv = SECSuccess;
+ goto shutdown;
+ }
+
+
+ /**************************************************/
+ /* Execute the "-S" list security modules command */
+ /* */
+ /* NOTE: This command is mutually */
+ /* exclusive from all others. */
+ /**************************************************/
+
+ if( tkstool.commands[cmd_ListSecModules].activated ) {
+ rv = TKS_ListSecModules();
+ goto shutdown;
+ }
+
+
+ /**********************************************/
+ /* Execute the "-U" unwrap master key command */
+ /* */
+ /* NOTE: This command is mutually */
+ /* exclusive from all others. */
+ /**********************************************/
+
+ if( tkstool.commands[cmd_UnWrapMasterKey].activated ) {
+
+ /**********************************************************/
+ /* Do not allow duplicate symmetric keys to be stored */
+ /* (i. e. - disallow symmetric keys specified */
+ /* by the same keyname) */
+ /* */
+ /* NOTE: The following code snippet effectively */
+ /* prohibits this tool from storing any */
+ /* symmetric key with a keyname that already */
+ /* resides in the specified token */
+ /**********************************************************/
+
+ rvFindSymKey = TKS_FindSymKey( slot,
+ keyname,
+ &pwdata );
+ if( rvFindSymKey == SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c:\tthe \"%s\" keyname specified by "
+ "\n\t\t\"-n %s\"\n\t\talready exists in the "
+ "specified token.\n\t\tPlease specify a "
+ "different keyname.\n\n",
+ progName,
+ commandToRun,
+ keyname,
+ keyname );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*******************************************************************/
+ /* Retrieve a handle to the specified unwrapping key. This insures */
+ /* that the specified unwrapping key (i. e. - transport key) */
+ /* already exists on the specified token. */
+ /* */
+ /* NOTE: Requiring that the transport key AND the master key */
+ /* reside on the same token is a FIPS 140-1 requirement! */
+ /*******************************************************************/
+
+ TKS_ClearScreen();
+
+ PR_fprintf( PR_STDOUT,
+ "\nRetrieving the transport key from the "
+ "specified token (for unwrapping) . . .\n\n" );
+
+ transportKey = TKS_RetrieveSymKey( slot,
+ transport_keyname,
+ &pwdata );
+ if( transportKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c:\tthe \"%s\" transport keyname specified by "
+ "\"-t %s\"\n\t\tdoes NOT exist on the specified "
+ "token.\n\t\tPlease specify a "
+ "different transport keyname.\n\n",
+ progName,
+ commandToRun,
+ transport_keyname,
+ transport_keyname );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*****************************************************************/
+ /* Read in the wrapped master key from the specified input file. */
+ /*****************************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Reading in the wrapped data (and resident master key KCV) "
+ "from the file called\n\"%s\" . . .\n\n",
+ input );
+
+ /* Create a clean new storage buffer for this wrapped key */
+ wrappedMasterKey.len = WRAPPED_KEY_LENGTH;
+ wrappedMasterKey.data = ( unsigned char * )
+ PORT_ZAlloc( WRAPPED_KEY_LENGTH );
+
+ /* Create a clean new hex storage buffer for this master key's KCV */
+ hexInternalKeyKCV.type = ( SECItemType ) siBuffer;
+ hexInternalKeyKCV.len = ( HEX_WRAPPED_KEY_KCV_LENGTH + 1 );
+ hexInternalKeyKCV.data = ( unsigned char * )
+ PORT_ZAlloc( hexInternalKeyKCV.len );
+ if( hexInternalKeyKCV.data == NULL ) {
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+ rvWrappedMasterKey = TKS_ReadInputFileIntoSECItem( input,
+ ( char * ) hexInternalKeyKCV.data,
+ hexInternalKeyKCV.len,
+ keyname,
+ &wrappedMasterKey );
+ if( rvWrappedMasterKey != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c:\tunable to read in wrapped master key "
+ "from file called \"%s\".\n",
+ progName,
+ commandToRun,
+ input );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*************************************************************/
+ /* Temporarily unwrap the master key to check its KCV value. */
+ /*************************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Using the transport key to temporarily unwrap "
+ "the master key to recompute\nits KCV value to "
+ "check against its pre-computed KCV value . . .\n\n" );
+
+ temporaryMasterKey = PK11_UnwrapSymKeyWithFlagsPerm(
+ /* wrapping key */ transportKey,
+ /* wraptype */ CKM_DES3_ECB,
+ /* param */ 0,
+ /* wrapped key */ &wrappedMasterKey,
+ /* target */ CKM_DES3_ECB,
+ /* operation */ CKA_ENCRYPT,
+ /* target key length */ WRAPPED_KEY_LENGTH,
+ /* flags */ 0,
+ /* isPerm */ PR_FALSE );
+ if( temporaryMasterKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s:%d\n",
+ progName,
+ commandToRun,
+ "unable to temporarily unwrap the master key ",
+ PR_GetError() );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+ /* verify that the wrapped key and KCV read in from */
+ /* the input file correspond to each other . . . */
+ rvKCV = TKS_ComputeAndDisplayKCV( ( PRUint8 * ) NULL,
+ ( PRIntn ) 0,
+ ( PRUint8 * ) KCV,
+ ( PRIntn ) KCVLen,
+ temporaryMasterKey,
+ keyname,
+ UNWRAPPED_KEY,
+ PR_FALSE,
+ hexInternalKeyKCV.data );
+ if( rvKCV != SECSuccess ) {
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /***************************************************************/
+ /* Unwrap the master key and store it on the designated token. */
+ /***************************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Using the transport key to unwrap and store "
+ "the master key\non the specified token . . .\n\n" );
+
+ masterKey = PK11_UnwrapSymKeyWithFlagsPerm(
+ /* wrapping key */ transportKey,
+ /* wraptype */ CKM_DES3_ECB,
+ /* param */ 0,
+ /* wrapped key */ &wrappedMasterKey,
+ /* target */ CKM_DES3_ECB,
+ /* operation */ CKA_ENCRYPT,
+ /* target key length */ WRAPPED_KEY_LENGTH,
+ /* flags */ 0,
+ /* isPerm */ PR_TRUE );
+ if( masterKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s:%d\n",
+ progName,
+ commandToRun,
+ "unable to unwrap/store the master key ",
+ PR_GetError() );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*****************************************************************/
+ /* Finally, name the master key with the specified name. */
+ /*****************************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Naming the master key \"%s\" . . .\n\n",
+ keyname );
+
+ rvMasterKeyname = PK11_SetSymKeyNickname(
+ /* symmetric key */ masterKey,
+ /* nickname */ keyname );
+ if( rvMasterKeyname != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Failed to name the master key!\n\n" );
+ rv = SECFailure;
+ goto shutdown;
+ } else {
+ PR_fprintf( PR_STDOUT,
+ "Successfully unwrapped, stored, and named the "
+ "master key!\n\n" );
+ }
+
+
+ /*********************************/
+ /* Cleanup and exit with success */
+ /*********************************/
+
+ rv = SECSuccess;
+ goto shutdown;
+ }
+
+
+ /******************************************************/
+ /* Execute the "-W" wrap generated master key command */
+ /* */
+ /* NOTE: This command is mutually */
+ /* exclusive from all others. */
+ /******************************************************/
+
+ if( tkstool.commands[cmd_WrapMasterKey].activated ) {
+
+ /**********************************************************/
+ /* Do not allow duplicate symmetric keys to be stored */
+ /* (i. e. - disallow symmetric keys specified */
+ /* by the same keyname) */
+ /* */
+ /* NOTE: The following code snippet effectively */
+ /* prohibits this tool from storing any */
+ /* symmetric key with a keyname that already */
+ /* resides in the specified token */
+ /**********************************************************/
+
+ rvFindSymKey = TKS_FindSymKey( slot,
+ keyname,
+ &pwdata );
+ if( rvFindSymKey == SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c:\tthe \"%s\" keyname specified by "
+ "\n\t\t\"-n %s\"\n\t\talready exists in the "
+ "specified token.\n\t\tPlease specify a "
+ "different keyname.\n\n",
+ progName,
+ commandToRun,
+ keyname,
+ keyname );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*****************************************************************/
+ /* Retrieve a handle to the specified wrapping key. This insures */
+ /* that the specified wrapping key (i. e. - transport key) */
+ /* already exists on the specified token. */
+ /* */
+ /* NOTE: Requiring that the transport key AND the master key */
+ /* reside on the same token is a FIPS 140-1 requirement! */
+ /*****************************************************************/
+
+ TKS_ClearScreen();
+
+ PR_fprintf( PR_STDOUT,
+ "\nRetrieving the transport key (for wrapping) "
+ "from the specified token . . .\n\n" );
+
+ transportKey = TKS_RetrieveSymKey( slot,
+ transport_keyname,
+ &pwdata );
+ if( transportKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c:\tthe \"%s\" transport keyname specified by "
+ "\"-t %s\"\n\t\tdoes NOT exist on the specified "
+ "token.\n\t\tPlease specify a "
+ "different transport keyname.\n\n",
+ progName,
+ commandToRun,
+ transport_keyname,
+ transport_keyname );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*****************************************************************/
+ /* Generate the master key and store it on the designated token. */
+ /*****************************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Generating and storing the master key "
+ "on the specified token . . .\n\n" );
+
+ if( WRAPPED_KEY_LENGTH == ( 2 * DES_LENGTH ) ) {
+ masterKey = PK11_TokenKeyGen(
+ /* slot */ slot,
+ /* mechanism */ CKM_DES2_KEY_GEN,
+ /* param */ 0,
+ /* keySize */ 0,
+ /* keyid */ 0,
+ /* isToken (i. e. - isPerm) */ PR_TRUE,
+ /* wincx */ &pwdata );
+ if( masterKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s:%d\n",
+ progName,
+ commandToRun,
+ "unable to generate/store this DES2 master key ",
+ PR_GetError() );
+ rv = SECFailure;
+ goto shutdown;
+ }
+ } else if( WRAPPED_KEY_LENGTH == ( 3 * DES_LENGTH ) ) {
+ masterKey = PK11_TokenKeyGen(
+ /* slot */ slot,
+ /* mechanism */ CKM_DES3_KEY_GEN,
+ /* param */ 0,
+ /* keySize */ 0,
+ /* keyid */ 0,
+ /* isToken (i. e. - isPerm) */ PR_TRUE,
+ /* wincx */ &pwdata );
+ if( masterKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s:%d\n",
+ progName,
+ commandToRun,
+ "unable to generate/store this DES3 master key ",
+ PR_GetError() );
+ rv = SECFailure;
+ goto shutdown;
+ }
+ } else {
+ /* invalid key size */
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s\n\n\n",
+ progName,
+ commandToRun,
+ "WRAPPED_KEY_LENGTH must be DES2 or DES3 length!" );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /************************************************/
+ /* Name the master key with the specified name. */
+ /************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Naming the master key \"%s\" . . .\n\n",
+ keyname );
+
+ rvMasterKeyname = PK11_SetSymKeyNickname(
+ /* symmetric key */ masterKey,
+ /* nickname */ keyname );
+ if( rvMasterKeyname != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Failed to name the master key!\n\n" );
+ rv = SECFailure;
+ goto shutdown;
+ } else {
+ PR_fprintf( PR_STDOUT,
+ "Successfully generated, stored, and named the "
+ "master key!\n\n" );
+ }
+
+
+ /**********************************/
+ /* Compute this master key's KCV. */
+ /**********************************/
+
+ /* Create a clean new hex storage buffer for this master key's KCV */
+ hexInternalKeyKCV.type = ( SECItemType ) siBuffer;
+ hexInternalKeyKCV.len = ( HEX_WRAPPED_KEY_KCV_LENGTH + 1 );
+ hexInternalKeyKCV.data = ( unsigned char * )
+ PORT_ZAlloc( hexInternalKeyKCV.len );
+ if( hexInternalKeyKCV.data == NULL ) {
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+ /* Calculate this master key's KCV */
+ rvKCV = TKS_ComputeAndDisplayKCV( ( PRUint8 * ) NULL,
+ ( PRIntn ) 0,
+ ( PRUint8 * ) KCV,
+ ( PRIntn ) KCVLen,
+ masterKey,
+ keyname,
+ WRAPPED_KEY,
+ PR_FALSE,
+ hexInternalKeyKCV.data );
+ if( rvKCV != SECSuccess ) {
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /****************************************/
+ /* Wrap the newly generated master key. */
+ /****************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Using the transport key to wrap and store "
+ "the master key . . .\n\n" );
+
+ wrappedMasterKey.len = WRAPPED_KEY_LENGTH;
+ wrappedMasterKey.data = ( unsigned char * )
+ PORT_ZAlloc( WRAPPED_KEY_LENGTH );
+
+ rvWrappedMasterKey = PK11_WrapSymKey(
+ /* mechanism type */ CKM_DES3_ECB,
+ /* param */ 0,
+ /* wrapping key */ transportKey,
+ /* key to be wrapped */ masterKey,
+ /* wrapped key */ &wrappedMasterKey );
+ if( rvWrappedMasterKey != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s:%d\n",
+ progName,
+ commandToRun,
+ "unable to wrap the master key ",
+ PR_GetError() );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /**************************************************************/
+ /* Write the wrapped master key to the specified output file. */
+ /**************************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Writing the wrapped data (and resident master key KCV) "
+ "into the file called\n\"%s\" . . .\n\n",
+ output );
+
+ rvSaveWrappedMasterKey = TKS_WriteSECItemIntoOutputFile( &wrappedMasterKey,
+ keyname,
+ ( char * ) hexInternalKeyKCV.data,
+ ( hexInternalKeyKCV.len - 1 ),
+ output );
+ if( rvSaveWrappedMasterKey != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s:%d\n",
+ progName,
+ commandToRun,
+ "unable to save the wrapped master key ",
+ PR_GetError() );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*********************************/
+ /* Cleanup and exit with success */
+ /*********************************/
+
+ rv = SECSuccess;
+ goto shutdown;
+ }
+
+
+shutdown:
+ /* free internal slot */
+ if( slot ) {
+ PK11_FreeSlot( /* slot */ internalSlot );
+ }
+
+
+ /* free slot */
+ if( slot ) {
+ PK11_FreeSlot( /* slot */ slot );
+ }
+
+
+ /* destroy the pwdata */
+ if( pwdata.data != NULL ) {
+ pwdata.source = PW_NONE;
+ i = 0;
+ do {
+ if( pwdata.data[i] != 0 ) {
+ pwdata.data[i] = 0;
+ i++;
+ } else {
+ status = PR_TRUE;
+ }
+ } while( status == PR_FALSE );
+ }
+
+
+ /* destroy the first session key share */
+ if( firstSessionKeyShare.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ firstSessionKeyShare.data,
+ firstSessionKeyShare.len );
+ firstSessionKeyShare.data = NULL;
+ firstSessionKeyShare.len = 0;
+ }
+
+
+#if defined(PAD_DES2_KEY_LENGTH)
+ /* destroy the first padded session key share */
+ if( paddedFirstSessionKeyShare.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ paddedFirstSessionKeyShare.data,
+ paddedFirstSessionKeyShare.len );
+ paddedFirstSessionKeyShare.data = NULL;
+ paddedFirstSessionKeyShare.len = 0;
+ }
+#endif
+
+
+ /* destroy the "original" second session key share */
+ if( secondDerivationData.pData != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ secondDerivationData.pData,
+ secondDerivationData.ulLen );
+ secondDerivationData.pData = NULL;
+ secondDerivationData.ulLen = 0;
+ }
+
+
+#if defined(PAD_DES2_KEY_LENGTH)
+ /* destroy the second padded session key share */
+ if( paddedSecondSessionKeyShare.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ paddedSecondSessionKeyShare.data,
+ paddedSecondSessionKeyShare.len );
+ paddedSecondSessionKeyShare.data = NULL;
+ paddedSecondSessionKeyShare.len = 0;
+ }
+#endif
+
+
+ /* destroy the second session key share container */
+ if( secondSessionKeyShare.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ secondSessionKeyShare.data,
+ secondSessionKeyShare.len );
+ secondSessionKeyShare.data = NULL;
+ secondSessionKeyShare.len = 0;
+ }
+
+
+ /* destroy the "original" third session key share */
+ if( thirdDerivationData.pData != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ thirdDerivationData.pData,
+ thirdDerivationData.ulLen );
+ thirdDerivationData.pData = NULL;
+ thirdDerivationData.ulLen = 0;
+ }
+
+
+#if defined(PAD_DES2_KEY_LENGTH)
+ /* destroy the third padded session key share */
+ if( paddedThirdSessionKeyShare.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ paddedThirdSessionKeyShare.data,
+ paddedThirdSessionKeyShare.len );
+ paddedThirdSessionKeyShare.data = NULL;
+ paddedThirdSessionKeyShare.len = 0;
+ }
+#endif
+
+
+ /* destroy the third session key share container */
+ if( thirdSessionKeyShare.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ thirdSessionKeyShare.data,
+ thirdSessionKeyShare.len );
+ thirdSessionKeyShare.data = NULL;
+ thirdSessionKeyShare.len = 0;
+ }
+
+
+ /* destroy the first symmetric key */
+ if( firstSymmetricKey ) {
+ PK11_FreeSymKey( /* symmetric key */ firstSymmetricKey );
+ }
+
+
+ /* destroy the second symmetric key */
+ if( secondSymmetricKey ) {
+ PK11_FreeSymKey( /* symmetric key */ secondSymmetricKey );
+ }
+
+
+ /* destroy the third symmetric key (transport key) */
+ if( thirdSymmetricKey ) {
+ PK11_FreeSymKey( /* symmetric key */ thirdSymmetricKey );
+ }
+
+
+ /* destroy the hexInternalKeyKCV */
+ if( hexInternalKeyKCV.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ hexInternalKeyKCV.data,
+ hexInternalKeyKCV.len );
+ hexInternalKeyKCV.data = NULL;
+ hexInternalKeyKCV.len = 0;
+ }
+
+
+ /* destroy the KCV */
+ if( KCV != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ KCV,
+ KCVLen );
+ KCV = NULL;
+ KCVLen = 0;
+ }
+
+
+ /* destroy the temporary master key */
+ if( temporaryMasterKey ) {
+ PK11_FreeSymKey( /* symmetric key */ temporaryMasterKey );
+ }
+
+
+ /* destroy the master key */
+ if( masterKey ) {
+ PK11_FreeSymKey( /* symmetric key */ masterKey );
+ }
+
+
+ /* destroy the transport key */
+ if( transportKey ) {
+ PK11_FreeSymKey( /* symmetric key */ transportKey );
+ }
+
+
+ /* shutdown NSS */
+ if( NSS_Shutdown() != SECSuccess ) {
+ return 255;
+ }
+
+
+ /* exit with an appropriate return value */
+ if( rv == SECSuccess ) {
+ return 0;
+ } else {
+ return 255;
+ }
+}
+