/* --- 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 */ /* 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; } }