/* * The Initial Developer of the Original Code is International * Business Machines Corporation. Portions created by IBM * Corporation are Copyright (C) 2005 International Business * Machines Corporation. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Common Public License as published by * IBM Corporation; either version 1 of the License, or (at your option) * any later version. * * 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 * Common Public License for more details. * * You should have received a copy of the Common Public License * along with this program; if not, a copy can be viewed at * http://www.opensource.org/licenses/cpl1.0.php. */ #include "data_init.h" #include "data_common.h" #include #include #include #include #define _GNU_SOURCE #include BOOL g_bYes = FALSE; // Yes/No prompt reply char *g_pszToken = NULL; // Token label to be used /* * parseCallback * Process the command specific options. */ int parseCallback( int a_iOpt, const char *a_pszOptArg ) { switch ( a_iOpt ) { // Use the specified token label when finding the token case 'k': if ( !a_pszOptArg ) return -1; g_pszToken = strdup( a_pszOptArg ); break; case 'y': g_bYes = TRUE; break; } return 0; } /* * usageCallback * Display command usage information. */ void usageCallback( const char *a_pszCmd ) { logCmdHelp( a_pszCmd ); logCmdOption( "-k, --token STRING", _("Use STRING to identify the label of the PKCS#11 token to be used") ); logCmdOption( "-y, --yes", _("Reply 'yes' to the clear TPM token prompt") ); } /* * parseCmd * Parse the command line options. */ int parseCmd( int a_iArgc, char **a_pszArgv ) { char *pszShortOpts = "k:y"; struct option stLongOpts[] = { { "token", required_argument, NULL, 'k' }, { "yes", no_argument, NULL, 'y' }, }; int iNumLongOpts = sizeof( stLongOpts ) / sizeof( struct option ); return genericOptHandler( a_iArgc, a_pszArgv, pszShortOpts, stLongOpts, iNumLongOpts, parseCallback, usageCallback ); } int main( int a_iArgc, char **a_pszArgv ) { int rc = 1; // Create buffers for PIN prompts for formatting using sprintf char szSoNewPinPrompt[ strlen( TOKEN_SO_NEW_PIN_PROMPT ) + 16 ]; char szUserNewPinPrompt[ strlen( TOKEN_USER_NEW_PIN_PROMPT ) + 16 ]; char *pszReply = NULL; char *pszSoPin = NULL; char *pszNewSoPin = NULL; char *pszNewUserPin = NULL; CK_RV rv = CKR_OK; CK_SESSION_HANDLE hSession = 0; // Set up i18n initIntlSys( ); // Parse the command if ( parseCmd( a_iArgc, a_pszArgv ) == -1 ) goto out; // Open the PKCS#11 TPM Token rv = openToken( g_pszToken ); if ( rv != CKR_OK ) goto out; // Check if the token is already initialized if ( isTokenInitialized( ) ) { // Warn and ask the user before clearing if ( !g_bYes ) { pszReply = getReply( TOKEN_CLEAR_PROMPT, 1 ); if ( !pszReply || ( strlen( pszReply ) == 0 ) || ( strcasecmp( pszReply, TOKEN_CLEAR_NO ) == 0 ) ) { goto out; } } // Prompt for the current SO password pszSoPin = getPlainPasswd( TOKEN_SO_PIN_PROMPT, FALSE ); if ( !pszSoPin ) goto out; } else pszSoPin = strdup( TOKEN_SO_INIT_PIN ); // Clear the TPM token rv = initToken( pszSoPin ); if ( rv != CKR_OK ) goto out; // Open a session rv = openTokenSession( CKF_RW_SESSION, &hSession ); if ( rv != CKR_OK ) goto out; // Login to the token rv = loginToken( hSession, CKU_SO, TOKEN_SO_INIT_PIN ); if ( rv != CKR_OK ) goto out; sprintf( szSoNewPinPrompt, TOKEN_SO_NEW_PIN_PROMPT, getMinPinLen( ), getMaxPinLen( ) ); while ( TRUE ) { // Prompt for a new SO password pszNewSoPin = getPlainPasswd( szSoNewPinPrompt, TRUE ); if ( !pszNewSoPin ) goto out; // Set the new password rv = setPin( hSession, TOKEN_SO_INIT_PIN, pszNewSoPin ); if ( rv == CKR_OK ) break; if ( ( rv == CKR_PIN_INVALID ) || ( rv == CKR_PIN_LEN_RANGE ) ) logError( TOKEN_INVALID_PIN ); else goto out; shredPasswd( pszNewSoPin ); } // Open a new session closeTokenSession( hSession ); hSession = 0; rv = openTokenSession( CKF_RW_SESSION, &hSession ); if ( rv != CKR_OK ) goto out; // Login to the token rv = loginToken( hSession, CKU_USER, TOKEN_USER_INIT_PIN ); if ( rv != CKR_OK ) goto out; sprintf( szUserNewPinPrompt, TOKEN_USER_NEW_PIN_PROMPT, getMinPinLen( ), getMaxPinLen( ) ); while ( TRUE ) { // Prompt for a new User password pszNewUserPin = getPlainPasswd( szUserNewPinPrompt, TRUE ); if ( !pszNewUserPin ) goto out; // Set the new password rv = setPin( hSession, TOKEN_USER_INIT_PIN, pszNewUserPin ); if ( rv == CKR_OK ) break; if ( ( rv == CKR_PIN_INVALID ) || ( rv == CKR_PIN_LEN_RANGE ) ) logError( TOKEN_INVALID_PIN ); else goto out; shredPasswd( pszNewUserPin ); } rc = 0; out: free( pszReply ); shredPasswd( pszSoPin ); shredPasswd( pszNewSoPin ); shredPasswd( pszNewUserPin ); if ( hSession ) closeTokenSession( hSession ); closeToken( ); if ( rc == 0 ) logInfo( TOKEN_CMD_SUCCESS, a_pszArgv[ 0 ] ); else logInfo( TOKEN_CMD_FAILED, a_pszArgv[ 0 ] ); return rc; }