xref: /onnv-gate/usr/src/cmd/cmd-crypto/pktool/genkey.c (revision 3089:8ddeb2ace8aa)
1*3089Swyllys /*
2*3089Swyllys  * CDDL HEADER START
3*3089Swyllys  *
4*3089Swyllys  * The contents of this file are subject to the terms of the
5*3089Swyllys  * Common Development and Distribution License (the "License").
6*3089Swyllys  * You may not use this file except in compliance with the License.
7*3089Swyllys  *
8*3089Swyllys  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*3089Swyllys  * or http://www.opensolaris.org/os/licensing.
10*3089Swyllys  * See the License for the specific language governing permissions
11*3089Swyllys  * and limitations under the License.
12*3089Swyllys  *
13*3089Swyllys  * When distributing Covered Code, include this CDDL HEADER in each
14*3089Swyllys  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*3089Swyllys  * If applicable, add the following below this CDDL HEADER, with the
16*3089Swyllys  * fields enclosed by brackets "[]" replaced with your own identifying
17*3089Swyllys  * information: Portions Copyright [yyyy] [name of copyright owner]
18*3089Swyllys  *
19*3089Swyllys  * CDDL HEADER END
20*3089Swyllys  */
21*3089Swyllys /*
22*3089Swyllys  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23*3089Swyllys  * Use is subject to license terms.
24*3089Swyllys  */
25*3089Swyllys 
26*3089Swyllys #pragma ident	"%Z%%M%	%I%	%E% SMI"
27*3089Swyllys 
28*3089Swyllys #include <stdio.h>
29*3089Swyllys #include <string.h>
30*3089Swyllys #include <ctype.h>
31*3089Swyllys #include <malloc.h>
32*3089Swyllys #include <libgen.h>
33*3089Swyllys #include <errno.h>
34*3089Swyllys #include <cryptoutil.h>
35*3089Swyllys #include <security/cryptoki.h>
36*3089Swyllys #include "common.h"
37*3089Swyllys #include <kmfapi.h>
38*3089Swyllys 
39*3089Swyllys 
40*3089Swyllys static KMF_RETURN
41*3089Swyllys genkey_nss(KMF_HANDLE_T kmfhandle, char *token, char *dir, char *prefix,
42*3089Swyllys     char *keylabel, KMF_KEY_ALG keyAlg, int keylen, KMF_CREDENTIAL *tokencred)
43*3089Swyllys {
44*3089Swyllys 	KMF_RETURN kmfrv = KMF_OK;
45*3089Swyllys 	KMF_CREATESYMKEY_PARAMS csk_params;
46*3089Swyllys 	KMF_KEY_HANDLE key;
47*3089Swyllys 
48*3089Swyllys 	if (keylabel == NULL) {
49*3089Swyllys 		cryptoerror(LOG_STDERR,
50*3089Swyllys 		    gettext("A key label must be specified \n"));
51*3089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
52*3089Swyllys 	}
53*3089Swyllys 
54*3089Swyllys 	kmfrv = configure_nss(kmfhandle, dir, prefix);
55*3089Swyllys 	if (kmfrv != KMF_OK)
56*3089Swyllys 		return (kmfrv);
57*3089Swyllys 
58*3089Swyllys 	(void) memset(&key, 0, sizeof (KMF_KEY_HANDLE));
59*3089Swyllys 	csk_params.kstype = KMF_KEYSTORE_NSS;
60*3089Swyllys 	csk_params.nssparms.slotlabel = token;
61*3089Swyllys 	csk_params.keytype = keyAlg;
62*3089Swyllys 	csk_params.keylength = keylen;
63*3089Swyllys 	csk_params.keylabel = keylabel;
64*3089Swyllys 	csk_params.cred.cred = tokencred->cred;
65*3089Swyllys 	csk_params.cred.credlen = tokencred->credlen;
66*3089Swyllys 	kmfrv = KMF_CreateSymKey(kmfhandle, &csk_params, &key);
67*3089Swyllys 
68*3089Swyllys 	return (kmfrv);
69*3089Swyllys }
70*3089Swyllys 
71*3089Swyllys static KMF_RETURN
72*3089Swyllys genkey_pkcs11(KMF_HANDLE_T kmfhandle, char *token,
73*3089Swyllys 	char *keylabel, KMF_KEY_ALG keyAlg, int keylen,
74*3089Swyllys 	char *senstr, char *extstr, boolean_t print_hex,
75*3089Swyllys 	KMF_CREDENTIAL *tokencred)
76*3089Swyllys {
77*3089Swyllys 	KMF_RETURN kmfrv = KMF_OK;
78*3089Swyllys 	KMF_CREATESYMKEY_PARAMS params;
79*3089Swyllys 	KMF_KEY_HANDLE key;
80*3089Swyllys 	KMF_RAW_SYM_KEY  *rkey = NULL;
81*3089Swyllys 	boolean_t 	sensitive = B_FALSE;
82*3089Swyllys 	boolean_t	not_extractable = B_FALSE;
83*3089Swyllys 	char *hexstr = NULL;
84*3089Swyllys 	int  hexstrlen;
85*3089Swyllys 
86*3089Swyllys 	if (keylabel == NULL) {
87*3089Swyllys 		cryptoerror(LOG_STDERR,
88*3089Swyllys 		    gettext("A key label must be specified \n"));
89*3089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
90*3089Swyllys 	}
91*3089Swyllys 
92*3089Swyllys 	/* Check the sensitive option value if specified. */
93*3089Swyllys 	if (senstr != NULL) {
94*3089Swyllys 		if (tolower(senstr[0]) == 'y')
95*3089Swyllys 			sensitive = B_TRUE;
96*3089Swyllys 		else if (tolower(senstr[0]) == 'n')
97*3089Swyllys 			sensitive = B_FALSE;
98*3089Swyllys 		else {
99*3089Swyllys 			cryptoerror(LOG_STDERR,
100*3089Swyllys 			    gettext("Incorrect sensitive option value.\n"));
101*3089Swyllys 			return (KMF_ERR_BAD_PARAMETER);
102*3089Swyllys 		}
103*3089Swyllys 	}
104*3089Swyllys 
105*3089Swyllys 	/* Check the extractable option value if specified. */
106*3089Swyllys 	if (extstr != NULL) {
107*3089Swyllys 		if (tolower(extstr[0]) == 'y')
108*3089Swyllys 			not_extractable = B_FALSE;
109*3089Swyllys 		else if (tolower(extstr[0]) == 'n')
110*3089Swyllys 			not_extractable = B_TRUE;
111*3089Swyllys 		else {
112*3089Swyllys 			cryptoerror(LOG_STDERR,
113*3089Swyllys 			    gettext("Incorrect extractable option value.\n"));
114*3089Swyllys 			return (KMF_ERR_BAD_PARAMETER);
115*3089Swyllys 		}
116*3089Swyllys 	}
117*3089Swyllys 
118*3089Swyllys 	/* Select a PKCS11 token first */
119*3089Swyllys 	kmfrv = select_token(kmfhandle, token, FALSE);
120*3089Swyllys 	if (kmfrv != KMF_OK) {
121*3089Swyllys 		return (kmfrv);
122*3089Swyllys 	}
123*3089Swyllys 
124*3089Swyllys 	(void) memset(&key, 0, sizeof (KMF_KEY_HANDLE));
125*3089Swyllys 	params.kstype = KMF_KEYSTORE_PK11TOKEN;
126*3089Swyllys 	params.keytype = keyAlg;
127*3089Swyllys 	params.keylength = keylen; /* bits */
128*3089Swyllys 	params.keylabel = keylabel;
129*3089Swyllys 	params.pkcs11parms.sensitive = sensitive;
130*3089Swyllys 	params.pkcs11parms.not_extractable = not_extractable;
131*3089Swyllys 	params.cred.cred = tokencred->cred;
132*3089Swyllys 	params.cred.credlen = tokencred->credlen;
133*3089Swyllys 	kmfrv = KMF_CreateSymKey(kmfhandle, &params, &key);
134*3089Swyllys 	if (kmfrv != KMF_OK) {
135*3089Swyllys 		goto out;
136*3089Swyllys 	}
137*3089Swyllys 
138*3089Swyllys 	if (print_hex) {
139*3089Swyllys 		if (sensitive == B_TRUE || not_extractable == B_TRUE) {
140*3089Swyllys 			cryptoerror(LOG_STDERR,
141*3089Swyllys 			    gettext("Warning: can not reveal the key value "
142*3089Swyllys 			    "for a sensitive or non-extractable key.\n"));
143*3089Swyllys 			goto out;
144*3089Swyllys 		} else {
145*3089Swyllys 			rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
146*3089Swyllys 			if (rkey == NULL) {
147*3089Swyllys 				kmfrv = KMF_ERR_MEMORY;
148*3089Swyllys 				goto out;
149*3089Swyllys 			}
150*3089Swyllys 			(void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
151*3089Swyllys 			kmfrv = KMF_GetSymKeyValue(kmfhandle, &key, rkey);
152*3089Swyllys 			if (kmfrv != KMF_OK) {
153*3089Swyllys 				goto out;
154*3089Swyllys 			}
155*3089Swyllys 			hexstrlen = 2 * rkey->keydata.len + 1;
156*3089Swyllys 			hexstr = malloc(hexstrlen);
157*3089Swyllys 			if (hexstr == NULL) {
158*3089Swyllys 				kmfrv = KMF_ERR_MEMORY;
159*3089Swyllys 				goto out;
160*3089Swyllys 			}
161*3089Swyllys 
162*3089Swyllys 			tohexstr(rkey->keydata.val, rkey->keydata.len, hexstr,
163*3089Swyllys 			    hexstrlen);
164*3089Swyllys 			(void) printf(gettext("\tKey Value =\"%s\"\n"), hexstr);
165*3089Swyllys 		}
166*3089Swyllys 	}
167*3089Swyllys 
168*3089Swyllys out:
169*3089Swyllys 	KMF_FreeRawSymKey(rkey);
170*3089Swyllys 
171*3089Swyllys 	if (hexstr != NULL)
172*3089Swyllys 		free(hexstr);
173*3089Swyllys 
174*3089Swyllys 	return (kmfrv);
175*3089Swyllys }
176*3089Swyllys 
177*3089Swyllys 
178*3089Swyllys static KMF_RETURN
179*3089Swyllys genkey_file(KMF_HANDLE_T kmfhandle, KMF_KEY_ALG keyAlg, int keylen, char *dir,
180*3089Swyllys     char *outkey, boolean_t print_hex)
181*3089Swyllys {
182*3089Swyllys 	KMF_RETURN kmfrv = KMF_OK;
183*3089Swyllys 	KMF_CREATESYMKEY_PARAMS csk_params;
184*3089Swyllys 	KMF_KEY_HANDLE key;
185*3089Swyllys 	KMF_RAW_SYM_KEY *rkey = NULL;
186*3089Swyllys 	char *hexstr = NULL;
187*3089Swyllys 	int hexstrlen;
188*3089Swyllys 
189*3089Swyllys 	if (EMPTYSTRING(outkey)) {
190*3089Swyllys 		cryptoerror(LOG_STDERR,
191*3089Swyllys 		    gettext("No output key file was specified for the key\n"));
192*3089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
193*3089Swyllys 	}
194*3089Swyllys 
195*3089Swyllys 	if (verify_file(outkey)) {
196*3089Swyllys 		cryptoerror(LOG_STDERR,
197*3089Swyllys 			gettext("Cannot write the indicated output "
198*3089Swyllys 				"key file (%s).\n"), outkey);
199*3089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
200*3089Swyllys 	}
201*3089Swyllys 
202*3089Swyllys 	(void) memset(&key, 0, sizeof (KMF_KEY_HANDLE));
203*3089Swyllys 	csk_params.kstype = KMF_KEYSTORE_OPENSSL;
204*3089Swyllys 	csk_params.keytype = keyAlg;
205*3089Swyllys 	csk_params.keylength = keylen;
206*3089Swyllys 	csk_params.cred.cred = NULL;
207*3089Swyllys 	csk_params.cred.credlen = 0;
208*3089Swyllys 	csk_params.sslparms.dirpath = (dir == NULL) ? "." : dir;
209*3089Swyllys 	csk_params.sslparms.keyfile = outkey;
210*3089Swyllys 
211*3089Swyllys 	kmfrv = KMF_CreateSymKey(kmfhandle, &csk_params, &key);
212*3089Swyllys 	if (kmfrv != KMF_OK) {
213*3089Swyllys 		goto out;
214*3089Swyllys 	}
215*3089Swyllys 
216*3089Swyllys 	if (print_hex) {
217*3089Swyllys 		rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
218*3089Swyllys 		if (rkey == NULL) {
219*3089Swyllys 			kmfrv = KMF_ERR_MEMORY;
220*3089Swyllys 			goto out;
221*3089Swyllys 		}
222*3089Swyllys 		(void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
223*3089Swyllys 		kmfrv = KMF_GetSymKeyValue(kmfhandle, &key, rkey);
224*3089Swyllys 		if (kmfrv != KMF_OK) {
225*3089Swyllys 			goto out;
226*3089Swyllys 		}
227*3089Swyllys 
228*3089Swyllys 		hexstrlen = 2 * rkey->keydata.len + 1;
229*3089Swyllys 		hexstr = malloc(hexstrlen);
230*3089Swyllys 		if (hexstr == NULL) {
231*3089Swyllys 			kmfrv = KMF_ERR_MEMORY;
232*3089Swyllys 			goto out;
233*3089Swyllys 		}
234*3089Swyllys 		tohexstr(rkey->keydata.val, rkey->keydata.len, hexstr,
235*3089Swyllys 		    hexstrlen);
236*3089Swyllys 		(void) printf(gettext("\tKey Value =\"%s\"\n"), hexstr);
237*3089Swyllys 	}
238*3089Swyllys 
239*3089Swyllys out:
240*3089Swyllys 	KMF_FreeRawSymKey(rkey);
241*3089Swyllys 
242*3089Swyllys 	if (hexstr != NULL)
243*3089Swyllys 		free(hexstr);
244*3089Swyllys 
245*3089Swyllys 	return (kmfrv);
246*3089Swyllys }
247*3089Swyllys 
248*3089Swyllys int
249*3089Swyllys pk_genkey(int argc, char *argv[])
250*3089Swyllys {
251*3089Swyllys 	int rv;
252*3089Swyllys 	int opt;
253*3089Swyllys 	extern int	optind_av;
254*3089Swyllys 	extern char	*optarg_av;
255*3089Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
256*3089Swyllys 	char *tokenname = NULL;
257*3089Swyllys 	char *dir = NULL;
258*3089Swyllys 	char *prefix = NULL;
259*3089Swyllys 	char *keytype = "AES";
260*3089Swyllys 	char *keylenstr = NULL;
261*3089Swyllys 	int keylen = 0;
262*3089Swyllys 	char *keylabel = NULL;
263*3089Swyllys 	char *outkey = NULL;
264*3089Swyllys 	char *senstr = NULL;
265*3089Swyllys 	char *extstr = NULL;
266*3089Swyllys 	char *printstr = NULL;
267*3089Swyllys 	KMF_HANDLE_T kmfhandle = NULL;
268*3089Swyllys 	KMF_KEY_ALG keyAlg = KMF_AES;
269*3089Swyllys 	boolean_t print_hex = B_FALSE;
270*3089Swyllys 	KMF_CREDENTIAL tokencred = {NULL, 0};
271*3089Swyllys 
272*3089Swyllys 	while ((opt = getopt_av(argc, argv,
273*3089Swyllys 		"k:(keystore)l:(label)T:(token)d:(dir)p:(prefix)"
274*3089Swyllys 		"t:(keytype)y:(keylen)K:(outkey)P:(print)"
275*3089Swyllys 		"s:(sensitive)e:(extractable)")) != EOF) {
276*3089Swyllys 		if (EMPTYSTRING(optarg_av))
277*3089Swyllys 			return (PK_ERR_USAGE);
278*3089Swyllys 		switch (opt) {
279*3089Swyllys 			case 'k':
280*3089Swyllys 				kstype = KS2Int(optarg_av);
281*3089Swyllys 				if (kstype == 0)
282*3089Swyllys 					return (PK_ERR_USAGE);
283*3089Swyllys 				break;
284*3089Swyllys 			case 'l':
285*3089Swyllys 				if (keylabel)
286*3089Swyllys 					return (PK_ERR_USAGE);
287*3089Swyllys 				keylabel = optarg_av;
288*3089Swyllys 				break;
289*3089Swyllys 			case 'T':
290*3089Swyllys 				if (tokenname)
291*3089Swyllys 					return (PK_ERR_USAGE);
292*3089Swyllys 				tokenname = optarg_av;
293*3089Swyllys 				break;
294*3089Swyllys 			case 'd':
295*3089Swyllys 				if (dir)
296*3089Swyllys 					return (PK_ERR_USAGE);
297*3089Swyllys 				dir = optarg_av;
298*3089Swyllys 				break;
299*3089Swyllys 			case 'p':
300*3089Swyllys 				if (prefix)
301*3089Swyllys 					return (PK_ERR_USAGE);
302*3089Swyllys 				prefix = optarg_av;
303*3089Swyllys 				break;
304*3089Swyllys 			case 't':
305*3089Swyllys 				keytype = optarg_av;
306*3089Swyllys 				break;
307*3089Swyllys 			case 'y':
308*3089Swyllys 				if (keylenstr)
309*3089Swyllys 					return (PK_ERR_USAGE);
310*3089Swyllys 				keylenstr = optarg_av;
311*3089Swyllys 				break;
312*3089Swyllys 			case 'K':
313*3089Swyllys 				if (outkey)
314*3089Swyllys 					return (PK_ERR_USAGE);
315*3089Swyllys 				outkey = optarg_av;
316*3089Swyllys 				break;
317*3089Swyllys 			case 'P':
318*3089Swyllys 				if (printstr)
319*3089Swyllys 					return (PK_ERR_USAGE);
320*3089Swyllys 				printstr = optarg_av;
321*3089Swyllys 				break;
322*3089Swyllys 			case 's':
323*3089Swyllys 				if (senstr)
324*3089Swyllys 					return (PK_ERR_USAGE);
325*3089Swyllys 				senstr = optarg_av;
326*3089Swyllys 				break;
327*3089Swyllys 			case 'e':
328*3089Swyllys 				if (extstr)
329*3089Swyllys 					return (PK_ERR_USAGE);
330*3089Swyllys 				extstr = optarg_av;
331*3089Swyllys 				break;
332*3089Swyllys 			default:
333*3089Swyllys 				return (PK_ERR_USAGE);
334*3089Swyllys 		}
335*3089Swyllys 	}
336*3089Swyllys 
337*3089Swyllys 	/* No additional args allowed. */
338*3089Swyllys 	argc -= optind_av;
339*3089Swyllys 	argv += optind_av;
340*3089Swyllys 	if (argc) {
341*3089Swyllys 		return (PK_ERR_USAGE);
342*3089Swyllys 	}
343*3089Swyllys 
344*3089Swyllys 	/* Check keytype. If not specified, default to AES */
345*3089Swyllys 	if (keytype != NULL && Str2SymKeyType(keytype, &keyAlg) != 0) {
346*3089Swyllys 		cryptoerror(LOG_STDERR, gettext("Unrecognized keytype(%s).\n"),
347*3089Swyllys 			keytype);
348*3089Swyllys 		return (PK_ERR_USAGE);
349*3089Swyllys 	}
350*3089Swyllys 
351*3089Swyllys 	/*
352*3089Swyllys 	 * Check and set the key length.
353*3089Swyllys 	 * - For DES and 3DES, the key size are fixed. Ingore the keylen
354*3089Swyllys 	 *   option, even if it is specified.
355*3089Swyllys 	 * - For AES and ARCFOUR, if keylen is not specified, default to
356*3089Swyllys 	 *   128 bits.
357*3089Swyllys 	 */
358*3089Swyllys 	if (keyAlg == KMF_DES)
359*3089Swyllys 		keylen = 64;  /* fixed size; ignore input */
360*3089Swyllys 	else if (keyAlg == KMF_DES3)
361*3089Swyllys 		keylen = 192; /* fixed size; ignore input */
362*3089Swyllys 	else /* AES or ARCFOUR */ {
363*3089Swyllys 		if (keylenstr == NULL) {
364*3089Swyllys 			cryptoerror(LOG_STDERR,
365*3089Swyllys 				gettext("Key length must be specified "
366*3089Swyllys 				"for AES and ARCFOUR symmetric keys.\n"));
367*3089Swyllys 			return (PK_ERR_USAGE);
368*3089Swyllys 		}
369*3089Swyllys 		if (sscanf(keylenstr, "%d", &keylen) != 1) {
370*3089Swyllys 			cryptoerror(LOG_STDERR,
371*3089Swyllys 				gettext("Unrecognized key length (%s).\n"),
372*3089Swyllys 				keytype);
373*3089Swyllys 			return (PK_ERR_USAGE);
374*3089Swyllys 		}
375*3089Swyllys 		if (keylen == 0 || (keylen % 8) != 0) {
376*3089Swyllys 			cryptoerror(LOG_STDERR,
377*3089Swyllys 				gettext("Key length bitlength must be a "
378*3089Swyllys 					"multiple of 8.\n"));
379*3089Swyllys 			return (PK_ERR_USAGE);
380*3089Swyllys 		}
381*3089Swyllys 	}
382*3089Swyllys 
383*3089Swyllys 	/* check the print option */
384*3089Swyllys 	if (printstr != NULL) {
385*3089Swyllys 		if (kstype == KMF_KEYSTORE_NSS) {
386*3089Swyllys 			cryptoerror(LOG_STDERR,
387*3089Swyllys 			    gettext("The print option does not apply "
388*3089Swyllys 			    "to the NSS keystore.\n"));
389*3089Swyllys 			return (PK_ERR_USAGE);
390*3089Swyllys 		}
391*3089Swyllys 
392*3089Swyllys 		if (tolower(printstr[0]) == 'y')
393*3089Swyllys 			print_hex = B_TRUE;
394*3089Swyllys 		else if (tolower(printstr[0]) == 'n')
395*3089Swyllys 			print_hex = B_FALSE;
396*3089Swyllys 		else {
397*3089Swyllys 			cryptoerror(LOG_STDERR,
398*3089Swyllys 			    gettext("Incorrect print option value.\n"));
399*3089Swyllys 			return (PK_ERR_USAGE);
400*3089Swyllys 		}
401*3089Swyllys 	}
402*3089Swyllys 
403*3089Swyllys 	/* check the sensitive and extractable options */
404*3089Swyllys 	if ((senstr != NULL || extstr != NULL) &&
405*3089Swyllys 	    (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_OPENSSL)) {
406*3089Swyllys 		cryptoerror(LOG_STDERR,
407*3089Swyllys 		    gettext("The sensitive or extractable option applies "
408*3089Swyllys 		    "to the PKCS11 keystore only.\n"));
409*3089Swyllys 		return (PK_ERR_USAGE);
410*3089Swyllys 	}
411*3089Swyllys 
412*3089Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN && tokenname == NULL) {
413*3089Swyllys 		tokenname = PK_DEFAULT_PK11TOKEN;
414*3089Swyllys 	} else if (kstype == KMF_KEYSTORE_NSS && tokenname == NULL) {
415*3089Swyllys 		tokenname = DEFAULT_NSS_TOKEN;
416*3089Swyllys 	}
417*3089Swyllys 
418*3089Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS)
419*3089Swyllys 		(void) get_token_password(kstype, tokenname, &tokencred);
420*3089Swyllys 
421*3089Swyllys 	if ((rv = KMF_Initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
422*3089Swyllys 		cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n"));
423*3089Swyllys 		goto end;
424*3089Swyllys 	}
425*3089Swyllys 
426*3089Swyllys 	if (kstype == KMF_KEYSTORE_NSS) {
427*3089Swyllys 		rv = genkey_nss(kmfhandle, tokenname, dir, prefix,
428*3089Swyllys 		    keylabel, keyAlg, keylen, &tokencred);
429*3089Swyllys 	} else if (kstype == KMF_KEYSTORE_OPENSSL) {
430*3089Swyllys 		rv = genkey_file(kmfhandle, keyAlg, keylen, dir, outkey,
431*3089Swyllys 		    print_hex);
432*3089Swyllys 	} else {
433*3089Swyllys 		rv = genkey_pkcs11(kmfhandle, tokenname, keylabel, keyAlg,
434*3089Swyllys 		    keylen, senstr, extstr, print_hex, &tokencred);
435*3089Swyllys 	}
436*3089Swyllys 
437*3089Swyllys end:
438*3089Swyllys 	if (rv != KMF_OK)
439*3089Swyllys 		display_error(kmfhandle, rv,
440*3089Swyllys 			gettext("Error generating key"));
441*3089Swyllys 
442*3089Swyllys 	if (tokencred.cred != NULL)
443*3089Swyllys 		free(tokencred.cred);
444*3089Swyllys 
445*3089Swyllys 	(void) KMF_Finalize(kmfhandle);
446*3089Swyllys 	if (rv != KMF_OK)
447*3089Swyllys 		return (PK_ERR_USAGE);
448*3089Swyllys 
449*3089Swyllys 	return (0);
450*3089Swyllys }
451