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  */
37 int   g_bPublic   = FALSE;		// Public object specifier
38 int   g_bExtended = FALSE;		// Extended information display specifier
39 char *g_pszToken  = NULL;		// Token label to be used
40 
41 /*
42  * parseCallback
43  *   Process the command specific options.
44  */
45 int
parseCallback(int a_iOpt,const char * a_pszOptArg)46 parseCallback( 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  */
74 void
usageCallback(const char * a_pszCmd)75 usageCallback( 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  */
90 int
parseCmd(int a_iArgc,char ** a_pszArgv)91 parseCmd( 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 
108 int
main(int a_iArgc,char ** a_pszArgv)109 main( 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 
175 out:
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