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