data_init.c revision 1.1.1.1
1/* 2 * The Initial Developer of the Original Code is International 3 * Business Machines Corporation. Portions created by IBM 4 * Corporation are Copyright (C) 2005 International Business 5 * Machines Corporation. All Rights Reserved. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the Common Public License as published by 9 * IBM Corporation; either version 1 of the License, or (at your option) 10 * any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * Common Public License for more details. 16 * 17 * You should have received a copy of the Common Public License 18 * along with this program; if not, a copy can be viewed at 19 * http://www.opensource.org/licenses/cpl1.0.php. 20 */ 21 22#include "data_init.h" 23#include "data_common.h" 24 25#include <tpm_pkcs11.h> 26#include <tpm_utils.h> 27 28#include <stdlib.h> 29#include <unistd.h> 30#define _GNU_SOURCE 31#include <getopt.h> 32 33 34BOOL g_bYes = FALSE; // Yes/No prompt reply 35char *g_pszToken = NULL; // Token label to be used 36 37/* 38 * parseCallback 39 * Process the command specific options. 40 */ 41int 42parseCallback( int a_iOpt, 43 const char *a_pszOptArg ) { 44 45 switch ( a_iOpt ) { 46 // Use the specified token label when finding the token 47 case 'k': 48 if ( !a_pszOptArg ) 49 return -1; 50 51 g_pszToken = strdup( a_pszOptArg ); 52 break; 53 54 case 'y': 55 g_bYes = TRUE; 56 break; 57 } 58 59 return 0; 60} 61 62/* 63 * usageCallback 64 * Display command usage information. 65 */ 66void 67usageCallback( const char *a_pszCmd ) { 68 69 logCmdHelp( a_pszCmd ); 70 logCmdOption( "-k, --token STRING", 71 _("Use STRING to identify the label of the PKCS#11 token to be used") ); 72 logCmdOption( "-y, --yes", 73 _("Reply 'yes' to the clear TPM token prompt") ); 74} 75 76/* 77 * parseCmd 78 * Parse the command line options. 79 */ 80int 81parseCmd( int a_iArgc, 82 char **a_pszArgv ) { 83 84 char *pszShortOpts = "k:y"; 85 struct option stLongOpts[] = { 86 { "token", required_argument, NULL, 'k' }, 87 { "yes", no_argument, NULL, 'y' }, 88 }; 89 int iNumLongOpts = sizeof( stLongOpts ) / sizeof( struct option ); 90 91 return genericOptHandler( a_iArgc, a_pszArgv, 92 pszShortOpts, stLongOpts, iNumLongOpts, 93 parseCallback, usageCallback ); 94} 95 96int 97main( int a_iArgc, 98 char **a_pszArgv ) { 99 100 int rc = 1; 101 102 // Create buffers for PIN prompts for formatting using sprintf 103 char szSoNewPinPrompt[ strlen( TOKEN_SO_NEW_PIN_PROMPT ) + 16 ]; 104 char szUserNewPinPrompt[ strlen( TOKEN_USER_NEW_PIN_PROMPT ) + 16 ]; 105 106 char *pszReply = NULL; 107 char *pszSoPin = NULL; 108 char *pszNewSoPin = NULL; 109 char *pszNewUserPin = NULL; 110 111 CK_RV rv = CKR_OK; 112 CK_SESSION_HANDLE hSession = 0; 113 114 // Set up i18n 115 initIntlSys( ); 116 117 // Parse the command 118 if ( parseCmd( a_iArgc, a_pszArgv ) == -1 ) 119 goto out; 120 121 // Open the PKCS#11 TPM Token 122 rv = openToken( g_pszToken ); 123 if ( rv != CKR_OK ) 124 goto out; 125 126 // Check if the token is already initialized 127 if ( isTokenInitialized( ) ) { 128 // Warn and ask the user before clearing 129 if ( !g_bYes ) { 130 pszReply = getReply( TOKEN_CLEAR_PROMPT, 1 ); 131 if ( !pszReply || 132 ( strlen( pszReply ) == 0 ) || 133 ( strcasecmp( pszReply, TOKEN_CLEAR_NO ) == 0 ) ) { 134 goto out; 135 } 136 } 137 138 // Prompt for the current SO password 139 pszSoPin = getPlainPasswd( TOKEN_SO_PIN_PROMPT, FALSE ); 140 if ( !pszSoPin ) 141 goto out; 142 } 143 else 144 pszSoPin = strdup( TOKEN_SO_INIT_PIN ); 145 146 // Clear the TPM token 147 rv = initToken( pszSoPin ); 148 if ( rv != CKR_OK ) 149 goto out; 150 151 // Open a session 152 rv = openTokenSession( CKF_RW_SESSION, &hSession ); 153 if ( rv != CKR_OK ) 154 goto out; 155 156 // Login to the token 157 rv = loginToken( hSession, CKU_SO, TOKEN_SO_INIT_PIN ); 158 if ( rv != CKR_OK ) 159 goto out; 160 161 sprintf( szSoNewPinPrompt, TOKEN_SO_NEW_PIN_PROMPT, getMinPinLen( ), getMaxPinLen( ) ); 162 while ( TRUE ) { 163 // Prompt for a new SO password 164 pszNewSoPin = getPlainPasswd( szSoNewPinPrompt, TRUE ); 165 if ( !pszNewSoPin ) 166 goto out; 167 168 // Set the new password 169 rv = setPin( hSession, TOKEN_SO_INIT_PIN, pszNewSoPin ); 170 if ( rv == CKR_OK ) 171 break; 172 173 if ( ( rv == CKR_PIN_INVALID ) || ( rv == CKR_PIN_LEN_RANGE ) ) 174 logError( TOKEN_INVALID_PIN ); 175 else 176 goto out; 177 178 shredPasswd( pszNewSoPin ); 179 } 180 181 // Open a new session 182 closeTokenSession( hSession ); 183 hSession = 0; 184 rv = openTokenSession( CKF_RW_SESSION, &hSession ); 185 if ( rv != CKR_OK ) 186 goto out; 187 188 // Login to the token 189 rv = loginToken( hSession, CKU_USER, TOKEN_USER_INIT_PIN ); 190 if ( rv != CKR_OK ) 191 goto out; 192 193 sprintf( szUserNewPinPrompt, TOKEN_USER_NEW_PIN_PROMPT, getMinPinLen( ), getMaxPinLen( ) ); 194 while ( TRUE ) { 195 // Prompt for a new User password 196 pszNewUserPin = getPlainPasswd( szUserNewPinPrompt, TRUE ); 197 if ( !pszNewUserPin ) 198 goto out; 199 200 // Set the new password 201 rv = setPin( hSession, TOKEN_USER_INIT_PIN, pszNewUserPin ); 202 if ( rv == CKR_OK ) 203 break; 204 205 if ( ( rv == CKR_PIN_INVALID ) || ( rv == CKR_PIN_LEN_RANGE ) ) 206 logError( TOKEN_INVALID_PIN ); 207 else 208 goto out; 209 210 shredPasswd( pszNewUserPin ); 211 } 212 213 rc = 0; 214 215out: 216 free( pszReply ); 217 shredPasswd( pszSoPin ); 218 shredPasswd( pszNewSoPin ); 219 shredPasswd( pszNewUserPin ); 220 221 if ( hSession ) 222 closeTokenSession( hSession ); 223 224 closeToken( ); 225 226 if ( rc == 0 ) 227 logInfo( TOKEN_CMD_SUCCESS, a_pszArgv[ 0 ] ); 228 else 229 logInfo( TOKEN_CMD_FAILED, a_pszArgv[ 0 ] ); 230 231 return rc; 232} 233