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_import.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 #include <errno.h>
33 
34 #include <openssl/rsa.h>
35 #include <openssl/x509.h>
36 #include <openssl/x509v3.h>
37 #include <openssl/pem.h>
38 #include <openssl/asn1.h>
39 #include <openssl/evp.h>
40 #include <openssl/err.h>
41 
42 #if OPENSSL_VERSION_NUMBER < 0x1010000fL || defined(LIBRESSL_VERSION_NUMBER)
43 #define	RSA_get0_n(x)	((x)->n)
44 #define	RSA_get0_e(x)	((x)->e)
45 #define	RSA_get0_d(x)	((x)->d)
46 #define	RSA_get0_p(x)	((x)->p)
47 #define	RSA_get0_q(x)	((x)->q)
48 #define	RSA_get0_dmp1(x)	((x)->dmp1)
49 #define	RSA_get0_dmq1(x)	((x)->dmq1)
50 #define	RSA_get0_iqmp(x)	((x)->iqmp)
51 #endif
52 
53 /*
54  * Global variables
55  */
56 char *g_pszFile   = NULL;		// Object import file name
57 char *g_pszIdFile = NULL;		// Object identification file name
58 char *g_pszType   = NULL;		// Object import type
59 int   g_bPublic   = FALSE;		// Public object specifier
60 int   g_bYes      = FALSE;		// Yes/No prompt reply
61 char *g_pszToken  = NULL;		// Token label to be used
62 
63 int       g_bAttrsValid  = FALSE;
64 CK_BYTE  *g_pchSubject   = NULL;	// SUBJECT attribute value
65 CK_LONG   g_subjectLen = 0;
66 CK_BYTE  *g_pchId        = NULL;	// ID attribute value
67 CK_ULONG  g_ulIdLen      = 0;
68 CK_BYTE  *g_pchName      = NULL;	// LABEL attribute value
69 CK_ULONG  g_ulNameLen    = 0;
70 
71 /*
72  * parseCallback
73  *   Process the command specific options.
74  */
75 int
parseCallback(int a_iOpt,const char * a_pszOptArg)76 parseCallback( int         a_iOpt,
77                const char *a_pszOptArg ) {
78 
79 	switch ( a_iOpt ) {
80 		// File with object to be used to obtain subject/id
81 		case 'i':
82 			if ( !a_pszOptArg )
83 				return -1;
84 
85 			g_pszIdFile = strdup( a_pszOptArg );
86 			break;
87 
88 		// Use the specified token label when finding the token
89 		case 'k':
90 			if ( !a_pszOptArg )
91 				return -1;
92 
93 			g_pszToken = strdup( a_pszOptArg );
94 			break;
95 
96 		// Name to use as the LABEL attribute value
97 		case 'n':
98 			if ( !a_pszOptArg )
99 				return -1;
100 
101 			g_pchName = (CK_BYTE *)strdup( a_pszOptArg );
102 			g_ulNameLen = strlen( a_pszOptArg );
103 			break;
104 
105 		// Make the object public
106 		case 'p':
107 			g_bPublic = TRUE;
108 			break;
109 
110 		// Only import the specified object type
111 		case 't':
112 			if ( !a_pszOptArg )
113 				return -1;
114 
115 			if ( ( strcmp( a_pszOptArg, TOKEN_OBJECT_KEY )  != 0 ) &&
116 			     ( strcmp( a_pszOptArg, TOKEN_OBJECT_CERT ) != 0 ) )
117 				return -1;
118 
119 			g_pszType = strdup( a_pszOptArg );
120 			break;
121 
122 		// Reply "yes" to any yes/no prompts
123 		case 'y':
124 			g_bYes = TRUE;
125 			break;
126 	}
127 
128 	return 0;
129 }
130 
131 /*
132  * usageCallback
133  *   Display command usage information.
134  */
135 void
usageCallback(const char * a_pszCmd)136 usageCallback( const char *a_pszCmd ) {
137 
138 	char *pszArgs[2];
139 	char *pszArgsDesc[2];
140 
141 	pszArgs[ 0 ] = "FILE";
142 	pszArgsDesc[ 0 ] = _("Import the PEM formatted RSA key and/or X.509 certificate object contained in FILE");
143 	pszArgs[ 1 ] = NULL;
144 	pszArgsDesc[ 1 ] = NULL;
145 
146 	logCmdHelpEx( a_pszCmd, pszArgs, pszArgsDesc );
147 	logCmdOption( "-i, --idfile FILE",
148 			_("Use FILE as the PEM formatted X.509 certificate input used to obtain the subject and id attributes") );
149 	logCmdOption( "-k, --token STRING",
150 			_("Use STRING to identify the label of the PKCS#11 token to be used") );
151 	logCmdOption( "-n, --name STRING",
152 			_("Use STRING as the label for the imported object(s)") );
153 	logCmdOption( "-p, --public",
154 			_("Import the object(s) as a public object") );
155 	logCmdOption( "-t, --type key|cert",
156 			_("Import only the specified object type") );
157 	logCmdOption( "-y, --yes",
158 			_("Assume yes as the answer to any confirmation prompt") );
159 }
160 
161 /*
162  * parseCmd
163  *   Parse the command line options.
164  */
165 int
parseCmd(int a_iArgc,char ** a_pszArgv)166 parseCmd( int    a_iArgc,
167           char **a_pszArgv ) {
168 
169 	int  rc;
170 
171 	char          *pszShortOpts  = "i:k:n:pt:y";
172 	struct option  stLongOpts[]  = {
173 			{ "idfile", required_argument, NULL, 'i' },
174 			{ "name", required_argument, NULL, 'n' },
175 			{ "public", no_argument, NULL, 'p' },
176 			{ "token", required_argument, NULL, 'k' },
177 			{ "type", required_argument, NULL, 't' },
178 			{ "yes", no_argument, NULL, 'y' },
179 		};
180 	int  iNumLongOpts = sizeof( stLongOpts ) / sizeof( struct option );
181 
182 	rc = genericOptHandler( a_iArgc, a_pszArgv,
183 		pszShortOpts, stLongOpts, iNumLongOpts,
184 		parseCallback, usageCallback );
185 	if ( rc == -1 )
186 		return -1;
187 
188 	if ( optind >= a_iArgc ) {
189 		logMsg( TOKEN_FILE_ERROR );
190 		usageCallback( a_pszArgv[ 0 ] );
191 		return -1;
192 	}
193 
194 	g_pszFile = strdup( a_pszArgv[ optind ] );
195 
196 	return 0;
197 }
198 
199 /*
200  * findExistingObjects
201  *   Search for objects of the supplied type that have a SUBJECT
202  *   and ID attribute equal to the values of the object to be
203  *   imported.
204  */
205 int
findExistingObjects(CK_SESSION_HANDLE a_hSession,CK_ATTRIBUTE * a_tAttr,CK_ULONG a_ulAttrCount,CK_OBJECT_HANDLE ** a_phObject,CK_ULONG * a_pulObjectCount)206 findExistingObjects( CK_SESSION_HANDLE   a_hSession,
207                      CK_ATTRIBUTE       *a_tAttr,
208                      CK_ULONG            a_ulAttrCount,
209                      CK_OBJECT_HANDLE  **a_phObject,
210                      CK_ULONG           *a_pulObjectCount ) {
211 
212 	CK_RV     rv;
213 	CK_BBOOL  bTrue = TRUE;
214 
215 	// Set up default search attributes
216 	CK_ATTRIBUTE  tDefaultAttr[]     = {
217 			{ CKA_TOKEN, &bTrue, sizeof( bTrue ) },
218 			{ CKA_SUBJECT, g_pchSubject, g_subjectLen },
219 			{ CKA_ID, g_pchId, g_ulIdLen },
220 		};
221 	CK_ULONG      ulDefaultAttrCount = sizeof( tDefaultAttr ) / sizeof( CK_ATTRIBUTE );
222 
223 	CK_ATTRIBUTE  tAttr[ ulDefaultAttrCount + a_ulAttrCount ];
224 	CK_ULONG      ulAttrCount = sizeof( tAttr ) / sizeof( CK_ATTRIBUTE );
225 
226 	*a_phObject = NULL;
227 	*a_pulObjectCount = 0;
228 
229 	// Apply attributes and search
230 	memcpy( tAttr, tDefaultAttr, ulDefaultAttrCount * sizeof( CK_ATTRIBUTE ) );
231 	if ( a_ulAttrCount )
232 		memcpy( tAttr + ulDefaultAttrCount, a_tAttr, a_ulAttrCount * sizeof( CK_ATTRIBUTE ) );
233 
234 	rv = findObjects( a_hSession, tAttr, ulAttrCount, a_phObject, a_pulObjectCount );
235 
236 	return ( rv == CKR_OK ) ? 0 : -1;
237 }
238 
239 /*
240  * checkExistingObjects
241  *   Use findExistingObjects to determine if objects of the
242  *   supplied type currently exist.  If so, prompt the user as
243  *   to whether to replace the existing objects.
244  */
245 int
checkExistingObjects(CK_SESSION_HANDLE a_hSession,CK_ATTRIBUTE * a_tAttr,CK_ULONG a_ulAttrCount,const char * a_pszObject)246 checkExistingObjects( CK_SESSION_HANDLE  a_hSession,
247                       CK_ATTRIBUTE      *a_tAttr,
248                       CK_ULONG           a_ulAttrCount,
249                       const char        *a_pszObject ) {
250 
251 	int  rc = -1;
252 
253 	CK_OBJECT_HANDLE *phObject      = NULL;
254 	CK_ULONG          ulObjectCount = 0;
255 
256 	char  szPrompt[ strlen( TOKEN_ID_PROMPT ) + strlen( a_pszObject ) + 1 ];
257 	char *pszReply = NULL;
258 
259 	if ( g_bAttrsValid ) {
260 		// Search for existing objects
261 		if ( findExistingObjects( a_hSession, a_tAttr, a_ulAttrCount, &phObject, &ulObjectCount ) == -1 )
262 			goto out;
263 
264 		if ( ulObjectCount > 0 ) {
265 			// One or more objects exists
266 			if ( !g_bYes ) {
267 				// Prompt for whether to replace the existing objects
268 				sprintf( szPrompt, TOKEN_ID_PROMPT, a_pszObject );
269 				pszReply = getReply( szPrompt, 1 );
270 				if ( !pszReply ||
271 					( strlen( pszReply ) == 0 ) ||
272 					( strcasecmp( pszReply, TOKEN_ID_NO ) == 0 ) ) {
273 					goto out;
274 				}
275 			}
276 		}
277 	}
278 
279 	rc = 0;
280 
281 out:
282 	free( phObject );
283 	free( pszReply );
284 
285 	return rc;
286 }
287 
288 /*
289  * destroyExistingObjects
290  *   Use findExistingObjects to locate all objects of the
291  *   supplied type that currently exists and destroy them.
292  */
293 int
destroyExistingObjects(CK_SESSION_HANDLE a_hSession,CK_ATTRIBUTE * a_tAttr,CK_ULONG a_ulAttrCount)294 destroyExistingObjects( CK_SESSION_HANDLE  a_hSession,
295                         CK_ATTRIBUTE      *a_tAttr,
296                         CK_ULONG           a_ulAttrCount ) {
297 
298 	int  rc = -1;
299 
300 	CK_RV             rv;
301 	CK_OBJECT_HANDLE *phObject      = NULL;
302 	CK_ULONG          ulObjectCount = 0;
303 
304 	if ( g_bAttrsValid ) {
305 		// Search for existing objects
306 		if ( findExistingObjects( a_hSession, a_tAttr, a_ulAttrCount, &phObject, &ulObjectCount ) == -1 )
307 			goto out;
308 
309 		// Destroy each object found
310 		while ( ulObjectCount > 0 ) {
311 			rv = destroyObject( a_hSession, phObject[ --ulObjectCount ] );
312 			if ( rv != CKR_OK )
313 				goto out;
314 		}
315 	}
316 
317 	rc = 0;
318 
319 out:
320 	free( phObject );
321 
322 	return rc;
323 }
324 
325 /*
326  * readX509Cert
327  *   Use the OpenSSL library to read a PEM formatted X509 certificate.
328  */
329 int
readX509Cert(const char * a_pszFile,int a_bCheckKey,X509 ** a_pX509)330 readX509Cert( const char  *a_pszFile,
331               int          a_bCheckKey,
332               X509       **a_pX509 ) {
333 
334 	int rc = -1;
335 
336 	FILE     *pFile = stdin;
337 	X509     *pX509 = NULL;
338 	EVP_PKEY *pKey  = NULL;
339 
340 	*a_pX509 = NULL;
341 
342 	// Open the file to be read
343 	if ( a_pszFile ) {
344 		errno = 0;
345 		pFile = fopen( a_pszFile, "r" );
346 		if ( !pFile ) {
347 			logError( TOKEN_FILE_OPEN_ERROR, a_pszFile, strerror( errno ) );
348 			goto out;
349 		}
350 	}
351 
352 	// Read the X509 certificate
353 	pX509 = PEM_read_X509( pFile, NULL, NULL, NULL );
354 	if ( !pX509 ) {
355 		unsigned long  ulError = ERR_get_error( );
356 
357 		// Not necessarily an error if the file doesn't contain the cert
358 		if ( ( ERR_GET_LIB( ulError ) == ERR_R_PEM_LIB ) &&
359 		     ( ERR_GET_REASON( ulError ) == PEM_R_NO_START_LINE ) ) {
360 			logInfo( TOKEN_OPENSSL_ERROR, ERR_error_string( ulError, NULL ) );
361 			rc = 0;
362 		}
363 		else
364 			logError( TOKEN_OPENSSL_ERROR, ERR_error_string( ulError, NULL ) );
365 
366 		goto out;
367 	}
368 
369 	// Make sure the certificate uses an RSA key
370 	if ( !a_bCheckKey ) {
371 		rc = 0;
372 		goto out;
373 	}
374 
375 	pKey = X509_get_pubkey( pX509 );
376 	if ( !pKey ) {
377 		logInfo( TOKEN_OPENSSL_ERROR,
378 			ERR_error_string( ERR_get_error( ), NULL ) );
379 
380 		X509_free( pX509 );
381 		pX509 = NULL;
382 		goto out;
383 	}
384 
385 	if ( EVP_PKEY_type( EVP_PKEY_id(pKey) ) != EVP_PKEY_RSA ) {
386 		logError( TOKEN_RSA_KEY_ERROR );
387 
388 		X509_free( pX509 );
389 		pX509 = NULL;
390 		goto out;
391 	}
392 
393 	rc = 0;
394 
395 out:
396 	*a_pX509 = pX509;
397 
398 	if ( a_pszFile && pFile )
399 		fclose( pFile );
400 
401 	return rc;
402 }
403 
404 /*
405  * checkX509Cert
406  *   Use checkExistingObjects to search for X_509 objects
407  *   that match the attributes of the X_509 object to be imported.
408  */
409 int
checkX509Cert(CK_SESSION_HANDLE a_hSession)410 checkX509Cert( CK_SESSION_HANDLE  a_hSession ) {
411 
412 	CK_CERTIFICATE_TYPE  tX509       = CKC_X_509;
413 	CK_ATTRIBUTE         tAttr[]     = {
414 			{ CKA_CERTIFICATE_TYPE, &tX509, sizeof( tX509 ) },
415 		};
416 	CK_ULONG             ulAttrCount = sizeof( tAttr ) / sizeof( CK_ATTRIBUTE );
417 
418 	return checkExistingObjects( a_hSession, tAttr, ulAttrCount, TOKEN_ID_X509_CERT );
419 }
420 
421 /*
422  * destroyX509CertObject
423  *   Use destroyExistingObjects to destroy X_509 objects
424  *   that match the attributes of the X_509 object to be imported.
425  */
426 int
destroyX509CertObject(CK_SESSION_HANDLE a_hSession)427 destroyX509CertObject( CK_SESSION_HANDLE  a_hSession ) {
428 
429 	CK_CERTIFICATE_TYPE  tX509       = CKC_X_509;
430 	CK_ATTRIBUTE         tAttr[]     = {
431 			{ CKA_CERTIFICATE_TYPE, &tX509, sizeof( tX509 ) },
432 		};
433 	CK_ULONG             ulAttrCount = sizeof( tAttr ) / sizeof( CK_ATTRIBUTE );
434 
435 	return destroyExistingObjects( a_hSession, tAttr, ulAttrCount );
436 }
437 
438 /*
439  * createX509CertObject
440  *   Create an X_509 object.
441  */
442 int
createX509CertObject(X509 * a_pX509,CK_SESSION_HANDLE a_hSession)443 createX509CertObject( X509              *a_pX509,
444                       CK_SESSION_HANDLE  a_hSession ) {
445 
446 	int  rc = -1;
447 
448 	CK_RV  rv;
449 
450 	CK_BBOOL  bTrue = TRUE;
451 
452 	X509_NAME    *pIssuer    = NULL;
453 	ASN1_INTEGER *pSerialNum = NULL;
454 
455 	CK_BYTE  *pchIssuer      = NULL;
456 	CK_LONG  issuerLen    = 0;
457 	CK_BYTE  *pchSerialNum   = NULL;
458 	CK_LONG  serialNumLen = 0;
459 	CK_BYTE  *pchCert        = NULL;
460 	CK_LONG  certLen      = 0;
461 
462 	CK_OBJECT_CLASS      clCertClass = CKO_CERTIFICATE;
463 	CK_CERTIFICATE_TYPE  tCertType   = CKC_X_509;
464 	CK_BBOOL             bPrivate    = ( !g_bPublic ) ? TRUE : FALSE;
465 
466 	// The issuer, serial number, and value attributes must be completed
467 	// before the object is created
468 	CK_ATTRIBUTE  tCertAttr[] = {
469 			{ CKA_CLASS, &clCertClass, sizeof( clCertClass ) },
470 			{ CKA_TOKEN, &bTrue, sizeof( bTrue ) },
471 			{ CKA_PRIVATE, &bPrivate, sizeof( bPrivate ) },
472 			{ CKA_MODIFIABLE, &bTrue, sizeof( bTrue ) },
473 			{ CKA_LABEL, g_pchName, g_ulNameLen },
474 			{ CKA_CERTIFICATE_TYPE, &tCertType, sizeof( tCertType ) },
475 			{ CKA_SUBJECT, g_pchSubject, g_subjectLen },
476 			{ CKA_ID, g_pchId, g_ulIdLen },
477 			{ CKA_ISSUER, NULL, 0 },
478 			{ CKA_SERIAL_NUMBER, NULL, 0 },
479 			{ CKA_VALUE, NULL, 0 },
480 		};
481 	CK_ULONG  ulCertAttrCount = sizeof( tCertAttr ) / sizeof( CK_ATTRIBUTE );
482 
483 	CK_OBJECT_HANDLE  hObject;
484 
485 	// Get the issuer name from the X509 certificate
486 	pIssuer = X509_get_issuer_name( a_pX509 );
487 	if ( !pIssuer ) {
488 		logError( TOKEN_OPENSSL_ERROR,
489 				ERR_error_string( ERR_get_error( ), NULL ) );
490 		goto out;
491 	}
492 	issuerLen = i2d_X509_NAME( pIssuer, &pchIssuer );
493 	if ( issuerLen < 0 ) {
494 		logError( TOKEN_OPENSSL_ERROR,
495 				ERR_error_string( ERR_get_error( ), NULL ) );
496 		goto out;
497 	}
498 
499 	// Get the serial number from the X509 certificate
500 	pSerialNum = X509_get_serialNumber( a_pX509 );
501 	if ( !pSerialNum ) {
502 		logError( TOKEN_OPENSSL_ERROR,
503 				ERR_error_string( ERR_get_error( ), NULL ) );
504 		goto out;
505 	}
506 	serialNumLen = i2d_ASN1_INTEGER( pSerialNum, &pchSerialNum );
507 	if ( serialNumLen < 0 ) {
508 		logError( TOKEN_OPENSSL_ERROR,
509 				ERR_error_string( ERR_get_error( ), NULL ) );
510 		goto out;
511 	}
512 
513 	// Get a DER encoded format of the X509 certificate
514 	certLen = i2d_X509( a_pX509, &pchCert );
515 	if ( certLen < 0 ) {
516 		logError( TOKEN_OPENSSL_ERROR,
517 				ERR_error_string( ERR_get_error( ), NULL ) );
518 		goto out;
519 	}
520 
521 	// Set the attribute values
522 	tCertAttr[ 8 ].pValue = pchIssuer;
523 	tCertAttr[ 8 ].ulValueLen = issuerLen;
524 	tCertAttr[ 9 ].pValue = pchSerialNum;
525 	tCertAttr[ 9 ].ulValueLen = serialNumLen;
526 	tCertAttr[ 10 ].pValue = pchCert;
527 	tCertAttr[ 10 ].ulValueLen = certLen;
528 
529 	// Create the X509 certificate object
530 	rv = createObject( a_hSession, tCertAttr, ulCertAttrCount, &hObject );
531 	if ( rv != CKR_OK )
532 		goto out;
533 
534 	rc = 0;
535 
536 out:
537 	OPENSSL_free( pchIssuer );
538 	OPENSSL_free( pchCert );
539 	OPENSSL_free( pchSerialNum );
540 
541 	return rc;
542 }
543 
544 /*
545  * doX509Cert
546  *   Process an X509 certificate for import.
547  */
548 int
doX509Cert(X509 * a_pX509,CK_SESSION_HANDLE a_hSession)549 doX509Cert( X509              *a_pX509,
550             CK_SESSION_HANDLE  a_hSession ) {
551 
552 	int  rc = -1;
553 
554 	if ( destroyX509CertObject( a_hSession ) == -1 )
555 		goto out;
556 
557 	if ( createX509CertObject( a_pX509, a_hSession ) == -1 )
558 		goto out;
559 
560 	rc = 0;
561 
562 out:
563 	return rc;
564 }
565 
566 /*
567  * readRsaKey
568  *   Use the OpenSSL library to read a PEM formatted RSA key.
569  */
570 int
readRsaKey(const char * a_pszFile,RSA ** a_pRsa)571 readRsaKey( const char  *a_pszFile,
572             RSA        **a_pRsa ) {
573 
574 	int  rc = -1;
575 
576 	FILE *pFile = stdin;
577 	RSA  *pRsa  = NULL;
578 
579 	*a_pRsa = NULL;
580 
581 	// Open the file to be read
582 	if ( a_pszFile ) {
583 		errno = 0;
584 		pFile = fopen( a_pszFile, "r" );
585 		if ( !pFile ) {
586 			logError( TOKEN_FILE_OPEN_ERROR, a_pszFile, strerror( errno ) );
587 			goto out;
588 		}
589 	}
590 
591 	// Read the RSA key
592 	//   This reads the public key also, not just the private key
593 	pRsa = PEM_read_RSAPrivateKey( pFile, NULL, NULL, NULL );
594 	if ( !pRsa ) {
595 		unsigned long  ulError = ERR_get_error( );
596 
597 		// Not necessarily an error if the file doesn't contain the key
598 		if ( ( ERR_GET_LIB( ulError ) == ERR_R_PEM_LIB ) &&
599 		     ( ERR_GET_REASON( ulError ) == PEM_R_NO_START_LINE ) ) {
600 			logInfo( TOKEN_OPENSSL_ERROR, ERR_error_string( ulError, NULL ) );
601 			rc = 0;
602 		}
603 		else
604 			logError( TOKEN_OPENSSL_ERROR, ERR_error_string( ulError, NULL ) );
605 
606 		goto out;
607 	}
608 
609 	rc = 0;
610 
611 out:
612 	if ( a_pszFile && pFile )
613 		fclose( pFile );
614 
615 	*a_pRsa = pRsa;
616 
617 	return rc;
618 }
619 
620 /*
621  * checkRsaPubKey
622  *   Use checkExistingObjects to search for RSA public key objects
623  *   that match the attributes of the X509's RSA public key object
624  *   to be imported.
625  */
626 int
checkRsaPubKey(CK_SESSION_HANDLE a_hSession)627 checkRsaPubKey( CK_SESSION_HANDLE  a_hSession ) {
628 
629 	CK_OBJECT_CLASS  tPubKey  = CKO_PUBLIC_KEY;
630 	CK_KEY_TYPE      tRsa     = CKK_RSA;
631 	CK_ATTRIBUTE     tAttr[]  = {
632 			{ CKA_CLASS, &tPubKey, sizeof( tPubKey ) },
633 			{ CKA_KEY_TYPE, &tRsa, sizeof( tRsa ) },
634 		};
635 	CK_ULONG         ulAttrCount = sizeof( tAttr ) / sizeof( CK_ATTRIBUTE );
636 
637 	return checkExistingObjects( a_hSession, tAttr, ulAttrCount, TOKEN_ID_RSA_PUBKEY );
638 }
639 
640 /*
641  * checkRsaKey
642  *   Use checkExistingObjects to search for RSA objects
643  *   that match the attributes of the RSA object to be imported.
644  */
645 int
checkRsaKey(CK_SESSION_HANDLE a_hSession)646 checkRsaKey( CK_SESSION_HANDLE  a_hSession ) {
647 
648 	CK_KEY_TYPE   tRsa        = CKK_RSA;
649 	CK_ATTRIBUTE  tAttr[]     = {
650 			{ CKA_KEY_TYPE, &tRsa, sizeof( tRsa ) },
651 		};
652 	CK_ULONG      ulAttrCount = sizeof( tAttr ) / sizeof( CK_ATTRIBUTE );
653 
654 	return checkExistingObjects( a_hSession, tAttr, ulAttrCount, TOKEN_ID_RSA_KEY );
655 }
656 
657 /*
658  * destroyRsaKeyObject
659  *   Use destroyExistingObjects to destroy RSA objects
660  *   that match the attributes of the RSA object to be imported.
661  */
662 int
destroyRsaPubKeyObject(CK_SESSION_HANDLE a_hSession)663 destroyRsaPubKeyObject( CK_SESSION_HANDLE  a_hSession ) {
664 
665 	CK_OBJECT_CLASS  tPubKey     = CKO_PUBLIC_KEY;
666 	CK_KEY_TYPE      tRsa        = CKK_RSA;
667 	CK_ATTRIBUTE     tAttr[]     = {
668 			{ CKA_CLASS, &tPubKey, sizeof( tPubKey ) },
669 			{ CKA_KEY_TYPE, &tRsa, sizeof( tRsa ) },
670 		};
671 	CK_ULONG         ulAttrCount = sizeof( tAttr ) / sizeof( CK_ATTRIBUTE );
672 
673 	return destroyExistingObjects( a_hSession, tAttr, ulAttrCount );
674 }
675 
676 /*
677  * destroyRsaKeyObject
678  *   Use destroyExistingObjects to destroy RSA objects
679  *   that match the attributes of the RSA object to be imported.
680  */
681 int
destroyRsaKeyObject(CK_SESSION_HANDLE a_hSession)682 destroyRsaKeyObject( CK_SESSION_HANDLE  a_hSession ) {
683 
684 	CK_KEY_TYPE   tRsa        = CKK_RSA;
685 	CK_ATTRIBUTE  tAttr[]     = {
686 			{ CKA_KEY_TYPE, &tRsa, sizeof( tRsa ) },
687 		};
688 	CK_ULONG      ulAttrCount = sizeof( tAttr ) / sizeof( CK_ATTRIBUTE );
689 
690 	return destroyExistingObjects( a_hSession, tAttr, ulAttrCount );
691 }
692 
693 /*
694  * createRsaPubKeyObject
695  *   Create an RSA public key object.
696  */
697 int
createRsaPubKeyObject(RSA * a_pRsa,CK_SESSION_HANDLE a_hSession,CK_OBJECT_HANDLE * a_hObject)698 createRsaPubKeyObject( RSA               *a_pRsa,
699                        CK_SESSION_HANDLE  a_hSession,
700                        CK_OBJECT_HANDLE  *a_hObject ) {
701 
702 	int  rc = -1;
703 
704 	int  nLen = BN_num_bytes( RSA_get0_n(a_pRsa) );
705 	int  eLen = BN_num_bytes( RSA_get0_e(a_pRsa) );
706 
707 	CK_RV  rv;
708 
709 	CK_BBOOL  bTrue  = TRUE;
710 	CK_BBOOL  bFalse = FALSE;
711 
712 	CK_BYTE *n = malloc( nLen );
713 	CK_BYTE *e = malloc( eLen );
714 
715 	CK_OBJECT_CLASS  clPubClass  = CKO_PUBLIC_KEY;
716 	CK_KEY_TYPE      tKeyType    = CKK_RSA;
717 	CK_BBOOL         bPrivate    = ( !g_bPublic ) ? TRUE : FALSE;
718 
719 	CK_ATTRIBUTE  tAttr[] = {
720 			{ CKA_CLASS, &clPubClass, sizeof( clPubClass ) },
721 			{ CKA_TOKEN, &bTrue, sizeof( bTrue ) },
722 			{ CKA_PRIVATE, &bPrivate, sizeof( bPrivate ) },
723 			{ CKA_MODIFIABLE, &bTrue, sizeof( bTrue ) },
724 			{ CKA_LABEL, g_pchName, g_ulNameLen },
725 			{ CKA_KEY_TYPE, &tKeyType, sizeof( tKeyType ) },
726 			{ CKA_ID, g_pchId, g_ulIdLen },
727 			{ CKA_SUBJECT, g_pchSubject, g_subjectLen },
728 			{ CKA_ENCRYPT, &bTrue, sizeof( bTrue ) },
729 			{ CKA_VERIFY, &bTrue, sizeof( bTrue ) },
730 			{ CKA_VERIFY_RECOVER, &bFalse, sizeof( bFalse ) },
731 			{ CKA_WRAP, &bFalse, sizeof( bFalse ) },
732 			{ CKA_MODULUS, n, nLen },
733 			{ CKA_PUBLIC_EXPONENT, e, eLen },
734 		};
735 	CK_ULONG  ulAttrCount = sizeof( tAttr ) / sizeof( CK_ATTRIBUTE );
736 
737 	*a_hObject = 0;
738 
739 	if ( !n || !e ) {
740 		logError( TOKEN_MEMORY_ERROR );
741 		goto out;
742 	}
743 
744 	// Get binary representations of the RSA key information
745 	BN_bn2bin( RSA_get0_n(a_pRsa), n );
746 	BN_bn2bin( RSA_get0_e(a_pRsa), e );
747 
748 	// Create the RSA public key object
749 	rv = createObject( a_hSession, tAttr, ulAttrCount, a_hObject );
750 	if ( rv != CKR_OK )
751 		goto out;
752 
753 	rc = 0;
754 
755 out:
756 	free( n );
757 	free( e );
758 
759 	return rc;
760 }
761 
762 /*
763  * createRsaPrivKeyObject
764  *   Create an RSA private key object.
765  */
766 int
createRsaPrivKeyObject(RSA * a_pRsa,CK_SESSION_HANDLE a_hSession,CK_OBJECT_HANDLE * a_hObject)767 createRsaPrivKeyObject( RSA               *a_pRsa,
768                         CK_SESSION_HANDLE  a_hSession,
769                         CK_OBJECT_HANDLE  *a_hObject ) {
770 
771 	int  rc = -1;
772 
773 	int  nLen = BN_num_bytes( RSA_get0_n(a_pRsa) );
774 	int  eLen = BN_num_bytes( RSA_get0_e(a_pRsa) );
775 	int  dLen = BN_num_bytes( RSA_get0_d(a_pRsa) );
776 	int  pLen = BN_num_bytes( RSA_get0_p(a_pRsa) );
777 	int  qLen = BN_num_bytes( RSA_get0_q(a_pRsa) );
778 	int  dmp1Len = BN_num_bytes( RSA_get0_dmp1(a_pRsa) );
779 	int  dmq1Len = BN_num_bytes( RSA_get0_dmq1(a_pRsa) );
780 	int  iqmpLen = BN_num_bytes( RSA_get0_iqmp(a_pRsa) );
781 
782 	CK_RV  rv;
783 
784 	CK_BBOOL  bTrue  = TRUE;
785 	CK_BBOOL  bFalse = FALSE;
786 
787 	CK_BYTE *n = malloc( nLen );
788 	CK_BYTE *e = malloc( eLen );
789 	CK_BYTE *d = malloc( dLen );
790 	CK_BYTE *p = malloc( pLen );
791 	CK_BYTE *q = malloc( qLen );
792 	CK_BYTE *dmp1 = malloc( dmp1Len );
793 	CK_BYTE *dmq1 = malloc( dmq1Len );
794 	CK_BYTE *iqmp = malloc( iqmpLen );
795 
796 	CK_OBJECT_CLASS  clPrivClass = CKO_PRIVATE_KEY;
797 	CK_KEY_TYPE      tKeyType    = CKK_RSA;
798 	CK_BBOOL         bPrivate    = ( !g_bPublic ) ? TRUE : FALSE;
799 
800 	CK_ATTRIBUTE  tAttr[] = {
801 			{ CKA_CLASS, &clPrivClass, sizeof( clPrivClass ) },
802 			{ CKA_TOKEN, &bTrue, sizeof( bTrue ) },
803 			{ CKA_PRIVATE, &bPrivate, sizeof( bPrivate ) },
804 			{ CKA_MODIFIABLE, &bTrue, sizeof( bTrue ) },
805 			{ CKA_LABEL, g_pchName, g_ulNameLen },
806 			{ CKA_KEY_TYPE, &tKeyType, sizeof( tKeyType ) },
807 			{ CKA_ID, g_pchId, g_ulIdLen },
808 			{ CKA_SUBJECT, g_pchSubject, g_subjectLen },
809 			{ CKA_SENSITIVE, &bTrue, sizeof( bTrue ) },
810 			{ CKA_DECRYPT, &bTrue, sizeof( bTrue ) },
811 			{ CKA_SIGN, &bTrue, sizeof( bTrue ) },
812 			{ CKA_SIGN_RECOVER, &bFalse, sizeof( bFalse ) },
813 			{ CKA_UNWRAP, &bFalse, sizeof( bFalse ) },
814 			{ CKA_EXTRACTABLE, &bFalse, sizeof( bFalse ) },
815 			{ CKA_MODULUS, n, nLen },
816 			{ CKA_PUBLIC_EXPONENT, e, eLen },
817 			{ CKA_PRIVATE_EXPONENT, d, dLen },
818 			{ CKA_PRIME_1, p, pLen },
819 			{ CKA_PRIME_2, q, qLen },
820 			{ CKA_EXPONENT_1, dmp1, dmp1Len },
821 			{ CKA_EXPONENT_2, dmq1, dmq1Len },
822 			{ CKA_COEFFICIENT, iqmp, iqmpLen },
823 		};
824 	CK_ULONG  ulAttrCount = sizeof( tAttr ) / sizeof( CK_ATTRIBUTE );
825 
826 	*a_hObject = 0;
827 
828 	if ( !n || !e || !d || !p || !q || !dmp1 || !dmq1 || !iqmp ) {
829 		logError( TOKEN_MEMORY_ERROR );
830 		goto out;
831 	}
832 
833 	// Get binary representations of the RSA key information
834 	BN_bn2bin( RSA_get0_n(a_pRsa), n );
835 	BN_bn2bin( RSA_get0_e(a_pRsa), e );
836 	BN_bn2bin( RSA_get0_d(a_pRsa), d );
837 	BN_bn2bin( RSA_get0_p(a_pRsa), p );
838 	BN_bn2bin( RSA_get0_q(a_pRsa), q );
839 	BN_bn2bin( RSA_get0_dmp1(a_pRsa), dmp1 );
840 	BN_bn2bin( RSA_get0_dmq1(a_pRsa), dmq1 );
841 	BN_bn2bin( RSA_get0_iqmp(a_pRsa), iqmp );
842 
843 	// Create the RSA private key object
844 	rv = createObject( a_hSession, tAttr, ulAttrCount, a_hObject );
845 	if ( rv != CKR_OK )
846 		goto out;
847 
848 	rc = 0;
849 
850 out:
851 	free( n );
852 	free( e );
853 	free( d );
854 	free( p );
855 	free( q );
856 	free( dmp1 );
857 	free( dmq1 );
858 	free( iqmp );
859 
860 	return rc;
861 }
862 
863 /*
864  * createRsaKeyObject
865  *   Create an RSA key object (both public and private).
866  */
867 int
createRsaKeyObject(RSA * a_pRsa,CK_SESSION_HANDLE a_hSession)868 createRsaKeyObject( RSA               *a_pRsa,
869                     CK_SESSION_HANDLE  a_hSession ) {
870 
871 	int  rc = -1;
872 
873 	CK_OBJECT_HANDLE  hPubObject;
874 	CK_OBJECT_HANDLE  hPrivObject;
875 
876 	// Create the RSA public key object
877 	if ( createRsaPubKeyObject( a_pRsa, a_hSession, &hPubObject ) == -1 )
878 		goto out;
879 
880 	// Create the RSA private key object
881 	if ( createRsaPrivKeyObject( a_pRsa, a_hSession, &hPrivObject ) == -1 ) {
882 		// Private key object creation failed, destroy the public
883 		// key object just created
884 		destroyObject( a_hSession, hPubObject );
885 		goto out;
886 	}
887 
888 	rc = 0;
889 
890 out:
891 	return rc;
892 }
893 
894 /*
895  * doRsaPubKey
896  *   Process an RSA public key for import.
897  */
898 int
doRsaPubKey(RSA * a_pRsa,CK_SESSION_HANDLE a_hSession)899 doRsaPubKey( RSA               *a_pRsa,
900              CK_SESSION_HANDLE  a_hSession ) {
901 
902 	int  rc = -1;
903 
904 	CK_OBJECT_HANDLE  hObject;
905 
906 	if ( destroyRsaPubKeyObject( a_hSession ) == -1 )
907 		goto out;
908 
909 	if ( createRsaPubKeyObject( a_pRsa, a_hSession, &hObject ) == -1 )
910 		goto out;
911 
912 	rc = 0;
913 
914 out:
915 	return rc;
916 }
917 
918 /*
919  * doRsaKey
920  *   Process an RSA key for import.
921  */
922 int
doRsaKey(RSA * a_pRsa,CK_SESSION_HANDLE a_hSession)923 doRsaKey( RSA               *a_pRsa,
924           CK_SESSION_HANDLE  a_hSession ) {
925 
926 	int  rc = -1;
927 
928 	if ( destroyRsaKeyObject( a_hSession ) == -1 )
929 		goto out;
930 
931 	if ( createRsaKeyObject( a_pRsa, a_hSession ) == -1 )
932 		goto out;
933 
934 	rc = 0;
935 
936 out:
937 	return rc;
938 }
939 
940 /*
941  * getSubjectId
942  *   Extract the subject name and key identifier from an
943  *   X509 certificate for use as the SUBJECT and ID attributes.
944  */
945 int
getSubjectId(X509 * a_pX509)946 getSubjectId( X509 *a_pX509 ) {
947 
948 	int  rc = -1;
949 
950 	char *pszReply = NULL;
951 
952 	X509              *pX509    = a_pX509;
953 	X509_NAME         *pSubject = NULL;
954 	ASN1_OCTET_STRING *pSkid    = NULL;
955 
956 	// Use the Id input file if specified
957 	if ( g_pszIdFile )
958 		if ( readX509Cert( g_pszIdFile, FALSE, &pX509 ) == -1 )
959 			goto out;
960 
961 	if ( !pX509 ) {
962 		// Prompt the user about creating without it.
963 		if ( !g_bYes ) {
964 			// Prompt for whether to import without the attributes
965 			pszReply = getReply( TOKEN_ID_MISSING_PROMPT, 1 );
966 			if ( !pszReply ||
967 				( strlen( pszReply ) == 0 ) ||
968 				( strcasecmp( pszReply, TOKEN_ID_NO ) == 0 ) ) {
969 				goto out;
970 			}
971 		}
972 
973 		rc = 0;
974 		goto out;
975 	}
976 
977 	// Get the subject name from the X509 certificate
978 	pSubject = X509_get_subject_name( pX509 );
979 	if ( !pSubject ) {
980 		logInfo( TOKEN_OPENSSL_ERROR,
981 				ERR_error_string( ERR_get_error( ), NULL ) );
982 		goto out;
983 	}
984 
985 	// Get the DER encoded format of the subject name
986 	g_subjectLen = i2d_X509_NAME( pSubject, &g_pchSubject );
987 	if ( g_subjectLen < 0 ) {
988 		logInfo( TOKEN_OPENSSL_ERROR,
989 				ERR_error_string( ERR_get_error( ), NULL ) );
990 		goto out;
991 	}
992 
993 	// Get the subject key identifier from the X509 certficate
994 	pSkid = X509_get_ext_d2i( pX509, NID_subject_key_identifier, NULL, NULL );
995 	if ( !pSkid ) {
996 		logInfo( TOKEN_OPENSSL_ERROR,
997 				ERR_error_string( ERR_get_error( ), NULL ) );
998 		goto out;
999 	}
1000 
1001 	// Get the ASCII string format of the subject key identifier
1002 	g_pchId = (CK_BYTE *)i2s_ASN1_OCTET_STRING( NULL, pSkid );
1003 	if ( !g_pchId ) {
1004 		logInfo( TOKEN_OPENSSL_ERROR,
1005 				ERR_error_string( ERR_get_error( ), NULL ) );
1006 		goto out;
1007 	}
1008 	g_ulIdLen = strlen( (char *)g_pchId );
1009 
1010 	g_bAttrsValid = TRUE;
1011 
1012 	rc = 0;
1013 
1014 out:
1015 	// Free the structure if it was created for this function
1016 	if ( pX509 && ( pX509 != a_pX509 ) )
1017 		X509_free( pX509 );
1018 
1019 	ASN1_OCTET_STRING_free( pSkid );
1020 	free( pszReply );
1021 
1022 	return rc;
1023 }
1024 
1025 int
main(int a_iArgc,char ** a_pszArgv)1026 main( int    a_iArgc,
1027       char **a_pszArgv ) {
1028 
1029 	int  rc = 1;
1030 
1031 	char *pszPin    = NULL;
1032 
1033 	CK_RV              rv        = CKR_OK;
1034 	CK_SESSION_HANDLE  hSession  = 0;
1035 
1036 	X509 *pX509   = NULL;
1037 	RSA  *pPubRsa = NULL;
1038 	RSA  *pRsa    = NULL;
1039 
1040 	// Set up i18n
1041 	initIntlSys( );
1042 
1043 	// Initialize OpenSSL
1044 	OpenSSL_add_all_algorithms( );
1045 	ERR_load_crypto_strings( );
1046 
1047 	// Parse the command
1048 	if ( parseCmd( a_iArgc, a_pszArgv ) == -1 )
1049 		goto out;
1050 
1051 	// Open the PKCS#11 TPM Token
1052 	rv = openToken( g_pszToken );
1053 	if ( rv != CKR_OK )
1054 		goto out;
1055 
1056 	// Make sure the token is initialized
1057 	if ( !isTokenInitialized( ) ) {
1058 		logMsg( TOKEN_NOT_INIT_ERROR );
1059 		goto out;
1060 	}
1061 
1062 	// Create the structures based on the input
1063 	if ( !g_pszType ) {
1064 		if ( readX509Cert( g_pszFile, TRUE, &pX509 ) == -1 )
1065 			goto out;
1066 		if ( readRsaKey( g_pszFile, &pRsa ) == -1 )
1067 			goto out;
1068 		if ( !pX509 && !pRsa ) {
1069 			logError( TOKEN_OBJECT_ERROR );
1070 			goto out;
1071 		}
1072 	}
1073 	else if ( strcmp( g_pszType, TOKEN_OBJECT_CERT ) == 0 ) {
1074 		if ( readX509Cert( g_pszFile, TRUE, &pX509 ) == -1 )
1075 			goto out;
1076 		if ( !pX509 ) {
1077 			logError( TOKEN_OBJECT_ERROR );
1078 			goto out;
1079 		}
1080 	}
1081 	else if ( strcmp( g_pszType, TOKEN_OBJECT_KEY ) == 0 ) {
1082 		if ( readRsaKey( g_pszFile, &pRsa ) == -1 )
1083 			goto out;
1084 		if ( !pRsa ) {
1085 			logError( TOKEN_OBJECT_ERROR );
1086 			goto out;
1087 		}
1088 	}
1089 
1090 	// Open a session
1091 	rv = openTokenSession( CKF_RW_SESSION, &hSession );
1092 	if ( rv != CKR_OK )
1093 		goto out;
1094 
1095 	// Check the scope of the request, which will determine the login
1096 	// requirements:
1097 	//   Public  = no password, no login
1098 	//   Private = user password, user login (default)
1099 	if ( !g_bPublic ) {
1100 		pszPin = getPlainPasswd( TOKEN_USER_PIN_PROMPT, FALSE );
1101 		if ( !pszPin )
1102 			goto out;
1103 
1104 		// Login to the token
1105 		rv = loginToken( hSession, CKU_USER, pszPin );
1106 		if ( rv != CKR_OK )
1107 			goto out;
1108 	}
1109 
1110 	// Obtain the subject name and id, these are used to
1111 	// uniquely identify the certificate/key relation
1112 	if ( getSubjectId( pX509 ) == -1 ) {
1113 		logError( TOKEN_ID_ERROR );
1114 		goto out;
1115 	}
1116 
1117 	// Now check for existing objects that may get replaced
1118 	// prior to processing the request(s)
1119 	if ( pX509 ) {
1120 		if ( checkX509Cert( hSession ) == -1 ) {
1121 			goto out;
1122 		}
1123 
1124 		// If we are not importing any RSA keys, use the
1125 		// public key from the certificate
1126 		if ( !pRsa ) {
1127 			if ( checkRsaPubKey( hSession ) == -1 ) {
1128 				goto out;
1129 			}
1130 		}
1131 
1132 		pPubRsa = EVP_PKEY_get1_RSA( X509_get_pubkey( pX509 ) );
1133 	}
1134 	if ( pRsa ) {
1135 		if ( checkRsaKey( hSession ) == -1 ) {
1136 			goto out;
1137 		}
1138 	}
1139 
1140 	// Process the request(s)
1141 	if ( pX509 ) {
1142 		if ( doX509Cert( pX509, hSession ) == -1 )
1143 			goto out;
1144 
1145 		// If we are not importing any RSA keys, use the
1146 		// public key from the certificate
1147 		if ( !pRsa ) {
1148 			if ( doRsaPubKey( pPubRsa, hSession ) == -1 )
1149 				goto out;
1150 		}
1151 	}
1152 	if ( pRsa ) {
1153 		if ( doRsaKey( pRsa, hSession ) == -1 )
1154 			goto out;
1155 	}
1156 
1157 	rc = 0;
1158 
1159 out:
1160 	shredPasswd( pszPin );
1161 
1162 	if ( hSession )
1163 		closeTokenSession( hSession );
1164 
1165 	closeToken( );
1166 
1167 	free( g_pszFile );
1168 	free( g_pszIdFile );
1169 	free( g_pszType );
1170 	X509_free( pX509 );
1171 	RSA_free( pRsa );
1172 	OPENSSL_free( g_pchSubject );
1173 	OPENSSL_free( g_pchId );
1174 	free( g_pchName );
1175 
1176 	EVP_cleanup( );
1177 
1178 	if ( rc == 0 )
1179 		logInfo( TOKEN_CMD_SUCCESS, a_pszArgv[ 0 ] );
1180 	else
1181 		logInfo( TOKEN_CMD_FAILED, a_pszArgv[ 0 ] );
1182 
1183 	return rc;
1184 }
1185