xref: /titanic_50/usr/src/cmd/cmd-crypto/pktool/genkey.c (revision c197cb9db36685d2808c057fdbe5700734483ab2)
199ebb4caSwyllys /*
299ebb4caSwyllys  * CDDL HEADER START
399ebb4caSwyllys  *
499ebb4caSwyllys  * The contents of this file are subject to the terms of the
599ebb4caSwyllys  * Common Development and Distribution License (the "License").
699ebb4caSwyllys  * You may not use this file except in compliance with the License.
799ebb4caSwyllys  *
899ebb4caSwyllys  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
999ebb4caSwyllys  * or http://www.opensolaris.org/os/licensing.
1099ebb4caSwyllys  * See the License for the specific language governing permissions
1199ebb4caSwyllys  * and limitations under the License.
1299ebb4caSwyllys  *
1399ebb4caSwyllys  * When distributing Covered Code, include this CDDL HEADER in each
1499ebb4caSwyllys  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1599ebb4caSwyllys  * If applicable, add the following below this CDDL HEADER, with the
1699ebb4caSwyllys  * fields enclosed by brackets "[]" replaced with your own identifying
1799ebb4caSwyllys  * information: Portions Copyright [yyyy] [name of copyright owner]
1899ebb4caSwyllys  *
1999ebb4caSwyllys  * CDDL HEADER END
2099ebb4caSwyllys  */
2199ebb4caSwyllys /*
22*c197cb9dShylee  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
2399ebb4caSwyllys  * Use is subject to license terms.
2499ebb4caSwyllys  */
2599ebb4caSwyllys 
2699ebb4caSwyllys #pragma ident	"%Z%%M%	%I%	%E% SMI"
2799ebb4caSwyllys 
2899ebb4caSwyllys #include <stdio.h>
2999ebb4caSwyllys #include <string.h>
3099ebb4caSwyllys #include <ctype.h>
3199ebb4caSwyllys #include <malloc.h>
3299ebb4caSwyllys #include <libgen.h>
3399ebb4caSwyllys #include <errno.h>
3499ebb4caSwyllys #include <cryptoutil.h>
3599ebb4caSwyllys #include <security/cryptoki.h>
3699ebb4caSwyllys #include "common.h"
3799ebb4caSwyllys #include <kmfapi.h>
3899ebb4caSwyllys 
3999ebb4caSwyllys 
4099ebb4caSwyllys static KMF_RETURN
4199ebb4caSwyllys genkey_nss(KMF_HANDLE_T kmfhandle, char *token, char *dir, char *prefix,
4299ebb4caSwyllys     char *keylabel, KMF_KEY_ALG keyAlg, int keylen, KMF_CREDENTIAL *tokencred)
4399ebb4caSwyllys {
4499ebb4caSwyllys 	KMF_RETURN kmfrv = KMF_OK;
4599ebb4caSwyllys 	KMF_CREATESYMKEY_PARAMS csk_params;
4699ebb4caSwyllys 	KMF_KEY_HANDLE key;
4799ebb4caSwyllys 
4899ebb4caSwyllys 	if (keylabel == NULL) {
4999ebb4caSwyllys 		cryptoerror(LOG_STDERR,
5099ebb4caSwyllys 		    gettext("A key label must be specified \n"));
5199ebb4caSwyllys 		return (KMF_ERR_BAD_PARAMETER);
5299ebb4caSwyllys 	}
5399ebb4caSwyllys 
5499ebb4caSwyllys 	kmfrv = configure_nss(kmfhandle, dir, prefix);
5599ebb4caSwyllys 	if (kmfrv != KMF_OK)
5699ebb4caSwyllys 		return (kmfrv);
5799ebb4caSwyllys 
5899ebb4caSwyllys 	(void) memset(&key, 0, sizeof (KMF_KEY_HANDLE));
5999ebb4caSwyllys 	csk_params.kstype = KMF_KEYSTORE_NSS;
6099ebb4caSwyllys 	csk_params.nssparms.slotlabel = token;
6199ebb4caSwyllys 	csk_params.keytype = keyAlg;
6299ebb4caSwyllys 	csk_params.keylength = keylen;
6399ebb4caSwyllys 	csk_params.keylabel = keylabel;
6499ebb4caSwyllys 	csk_params.cred.cred = tokencred->cred;
6599ebb4caSwyllys 	csk_params.cred.credlen = tokencred->credlen;
6699ebb4caSwyllys 	kmfrv = KMF_CreateSymKey(kmfhandle, &csk_params, &key);
6799ebb4caSwyllys 
6899ebb4caSwyllys 	return (kmfrv);
6999ebb4caSwyllys }
7099ebb4caSwyllys 
7199ebb4caSwyllys static KMF_RETURN
7299ebb4caSwyllys genkey_pkcs11(KMF_HANDLE_T kmfhandle, char *token,
7399ebb4caSwyllys 	char *keylabel, KMF_KEY_ALG keyAlg, int keylen,
7499ebb4caSwyllys 	char *senstr, char *extstr, boolean_t print_hex,
7599ebb4caSwyllys 	KMF_CREDENTIAL *tokencred)
7699ebb4caSwyllys {
7799ebb4caSwyllys 	KMF_RETURN kmfrv = KMF_OK;
7899ebb4caSwyllys 	KMF_CREATESYMKEY_PARAMS params;
7999ebb4caSwyllys 	KMF_KEY_HANDLE key;
8099ebb4caSwyllys 	KMF_RAW_SYM_KEY  *rkey = NULL;
8199ebb4caSwyllys 	boolean_t 	sensitive = B_FALSE;
8299ebb4caSwyllys 	boolean_t	not_extractable = B_FALSE;
8399ebb4caSwyllys 	char *hexstr = NULL;
8499ebb4caSwyllys 	int  hexstrlen;
8599ebb4caSwyllys 
8699ebb4caSwyllys 	if (keylabel == NULL) {
8799ebb4caSwyllys 		cryptoerror(LOG_STDERR,
8899ebb4caSwyllys 		    gettext("A key label must be specified \n"));
8999ebb4caSwyllys 		return (KMF_ERR_BAD_PARAMETER);
9099ebb4caSwyllys 	}
9199ebb4caSwyllys 
9299ebb4caSwyllys 	/* Check the sensitive option value if specified. */
9399ebb4caSwyllys 	if (senstr != NULL) {
9499ebb4caSwyllys 		if (tolower(senstr[0]) == 'y')
9599ebb4caSwyllys 			sensitive = B_TRUE;
9699ebb4caSwyllys 		else if (tolower(senstr[0]) == 'n')
9799ebb4caSwyllys 			sensitive = B_FALSE;
9899ebb4caSwyllys 		else {
9999ebb4caSwyllys 			cryptoerror(LOG_STDERR,
10099ebb4caSwyllys 			    gettext("Incorrect sensitive option value.\n"));
10199ebb4caSwyllys 			return (KMF_ERR_BAD_PARAMETER);
10299ebb4caSwyllys 		}
10399ebb4caSwyllys 	}
10499ebb4caSwyllys 
10599ebb4caSwyllys 	/* Check the extractable option value if specified. */
10699ebb4caSwyllys 	if (extstr != NULL) {
10799ebb4caSwyllys 		if (tolower(extstr[0]) == 'y')
10899ebb4caSwyllys 			not_extractable = B_FALSE;
10999ebb4caSwyllys 		else if (tolower(extstr[0]) == 'n')
11099ebb4caSwyllys 			not_extractable = B_TRUE;
11199ebb4caSwyllys 		else {
11299ebb4caSwyllys 			cryptoerror(LOG_STDERR,
11399ebb4caSwyllys 			    gettext("Incorrect extractable option value.\n"));
11499ebb4caSwyllys 			return (KMF_ERR_BAD_PARAMETER);
11599ebb4caSwyllys 		}
11699ebb4caSwyllys 	}
11799ebb4caSwyllys 
11899ebb4caSwyllys 	/* Select a PKCS11 token first */
11999ebb4caSwyllys 	kmfrv = select_token(kmfhandle, token, FALSE);
12099ebb4caSwyllys 	if (kmfrv != KMF_OK) {
12199ebb4caSwyllys 		return (kmfrv);
12299ebb4caSwyllys 	}
12399ebb4caSwyllys 
12499ebb4caSwyllys 	(void) memset(&key, 0, sizeof (KMF_KEY_HANDLE));
12599ebb4caSwyllys 	params.kstype = KMF_KEYSTORE_PK11TOKEN;
12699ebb4caSwyllys 	params.keytype = keyAlg;
12799ebb4caSwyllys 	params.keylength = keylen; /* bits */
12899ebb4caSwyllys 	params.keylabel = keylabel;
12999ebb4caSwyllys 	params.pkcs11parms.sensitive = sensitive;
13099ebb4caSwyllys 	params.pkcs11parms.not_extractable = not_extractable;
13199ebb4caSwyllys 	params.cred.cred = tokencred->cred;
13299ebb4caSwyllys 	params.cred.credlen = tokencred->credlen;
13399ebb4caSwyllys 	kmfrv = KMF_CreateSymKey(kmfhandle, &params, &key);
13499ebb4caSwyllys 	if (kmfrv != KMF_OK) {
13599ebb4caSwyllys 		goto out;
13699ebb4caSwyllys 	}
13799ebb4caSwyllys 
13899ebb4caSwyllys 	if (print_hex) {
13999ebb4caSwyllys 		if (sensitive == B_TRUE || not_extractable == B_TRUE) {
14099ebb4caSwyllys 			cryptoerror(LOG_STDERR,
14199ebb4caSwyllys 			    gettext("Warning: can not reveal the key value "
14299ebb4caSwyllys 			    "for a sensitive or non-extractable key.\n"));
14399ebb4caSwyllys 			goto out;
14499ebb4caSwyllys 		} else {
14599ebb4caSwyllys 			rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
14699ebb4caSwyllys 			if (rkey == NULL) {
14799ebb4caSwyllys 				kmfrv = KMF_ERR_MEMORY;
14899ebb4caSwyllys 				goto out;
14999ebb4caSwyllys 			}
15099ebb4caSwyllys 			(void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
15199ebb4caSwyllys 			kmfrv = KMF_GetSymKeyValue(kmfhandle, &key, rkey);
15299ebb4caSwyllys 			if (kmfrv != KMF_OK) {
15399ebb4caSwyllys 				goto out;
15499ebb4caSwyllys 			}
15599ebb4caSwyllys 			hexstrlen = 2 * rkey->keydata.len + 1;
15699ebb4caSwyllys 			hexstr = malloc(hexstrlen);
15799ebb4caSwyllys 			if (hexstr == NULL) {
15899ebb4caSwyllys 				kmfrv = KMF_ERR_MEMORY;
15999ebb4caSwyllys 				goto out;
16099ebb4caSwyllys 			}
16199ebb4caSwyllys 
16299ebb4caSwyllys 			tohexstr(rkey->keydata.val, rkey->keydata.len, hexstr,
16399ebb4caSwyllys 			    hexstrlen);
16499ebb4caSwyllys 			(void) printf(gettext("\tKey Value =\"%s\"\n"), hexstr);
16599ebb4caSwyllys 		}
16699ebb4caSwyllys 	}
16799ebb4caSwyllys 
16899ebb4caSwyllys out:
16999ebb4caSwyllys 	KMF_FreeRawSymKey(rkey);
17099ebb4caSwyllys 
17199ebb4caSwyllys 	if (hexstr != NULL)
17299ebb4caSwyllys 		free(hexstr);
17399ebb4caSwyllys 
17499ebb4caSwyllys 	return (kmfrv);
17599ebb4caSwyllys }
17699ebb4caSwyllys 
17799ebb4caSwyllys 
17899ebb4caSwyllys static KMF_RETURN
17999ebb4caSwyllys genkey_file(KMF_HANDLE_T kmfhandle, KMF_KEY_ALG keyAlg, int keylen, char *dir,
18099ebb4caSwyllys     char *outkey, boolean_t print_hex)
18199ebb4caSwyllys {
18299ebb4caSwyllys 	KMF_RETURN kmfrv = KMF_OK;
18399ebb4caSwyllys 	KMF_CREATESYMKEY_PARAMS csk_params;
18499ebb4caSwyllys 	KMF_KEY_HANDLE key;
18599ebb4caSwyllys 	KMF_RAW_SYM_KEY *rkey = NULL;
18699ebb4caSwyllys 	char *hexstr = NULL;
18799ebb4caSwyllys 	int hexstrlen;
18899ebb4caSwyllys 
18999ebb4caSwyllys 	if (EMPTYSTRING(outkey)) {
19099ebb4caSwyllys 		cryptoerror(LOG_STDERR,
19199ebb4caSwyllys 		    gettext("No output key file was specified for the key\n"));
19299ebb4caSwyllys 		return (KMF_ERR_BAD_PARAMETER);
19399ebb4caSwyllys 	}
19499ebb4caSwyllys 
19599ebb4caSwyllys 	if (verify_file(outkey)) {
19699ebb4caSwyllys 		cryptoerror(LOG_STDERR,
19799ebb4caSwyllys 			gettext("Cannot write the indicated output "
19899ebb4caSwyllys 				"key file (%s).\n"), outkey);
19999ebb4caSwyllys 		return (KMF_ERR_BAD_PARAMETER);
20099ebb4caSwyllys 	}
20199ebb4caSwyllys 
20299ebb4caSwyllys 	(void) memset(&key, 0, sizeof (KMF_KEY_HANDLE));
20399ebb4caSwyllys 	csk_params.kstype = KMF_KEYSTORE_OPENSSL;
20499ebb4caSwyllys 	csk_params.keytype = keyAlg;
20599ebb4caSwyllys 	csk_params.keylength = keylen;
20699ebb4caSwyllys 	csk_params.cred.cred = NULL;
20799ebb4caSwyllys 	csk_params.cred.credlen = 0;
20899ebb4caSwyllys 	csk_params.sslparms.dirpath = (dir == NULL) ? "." : dir;
20999ebb4caSwyllys 	csk_params.sslparms.keyfile = outkey;
21099ebb4caSwyllys 
21199ebb4caSwyllys 	kmfrv = KMF_CreateSymKey(kmfhandle, &csk_params, &key);
21299ebb4caSwyllys 	if (kmfrv != KMF_OK) {
21399ebb4caSwyllys 		goto out;
21499ebb4caSwyllys 	}
21599ebb4caSwyllys 
21699ebb4caSwyllys 	if (print_hex) {
21799ebb4caSwyllys 		rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
21899ebb4caSwyllys 		if (rkey == NULL) {
21999ebb4caSwyllys 			kmfrv = KMF_ERR_MEMORY;
22099ebb4caSwyllys 			goto out;
22199ebb4caSwyllys 		}
22299ebb4caSwyllys 		(void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
22399ebb4caSwyllys 		kmfrv = KMF_GetSymKeyValue(kmfhandle, &key, rkey);
22499ebb4caSwyllys 		if (kmfrv != KMF_OK) {
22599ebb4caSwyllys 			goto out;
22699ebb4caSwyllys 		}
22799ebb4caSwyllys 
22899ebb4caSwyllys 		hexstrlen = 2 * rkey->keydata.len + 1;
22999ebb4caSwyllys 		hexstr = malloc(hexstrlen);
23099ebb4caSwyllys 		if (hexstr == NULL) {
23199ebb4caSwyllys 			kmfrv = KMF_ERR_MEMORY;
23299ebb4caSwyllys 			goto out;
23399ebb4caSwyllys 		}
23499ebb4caSwyllys 		tohexstr(rkey->keydata.val, rkey->keydata.len, hexstr,
23599ebb4caSwyllys 		    hexstrlen);
23699ebb4caSwyllys 		(void) printf(gettext("\tKey Value =\"%s\"\n"), hexstr);
23799ebb4caSwyllys 	}
23899ebb4caSwyllys 
23999ebb4caSwyllys out:
24099ebb4caSwyllys 	KMF_FreeRawSymKey(rkey);
24199ebb4caSwyllys 
24299ebb4caSwyllys 	if (hexstr != NULL)
24399ebb4caSwyllys 		free(hexstr);
24499ebb4caSwyllys 
24599ebb4caSwyllys 	return (kmfrv);
24699ebb4caSwyllys }
24799ebb4caSwyllys 
24899ebb4caSwyllys int
24999ebb4caSwyllys pk_genkey(int argc, char *argv[])
25099ebb4caSwyllys {
25199ebb4caSwyllys 	int rv;
25299ebb4caSwyllys 	int opt;
25399ebb4caSwyllys 	extern int	optind_av;
25499ebb4caSwyllys 	extern char	*optarg_av;
25599ebb4caSwyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
25699ebb4caSwyllys 	char *tokenname = NULL;
25799ebb4caSwyllys 	char *dir = NULL;
25899ebb4caSwyllys 	char *prefix = NULL;
25999ebb4caSwyllys 	char *keytype = "AES";
26099ebb4caSwyllys 	char *keylenstr = NULL;
26199ebb4caSwyllys 	int keylen = 0;
26299ebb4caSwyllys 	char *keylabel = NULL;
26399ebb4caSwyllys 	char *outkey = NULL;
26499ebb4caSwyllys 	char *senstr = NULL;
26599ebb4caSwyllys 	char *extstr = NULL;
26699ebb4caSwyllys 	char *printstr = NULL;
26799ebb4caSwyllys 	KMF_HANDLE_T kmfhandle = NULL;
26899ebb4caSwyllys 	KMF_KEY_ALG keyAlg = KMF_AES;
26999ebb4caSwyllys 	boolean_t print_hex = B_FALSE;
27099ebb4caSwyllys 	KMF_CREDENTIAL tokencred = {NULL, 0};
27199ebb4caSwyllys 
27299ebb4caSwyllys 	while ((opt = getopt_av(argc, argv,
27399ebb4caSwyllys 		"k:(keystore)l:(label)T:(token)d:(dir)p:(prefix)"
27499ebb4caSwyllys 		"t:(keytype)y:(keylen)K:(outkey)P:(print)"
27599ebb4caSwyllys 		"s:(sensitive)e:(extractable)")) != EOF) {
27699ebb4caSwyllys 		if (EMPTYSTRING(optarg_av))
27799ebb4caSwyllys 			return (PK_ERR_USAGE);
27899ebb4caSwyllys 		switch (opt) {
27999ebb4caSwyllys 			case 'k':
28099ebb4caSwyllys 				kstype = KS2Int(optarg_av);
28199ebb4caSwyllys 				if (kstype == 0)
28299ebb4caSwyllys 					return (PK_ERR_USAGE);
28399ebb4caSwyllys 				break;
28499ebb4caSwyllys 			case 'l':
28599ebb4caSwyllys 				if (keylabel)
28699ebb4caSwyllys 					return (PK_ERR_USAGE);
28799ebb4caSwyllys 				keylabel = optarg_av;
28899ebb4caSwyllys 				break;
28999ebb4caSwyllys 			case 'T':
29099ebb4caSwyllys 				if (tokenname)
29199ebb4caSwyllys 					return (PK_ERR_USAGE);
29299ebb4caSwyllys 				tokenname = optarg_av;
29399ebb4caSwyllys 				break;
29499ebb4caSwyllys 			case 'd':
29599ebb4caSwyllys 				if (dir)
29699ebb4caSwyllys 					return (PK_ERR_USAGE);
29799ebb4caSwyllys 				dir = optarg_av;
29899ebb4caSwyllys 				break;
29999ebb4caSwyllys 			case 'p':
30099ebb4caSwyllys 				if (prefix)
30199ebb4caSwyllys 					return (PK_ERR_USAGE);
30299ebb4caSwyllys 				prefix = optarg_av;
30399ebb4caSwyllys 				break;
30499ebb4caSwyllys 			case 't':
30599ebb4caSwyllys 				keytype = optarg_av;
30699ebb4caSwyllys 				break;
30799ebb4caSwyllys 			case 'y':
30899ebb4caSwyllys 				if (keylenstr)
30999ebb4caSwyllys 					return (PK_ERR_USAGE);
31099ebb4caSwyllys 				keylenstr = optarg_av;
31199ebb4caSwyllys 				break;
31299ebb4caSwyllys 			case 'K':
31399ebb4caSwyllys 				if (outkey)
31499ebb4caSwyllys 					return (PK_ERR_USAGE);
31599ebb4caSwyllys 				outkey = optarg_av;
31699ebb4caSwyllys 				break;
31799ebb4caSwyllys 			case 'P':
31899ebb4caSwyllys 				if (printstr)
31999ebb4caSwyllys 					return (PK_ERR_USAGE);
32099ebb4caSwyllys 				printstr = optarg_av;
32199ebb4caSwyllys 				break;
32299ebb4caSwyllys 			case 's':
32399ebb4caSwyllys 				if (senstr)
32499ebb4caSwyllys 					return (PK_ERR_USAGE);
32599ebb4caSwyllys 				senstr = optarg_av;
32699ebb4caSwyllys 				break;
32799ebb4caSwyllys 			case 'e':
32899ebb4caSwyllys 				if (extstr)
32999ebb4caSwyllys 					return (PK_ERR_USAGE);
33099ebb4caSwyllys 				extstr = optarg_av;
33199ebb4caSwyllys 				break;
33299ebb4caSwyllys 			default:
33399ebb4caSwyllys 				return (PK_ERR_USAGE);
33499ebb4caSwyllys 		}
33599ebb4caSwyllys 	}
33699ebb4caSwyllys 
33799ebb4caSwyllys 	/* No additional args allowed. */
33899ebb4caSwyllys 	argc -= optind_av;
33999ebb4caSwyllys 	argv += optind_av;
34099ebb4caSwyllys 	if (argc) {
34199ebb4caSwyllys 		return (PK_ERR_USAGE);
34299ebb4caSwyllys 	}
34399ebb4caSwyllys 
34499ebb4caSwyllys 	/* Check keytype. If not specified, default to AES */
34599ebb4caSwyllys 	if (keytype != NULL && Str2SymKeyType(keytype, &keyAlg) != 0) {
34699ebb4caSwyllys 		cryptoerror(LOG_STDERR, gettext("Unrecognized keytype(%s).\n"),
34799ebb4caSwyllys 			keytype);
34899ebb4caSwyllys 		return (PK_ERR_USAGE);
34999ebb4caSwyllys 	}
35099ebb4caSwyllys 
35199ebb4caSwyllys 	/*
35299ebb4caSwyllys 	 * Check and set the key length.
35399ebb4caSwyllys 	 * - For DES and 3DES, the key size are fixed. Ingore the keylen
35499ebb4caSwyllys 	 *   option, even if it is specified.
35599ebb4caSwyllys 	 * - For AES and ARCFOUR, if keylen is not specified, default to
35699ebb4caSwyllys 	 *   128 bits.
35799ebb4caSwyllys 	 */
35899ebb4caSwyllys 	if (keyAlg == KMF_DES)
35999ebb4caSwyllys 		keylen = 64;  /* fixed size; ignore input */
36099ebb4caSwyllys 	else if (keyAlg == KMF_DES3)
36199ebb4caSwyllys 		keylen = 192; /* fixed size; ignore input */
362*c197cb9dShylee 	else /* AES, ARCFOUR, or GENERIC SECRET */ {
36399ebb4caSwyllys 		if (keylenstr == NULL) {
36499ebb4caSwyllys 			cryptoerror(LOG_STDERR,
365*c197cb9dShylee 				gettext("Key length must be specified for "
366*c197cb9dShylee 				"AES, ARCFOUR or GENERIC symmetric keys.\n"));
36799ebb4caSwyllys 			return (PK_ERR_USAGE);
36899ebb4caSwyllys 		}
36999ebb4caSwyllys 		if (sscanf(keylenstr, "%d", &keylen) != 1) {
37099ebb4caSwyllys 			cryptoerror(LOG_STDERR,
37199ebb4caSwyllys 				gettext("Unrecognized key length (%s).\n"),
37299ebb4caSwyllys 				keytype);
37399ebb4caSwyllys 			return (PK_ERR_USAGE);
37499ebb4caSwyllys 		}
37599ebb4caSwyllys 		if (keylen == 0 || (keylen % 8) != 0) {
37699ebb4caSwyllys 			cryptoerror(LOG_STDERR,
37799ebb4caSwyllys 				gettext("Key length bitlength must be a "
37899ebb4caSwyllys 					"multiple of 8.\n"));
37999ebb4caSwyllys 			return (PK_ERR_USAGE);
38099ebb4caSwyllys 		}
38199ebb4caSwyllys 	}
38299ebb4caSwyllys 
38399ebb4caSwyllys 	/* check the print option */
38499ebb4caSwyllys 	if (printstr != NULL) {
38599ebb4caSwyllys 		if (kstype == KMF_KEYSTORE_NSS) {
38699ebb4caSwyllys 			cryptoerror(LOG_STDERR,
38799ebb4caSwyllys 			    gettext("The print option does not apply "
38899ebb4caSwyllys 			    "to the NSS keystore.\n"));
38999ebb4caSwyllys 			return (PK_ERR_USAGE);
39099ebb4caSwyllys 		}
39199ebb4caSwyllys 
39299ebb4caSwyllys 		if (tolower(printstr[0]) == 'y')
39399ebb4caSwyllys 			print_hex = B_TRUE;
39499ebb4caSwyllys 		else if (tolower(printstr[0]) == 'n')
39599ebb4caSwyllys 			print_hex = B_FALSE;
39699ebb4caSwyllys 		else {
39799ebb4caSwyllys 			cryptoerror(LOG_STDERR,
39899ebb4caSwyllys 			    gettext("Incorrect print option value.\n"));
39999ebb4caSwyllys 			return (PK_ERR_USAGE);
40099ebb4caSwyllys 		}
40199ebb4caSwyllys 	}
40299ebb4caSwyllys 
40399ebb4caSwyllys 	/* check the sensitive and extractable options */
40499ebb4caSwyllys 	if ((senstr != NULL || extstr != NULL) &&
40599ebb4caSwyllys 	    (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_OPENSSL)) {
40699ebb4caSwyllys 		cryptoerror(LOG_STDERR,
40799ebb4caSwyllys 		    gettext("The sensitive or extractable option applies "
40899ebb4caSwyllys 		    "to the PKCS11 keystore only.\n"));
40999ebb4caSwyllys 		return (PK_ERR_USAGE);
41099ebb4caSwyllys 	}
41199ebb4caSwyllys 
41299ebb4caSwyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN && tokenname == NULL) {
41399ebb4caSwyllys 		tokenname = PK_DEFAULT_PK11TOKEN;
41499ebb4caSwyllys 	} else if (kstype == KMF_KEYSTORE_NSS && tokenname == NULL) {
41599ebb4caSwyllys 		tokenname = DEFAULT_NSS_TOKEN;
41699ebb4caSwyllys 	}
41799ebb4caSwyllys 
41899ebb4caSwyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS)
41999ebb4caSwyllys 		(void) get_token_password(kstype, tokenname, &tokencred);
42099ebb4caSwyllys 
42199ebb4caSwyllys 	if ((rv = KMF_Initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
42299ebb4caSwyllys 		cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n"));
42399ebb4caSwyllys 		goto end;
42499ebb4caSwyllys 	}
42599ebb4caSwyllys 
42699ebb4caSwyllys 	if (kstype == KMF_KEYSTORE_NSS) {
42799ebb4caSwyllys 		rv = genkey_nss(kmfhandle, tokenname, dir, prefix,
42899ebb4caSwyllys 		    keylabel, keyAlg, keylen, &tokencred);
42999ebb4caSwyllys 	} else if (kstype == KMF_KEYSTORE_OPENSSL) {
43099ebb4caSwyllys 		rv = genkey_file(kmfhandle, keyAlg, keylen, dir, outkey,
43199ebb4caSwyllys 		    print_hex);
43299ebb4caSwyllys 	} else {
43399ebb4caSwyllys 		rv = genkey_pkcs11(kmfhandle, tokenname, keylabel, keyAlg,
43499ebb4caSwyllys 		    keylen, senstr, extstr, print_hex, &tokencred);
43599ebb4caSwyllys 	}
43699ebb4caSwyllys 
43799ebb4caSwyllys end:
43899ebb4caSwyllys 	if (rv != KMF_OK)
43999ebb4caSwyllys 		display_error(kmfhandle, rv,
44099ebb4caSwyllys 			gettext("Error generating key"));
44199ebb4caSwyllys 
44299ebb4caSwyllys 	if (tokencred.cred != NULL)
44399ebb4caSwyllys 		free(tokencred.cred);
44499ebb4caSwyllys 
44599ebb4caSwyllys 	(void) KMF_Finalize(kmfhandle);
44699ebb4caSwyllys 	if (rv != KMF_OK)
44799ebb4caSwyllys 		return (PK_ERR_USAGE);
44899ebb4caSwyllys 
44999ebb4caSwyllys 	return (0);
45099ebb4caSwyllys }
451