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_object.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
34/*
35 * Global variables
36 */
37int   g_bPublic   = FALSE;		// Public object specifier
38int   g_bExtended = FALSE;		// Extended information display specifier
39char *g_pszToken  = NULL;		// Token label to be used
40
41/*
42 * parseCallback
43 *   Process the command specific options.
44 */
45int
46parseCallback( int         a_iOpt,
47               const char *a_pszOptArg ) {
48
49	switch ( a_iOpt ) {
50		// Use the specified token label when finding the token
51		case 'k':
52			if ( !a_pszOptArg )
53				return -1;
54
55			g_pszToken = strdup( a_pszOptArg );
56			break;
57
58		case 'p':
59			g_bPublic = TRUE;
60			break;
61
62		case 'x':
63			g_bExtended = TRUE;
64			break;
65	}
66
67	return 0;
68}
69
70/*
71 * usageCallback
72 *   Display command usage information.
73 */
74void
75usageCallback( const char *a_pszCmd ) {
76
77	logCmdHelp( a_pszCmd );
78	logCmdOption( "-k, --token STRING",
79			_("Use STRING to identify the label of the PKCS#11 token to be used") );
80	logCmdOption( "-p, --public",
81			_("Display only public objects") );
82	logCmdOption( "-x, --extended",
83			_("Display additional information about the objects") );
84}
85
86/*
87 * parseCmd
88 *   Parse the command line options.
89 */
90int
91parseCmd( int    a_iArgc,
92          char **a_pszArgv ) {
93
94	char          *pszShortOpts = "k:px";
95	struct option  stLongOpts[] = {
96					{ "token", required_argument, NULL, 'k' },
97					{ "public", no_argument, NULL, 'p' },
98					{ "extended", no_argument, NULL, 'x' },
99				};
100
101	int  iNumLongOpts = sizeof( stLongOpts ) / sizeof( struct option );
102
103	return genericOptHandler( a_iArgc, a_pszArgv,
104					pszShortOpts, stLongOpts, iNumLongOpts,
105					parseCallback, usageCallback );
106}
107
108int
109main( int    a_iArgc,
110      char **a_pszArgv ) {
111
112	int  rc = 1;
113
114	char *pszPin    = NULL;
115
116	CK_RV              rv        = CKR_OK;
117	CK_SESSION_HANDLE  hSession  = 0;
118	CK_OBJECT_HANDLE  *hObject;
119	CK_ULONG           ulCount;
120
121	// Set up i18n
122	initIntlSys( );
123
124	// Parse the command
125	if ( parseCmd( a_iArgc, a_pszArgv ) == -1 )
126		goto out;
127
128	// Open the PKCS#11 TPM Token
129	rv = openToken( g_pszToken );
130	if ( rv != CKR_OK )
131		goto out;
132
133	// Make sure the token is initialized
134	if ( !isTokenInitialized( ) ) {
135		logMsg( TOKEN_NOT_INIT_ERROR );
136		goto out;
137	}
138
139	// Open a session
140	rv = openTokenSession( CKF_RW_SESSION, &hSession );
141	if ( rv != CKR_OK )
142		goto out;
143
144	// Check the scope of the request, which will determine the login
145	// requirements:
146	//   Public  = no password, no login
147	//   Private = user password, user login
148	if ( !g_bPublic ) {
149		pszPin = getPlainPasswd( TOKEN_USER_PIN_PROMPT, FALSE );
150		if ( !pszPin )
151			goto out;
152
153		// Login to the token
154		rv = loginToken( hSession, CKU_USER, pszPin );
155		if ( rv != CKR_OK )
156			goto out;
157	}
158
159	rv = findObjects( hSession, NULL, 0, &hObject, &ulCount );
160	if ( rv != CKR_OK )
161		goto out;
162
163	if ( ulCount > 0 ) {
164		while ( ulCount > 0 )
165			displayObject( hSession, hObject[ --ulCount ], g_bExtended );
166	}
167	else {
168		logMsg( NO_TOKEN_OBJECTS );
169	}
170
171	free( hObject );
172
173	rc = 0;
174
175out:
176	shredPasswd( pszPin );
177
178	if ( hSession )
179		closeTokenSession( hSession );
180
181	closeToken( );
182
183	if ( rc == 0 )
184		logInfo( TOKEN_CMD_SUCCESS, a_pszArgv[ 0 ] );
185	else
186		logInfo( TOKEN_CMD_FAILED, a_pszArgv[ 0 ] );
187
188	return rc;
189}
190