xref: /onnv-gate/usr/src/cmd/cmd-crypto/pktool/genkey.c (revision 6884:ca518f772fa0)
13089Swyllys /*
23089Swyllys  * CDDL HEADER START
33089Swyllys  *
43089Swyllys  * The contents of this file are subject to the terms of the
53089Swyllys  * Common Development and Distribution License (the "License").
63089Swyllys  * You may not use this file except in compliance with the License.
73089Swyllys  *
83089Swyllys  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93089Swyllys  * or http://www.opensolaris.org/os/licensing.
103089Swyllys  * See the License for the specific language governing permissions
113089Swyllys  * and limitations under the License.
123089Swyllys  *
133089Swyllys  * When distributing Covered Code, include this CDDL HEADER in each
143089Swyllys  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153089Swyllys  * If applicable, add the following below this CDDL HEADER, with the
163089Swyllys  * fields enclosed by brackets "[]" replaced with your own identifying
173089Swyllys  * information: Portions Copyright [yyyy] [name of copyright owner]
183089Swyllys  *
193089Swyllys  * CDDL HEADER END
203089Swyllys  */
213089Swyllys /*
226354Swyllys  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
233089Swyllys  * Use is subject to license terms.
243089Swyllys  */
253089Swyllys 
263089Swyllys #pragma ident	"%Z%%M%	%I%	%E% SMI"
273089Swyllys 
283089Swyllys #include <stdio.h>
293089Swyllys #include <string.h>
303089Swyllys #include <ctype.h>
313089Swyllys #include <malloc.h>
323089Swyllys #include <libgen.h>
333089Swyllys #include <errno.h>
343089Swyllys #include <cryptoutil.h>
353089Swyllys #include <security/cryptoki.h>
363089Swyllys #include "common.h"
373089Swyllys #include <kmfapi.h>
383089Swyllys 
393089Swyllys 
403089Swyllys static KMF_RETURN
genkey_nss(KMF_HANDLE_T kmfhandle,char * token,char * dir,char * prefix,char * keylabel,KMF_KEY_ALG keyAlg,int keylen,KMF_CREDENTIAL * tokencred)413089Swyllys genkey_nss(KMF_HANDLE_T kmfhandle, char *token, char *dir, char *prefix,
423089Swyllys     char *keylabel, KMF_KEY_ALG keyAlg, int keylen, KMF_CREDENTIAL *tokencred)
433089Swyllys {
443089Swyllys 	KMF_RETURN kmfrv = KMF_OK;
453089Swyllys 	KMF_KEY_HANDLE key;
465051Swyllys 	KMF_ATTRIBUTE attlist[20];
475051Swyllys 	int i = 0;
485051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
495051Swyllys 	KMF_KEY_ALG keytype;
505051Swyllys 	uint32_t keylength;
513089Swyllys 
523089Swyllys 	if (keylabel == NULL) {
533089Swyllys 		cryptoerror(LOG_STDERR,
543089Swyllys 		    gettext("A key label must be specified \n"));
553089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
563089Swyllys 	}
573089Swyllys 
583089Swyllys 	kmfrv = configure_nss(kmfhandle, dir, prefix);
593089Swyllys 	if (kmfrv != KMF_OK)
603089Swyllys 		return (kmfrv);
613089Swyllys 
623089Swyllys 	(void) memset(&key, 0, sizeof (KMF_KEY_HANDLE));
635051Swyllys 
645051Swyllys 	keytype = keyAlg;
655051Swyllys 	keylength = keylen;
665051Swyllys 
675051Swyllys 	kmf_set_attr_at_index(attlist, i,
685051Swyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
695051Swyllys 	i++;
705051Swyllys 
715051Swyllys 	kmf_set_attr_at_index(attlist, i,
725051Swyllys 	    KMF_KEY_HANDLE_ATTR, &key, sizeof (KMF_KEY_HANDLE));
735051Swyllys 	i++;
745051Swyllys 
755051Swyllys 	kmf_set_attr_at_index(attlist, i,
765051Swyllys 	    KMF_KEYALG_ATTR, &keytype, sizeof (keytype));
775051Swyllys 	i++;
785051Swyllys 
795051Swyllys 	kmf_set_attr_at_index(attlist, i,
805051Swyllys 	    KMF_KEYLENGTH_ATTR, &keylength, sizeof (keylength));
815051Swyllys 	i++;
825051Swyllys 
835051Swyllys 	if (keylabel != NULL) {
845051Swyllys 		kmf_set_attr_at_index(attlist, i,
855051Swyllys 		    KMF_KEYLABEL_ATTR, keylabel,
865051Swyllys 		    strlen(keylabel));
875051Swyllys 		i++;
885051Swyllys 	}
895051Swyllys 
906354Swyllys 	if (tokencred != NULL && tokencred->cred != NULL) {
915051Swyllys 		kmf_set_attr_at_index(attlist, i,
925051Swyllys 		    KMF_CREDENTIAL_ATTR, tokencred,
935051Swyllys 		    sizeof (KMF_CREDENTIAL));
945051Swyllys 		i++;
955051Swyllys 	}
965051Swyllys 
975051Swyllys 	if (token != NULL) {
985051Swyllys 		kmf_set_attr_at_index(attlist, i,
995051Swyllys 		    KMF_TOKEN_LABEL_ATTR, token,
1005051Swyllys 		    strlen(token));
1015051Swyllys 		i++;
1025051Swyllys 	}
1035051Swyllys 
1045051Swyllys 	kmfrv = kmf_create_sym_key(kmfhandle, i, attlist);
1053089Swyllys 
1063089Swyllys 	return (kmfrv);
1073089Swyllys }
1083089Swyllys 
1093089Swyllys static KMF_RETURN
genkey_pkcs11(KMF_HANDLE_T kmfhandle,char * token,char * keylabel,KMF_KEY_ALG keyAlg,int keylen,char * senstr,char * extstr,boolean_t print_hex,KMF_CREDENTIAL * tokencred)1103089Swyllys genkey_pkcs11(KMF_HANDLE_T kmfhandle, char *token,
1113089Swyllys 	char *keylabel, KMF_KEY_ALG keyAlg, int keylen,
1123089Swyllys 	char *senstr, char *extstr, boolean_t print_hex,
1133089Swyllys 	KMF_CREDENTIAL *tokencred)
1143089Swyllys {
1153089Swyllys 	KMF_RETURN kmfrv = KMF_OK;
1163089Swyllys 	KMF_KEY_HANDLE key;
1173089Swyllys 	KMF_RAW_SYM_KEY  *rkey = NULL;
1183089Swyllys 	boolean_t 	sensitive = B_FALSE;
1193089Swyllys 	boolean_t	not_extractable = B_FALSE;
1203089Swyllys 	char *hexstr = NULL;
1213089Swyllys 	int  hexstrlen;
1225051Swyllys 	KMF_ATTRIBUTE attlist[20];
1235051Swyllys 	int i = 0;
1245051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
1255051Swyllys 	KMF_KEY_ALG keytype;
1265051Swyllys 	uint32_t keylength;
1273089Swyllys 
1283089Swyllys 	if (keylabel == NULL) {
1293089Swyllys 		cryptoerror(LOG_STDERR,
1303089Swyllys 		    gettext("A key label must be specified \n"));
1313089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
1323089Swyllys 	}
1333089Swyllys 
1343089Swyllys 	/* Check the sensitive option value if specified. */
1353089Swyllys 	if (senstr != NULL) {
1363089Swyllys 		if (tolower(senstr[0]) == 'y')
1373089Swyllys 			sensitive = B_TRUE;
1383089Swyllys 		else if (tolower(senstr[0]) == 'n')
1393089Swyllys 			sensitive = B_FALSE;
1403089Swyllys 		else {
1413089Swyllys 			cryptoerror(LOG_STDERR,
1423089Swyllys 			    gettext("Incorrect sensitive option value.\n"));
1433089Swyllys 			return (KMF_ERR_BAD_PARAMETER);
1443089Swyllys 		}
1453089Swyllys 	}
1463089Swyllys 
1473089Swyllys 	/* Check the extractable option value if specified. */
1483089Swyllys 	if (extstr != NULL) {
1493089Swyllys 		if (tolower(extstr[0]) == 'y')
1503089Swyllys 			not_extractable = B_FALSE;
1513089Swyllys 		else if (tolower(extstr[0]) == 'n')
1523089Swyllys 			not_extractable = B_TRUE;
1533089Swyllys 		else {
1543089Swyllys 			cryptoerror(LOG_STDERR,
1553089Swyllys 			    gettext("Incorrect extractable option value.\n"));
1563089Swyllys 			return (KMF_ERR_BAD_PARAMETER);
1573089Swyllys 		}
1583089Swyllys 	}
1593089Swyllys 
1603089Swyllys 	/* Select a PKCS11 token first */
1613089Swyllys 	kmfrv = select_token(kmfhandle, token, FALSE);
1623089Swyllys 	if (kmfrv != KMF_OK) {
1633089Swyllys 		return (kmfrv);
1643089Swyllys 	}
1653089Swyllys 
1663089Swyllys 	(void) memset(&key, 0, sizeof (KMF_KEY_HANDLE));
1675051Swyllys 
1685051Swyllys 	keytype = keyAlg;
1695051Swyllys 	keylength = keylen; /* bits */
1705051Swyllys 
1715051Swyllys 	kmf_set_attr_at_index(attlist, i,
1725051Swyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
1735051Swyllys 	i++;
1745051Swyllys 
1755051Swyllys 	kmf_set_attr_at_index(attlist, i,
1765051Swyllys 	    KMF_KEY_HANDLE_ATTR, &key, sizeof (KMF_KEY_HANDLE));
1775051Swyllys 	i++;
1785051Swyllys 
1795051Swyllys 	kmf_set_attr_at_index(attlist, i,
1805051Swyllys 	    KMF_KEYALG_ATTR, &keytype, sizeof (keytype));
1815051Swyllys 	i++;
1825051Swyllys 
1835051Swyllys 	kmf_set_attr_at_index(attlist, i,
1845051Swyllys 	    KMF_KEYLENGTH_ATTR, &keylength, sizeof (keylength));
1855051Swyllys 	i++;
1865051Swyllys 
1875051Swyllys 	if (keylabel != NULL) {
1885051Swyllys 		kmf_set_attr_at_index(attlist, i,
1895051Swyllys 		    KMF_KEYLABEL_ATTR, keylabel,
1905051Swyllys 		    strlen(keylabel));
1915051Swyllys 		i++;
1925051Swyllys 	}
1935051Swyllys 
1946354Swyllys 	if (tokencred != NULL && tokencred->cred != NULL) {
1955051Swyllys 		kmf_set_attr_at_index(attlist, i,
1965051Swyllys 		    KMF_CREDENTIAL_ATTR, tokencred,
1975051Swyllys 		    sizeof (KMF_CREDENTIAL));
1985051Swyllys 		i++;
1995051Swyllys 	}
2005051Swyllys 
2015051Swyllys 	kmf_set_attr_at_index(attlist, i,
2025051Swyllys 	    KMF_SENSITIVE_BOOL_ATTR, &sensitive,
2035051Swyllys 	    sizeof (sensitive));
2045051Swyllys 	i++;
2055051Swyllys 
2065051Swyllys 	kmf_set_attr_at_index(attlist, i,
2075051Swyllys 	    KMF_NON_EXTRACTABLE_BOOL_ATTR, &not_extractable,
2085051Swyllys 	    sizeof (not_extractable));
2095051Swyllys 	i++;
2105051Swyllys 
2115051Swyllys 	kmfrv = kmf_create_sym_key(kmfhandle, i, attlist);
2123089Swyllys 	if (kmfrv != KMF_OK) {
2133089Swyllys 		goto out;
2143089Swyllys 	}
2153089Swyllys 
2163089Swyllys 	if (print_hex) {
2173089Swyllys 		if (sensitive == B_TRUE || not_extractable == B_TRUE) {
2183089Swyllys 			cryptoerror(LOG_STDERR,
2193089Swyllys 			    gettext("Warning: can not reveal the key value "
2203089Swyllys 			    "for a sensitive or non-extractable key.\n"));
2213089Swyllys 			goto out;
2223089Swyllys 		} else {
2233089Swyllys 			rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
2243089Swyllys 			if (rkey == NULL) {
2253089Swyllys 				kmfrv = KMF_ERR_MEMORY;
2263089Swyllys 				goto out;
2273089Swyllys 			}
2283089Swyllys 			(void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
2295051Swyllys 			kmfrv = kmf_get_sym_key_value(kmfhandle, &key, rkey);
2303089Swyllys 			if (kmfrv != KMF_OK) {
2313089Swyllys 				goto out;
2323089Swyllys 			}
2333089Swyllys 			hexstrlen = 2 * rkey->keydata.len + 1;
2343089Swyllys 			hexstr = malloc(hexstrlen);
2353089Swyllys 			if (hexstr == NULL) {
2363089Swyllys 				kmfrv = KMF_ERR_MEMORY;
2373089Swyllys 				goto out;
2383089Swyllys 			}
2393089Swyllys 
2403089Swyllys 			tohexstr(rkey->keydata.val, rkey->keydata.len, hexstr,
2413089Swyllys 			    hexstrlen);
2423089Swyllys 			(void) printf(gettext("\tKey Value =\"%s\"\n"), hexstr);
2433089Swyllys 		}
2443089Swyllys 	}
2453089Swyllys 
2463089Swyllys out:
2475051Swyllys 	kmf_free_raw_sym_key(rkey);
2483089Swyllys 
2493089Swyllys 	if (hexstr != NULL)
2503089Swyllys 		free(hexstr);
2513089Swyllys 
2523089Swyllys 	return (kmfrv);
2533089Swyllys }
2543089Swyllys 
2553089Swyllys 
2563089Swyllys static KMF_RETURN
genkey_file(KMF_HANDLE_T kmfhandle,KMF_KEY_ALG keyAlg,int keylen,char * dir,char * outkey,boolean_t print_hex)2573089Swyllys genkey_file(KMF_HANDLE_T kmfhandle, KMF_KEY_ALG keyAlg, int keylen, char *dir,
2583089Swyllys     char *outkey, boolean_t print_hex)
2593089Swyllys {
2603089Swyllys 	KMF_RETURN kmfrv = KMF_OK;
2613089Swyllys 	KMF_KEY_HANDLE key;
2623089Swyllys 	KMF_RAW_SYM_KEY *rkey = NULL;
2633089Swyllys 	char *hexstr = NULL;
2643089Swyllys 	int hexstrlen;
2655051Swyllys 	KMF_ATTRIBUTE attlist[20];
2665051Swyllys 	int i = 0;
2675051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
2685051Swyllys 	KMF_KEY_ALG keytype;
2695051Swyllys 	uint32_t keylength;
2705051Swyllys 	char *dirpath;
2713089Swyllys 
2723089Swyllys 	if (EMPTYSTRING(outkey)) {
2733089Swyllys 		cryptoerror(LOG_STDERR,
2743089Swyllys 		    gettext("No output key file was specified for the key\n"));
2753089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
2763089Swyllys 	}
2773089Swyllys 
2783089Swyllys 	if (verify_file(outkey)) {
2793089Swyllys 		cryptoerror(LOG_STDERR,
2805051Swyllys 		    gettext("Cannot write the indicated output "
2815051Swyllys 		    "key file (%s).\n"), outkey);
2823089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
2833089Swyllys 	}
2843089Swyllys 
2853089Swyllys 	(void) memset(&key, 0, sizeof (KMF_KEY_HANDLE));
2865051Swyllys 
2875051Swyllys 	keytype = keyAlg;
2885051Swyllys 	keylength = keylen;
2895051Swyllys 
2905221Swyllys 	dirpath = dir;
2915051Swyllys 
2925051Swyllys 	kmf_set_attr_at_index(attlist, i,
2935051Swyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
2945051Swyllys 	i++;
2955051Swyllys 
2965051Swyllys 	kmf_set_attr_at_index(attlist, i,
2975051Swyllys 	    KMF_KEY_HANDLE_ATTR, &key, sizeof (KMF_KEY_HANDLE));
2985051Swyllys 	i++;
2995051Swyllys 
3005051Swyllys 	kmf_set_attr_at_index(attlist, i,
3015051Swyllys 	    KMF_KEYALG_ATTR, &keytype, sizeof (keytype));
3025051Swyllys 	i++;
3033089Swyllys 
3045051Swyllys 	kmf_set_attr_at_index(attlist, i,
3055051Swyllys 	    KMF_KEYLENGTH_ATTR, &keylength, sizeof (keylength));
3065051Swyllys 	i++;
3075051Swyllys 
3085051Swyllys 	if (dirpath != NULL) {
3095051Swyllys 		kmf_set_attr_at_index(attlist, i,
3105051Swyllys 		    KMF_DIRPATH_ATTR, dirpath,
3115051Swyllys 		    strlen(dirpath));
3125051Swyllys 		i++;
3135051Swyllys 	}
3145051Swyllys 
3155051Swyllys 	if (outkey != NULL) {
3165051Swyllys 		kmf_set_attr_at_index(attlist, i,
3175051Swyllys 		    KMF_KEY_FILENAME_ATTR, outkey,
3185051Swyllys 		    strlen(outkey));
3195051Swyllys 		i++;
3205051Swyllys 	}
3215051Swyllys 
3225051Swyllys 	kmfrv = kmf_create_sym_key(kmfhandle, i, attlist);
3233089Swyllys 	if (kmfrv != KMF_OK) {
3243089Swyllys 		goto out;
3253089Swyllys 	}
3263089Swyllys 
3273089Swyllys 	if (print_hex) {
3283089Swyllys 		rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
3293089Swyllys 		if (rkey == NULL) {
3303089Swyllys 			kmfrv = KMF_ERR_MEMORY;
3313089Swyllys 			goto out;
3323089Swyllys 		}
3333089Swyllys 		(void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
3345051Swyllys 		kmfrv = kmf_get_sym_key_value(kmfhandle, &key, rkey);
3353089Swyllys 		if (kmfrv != KMF_OK) {
3363089Swyllys 			goto out;
3373089Swyllys 		}
3383089Swyllys 
3393089Swyllys 		hexstrlen = 2 * rkey->keydata.len + 1;
3403089Swyllys 		hexstr = malloc(hexstrlen);
3413089Swyllys 		if (hexstr == NULL) {
3423089Swyllys 			kmfrv = KMF_ERR_MEMORY;
3433089Swyllys 			goto out;
3443089Swyllys 		}
3453089Swyllys 		tohexstr(rkey->keydata.val, rkey->keydata.len, hexstr,
3463089Swyllys 		    hexstrlen);
3473089Swyllys 		(void) printf(gettext("\tKey Value =\"%s\"\n"), hexstr);
3483089Swyllys 	}
3493089Swyllys 
3503089Swyllys out:
3515051Swyllys 	kmf_free_raw_sym_key(rkey);
3523089Swyllys 
3533089Swyllys 	if (hexstr != NULL)
3543089Swyllys 		free(hexstr);
3553089Swyllys 
3563089Swyllys 	return (kmfrv);
3573089Swyllys }
3583089Swyllys 
3593089Swyllys int
pk_genkey(int argc,char * argv[])3603089Swyllys pk_genkey(int argc, char *argv[])
3613089Swyllys {
3623089Swyllys 	int rv;
3633089Swyllys 	int opt;
3643089Swyllys 	extern int	optind_av;
3653089Swyllys 	extern char	*optarg_av;
3663089Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
3673089Swyllys 	char *tokenname = NULL;
3683089Swyllys 	char *dir = NULL;
3693089Swyllys 	char *prefix = NULL;
3705051Swyllys 	char *keytype = "generic";
3713089Swyllys 	char *keylenstr = NULL;
3723089Swyllys 	int keylen = 0;
3733089Swyllys 	char *keylabel = NULL;
3743089Swyllys 	char *outkey = NULL;
3753089Swyllys 	char *senstr = NULL;
3763089Swyllys 	char *extstr = NULL;
3773089Swyllys 	char *printstr = NULL;
3783089Swyllys 	KMF_HANDLE_T kmfhandle = NULL;
3795051Swyllys 	KMF_KEY_ALG keyAlg = KMF_GENERIC_SECRET;
3803089Swyllys 	boolean_t print_hex = B_FALSE;
3813089Swyllys 	KMF_CREDENTIAL tokencred = {NULL, 0};
3823089Swyllys 
3833089Swyllys 	while ((opt = getopt_av(argc, argv,
3845051Swyllys 	    "k:(keystore)l:(label)T:(token)d:(dir)p:(prefix)"
3855051Swyllys 	    "t:(keytype)y:(keylen)K:(outkey)P:(print)"
3865051Swyllys 	    "s:(sensitive)e:(extractable)")) != EOF) {
3873089Swyllys 		if (EMPTYSTRING(optarg_av))
3883089Swyllys 			return (PK_ERR_USAGE);
3893089Swyllys 		switch (opt) {
3903089Swyllys 			case 'k':
3913089Swyllys 				kstype = KS2Int(optarg_av);
3923089Swyllys 				if (kstype == 0)
3933089Swyllys 					return (PK_ERR_USAGE);
3943089Swyllys 				break;
3953089Swyllys 			case 'l':
3963089Swyllys 				if (keylabel)
3973089Swyllys 					return (PK_ERR_USAGE);
3983089Swyllys 				keylabel = optarg_av;
3993089Swyllys 				break;
4003089Swyllys 			case 'T':
4013089Swyllys 				if (tokenname)
4023089Swyllys 					return (PK_ERR_USAGE);
4033089Swyllys 				tokenname = optarg_av;
4043089Swyllys 				break;
4053089Swyllys 			case 'd':
4063089Swyllys 				if (dir)
4073089Swyllys 					return (PK_ERR_USAGE);
4083089Swyllys 				dir = optarg_av;
4093089Swyllys 				break;
4103089Swyllys 			case 'p':
4113089Swyllys 				if (prefix)
4123089Swyllys 					return (PK_ERR_USAGE);
4133089Swyllys 				prefix = optarg_av;
4143089Swyllys 				break;
4153089Swyllys 			case 't':
4163089Swyllys 				keytype = optarg_av;
4173089Swyllys 				break;
4183089Swyllys 			case 'y':
4193089Swyllys 				if (keylenstr)
4203089Swyllys 					return (PK_ERR_USAGE);
4213089Swyllys 				keylenstr = optarg_av;
4223089Swyllys 				break;
4233089Swyllys 			case 'K':
4243089Swyllys 				if (outkey)
4253089Swyllys 					return (PK_ERR_USAGE);
4263089Swyllys 				outkey = optarg_av;
4273089Swyllys 				break;
4283089Swyllys 			case 'P':
4293089Swyllys 				if (printstr)
4303089Swyllys 					return (PK_ERR_USAGE);
4313089Swyllys 				printstr = optarg_av;
4323089Swyllys 				break;
4333089Swyllys 			case 's':
4343089Swyllys 				if (senstr)
4353089Swyllys 					return (PK_ERR_USAGE);
4363089Swyllys 				senstr = optarg_av;
4373089Swyllys 				break;
4383089Swyllys 			case 'e':
4393089Swyllys 				if (extstr)
4403089Swyllys 					return (PK_ERR_USAGE);
4413089Swyllys 				extstr = optarg_av;
4423089Swyllys 				break;
4433089Swyllys 			default:
4443089Swyllys 				return (PK_ERR_USAGE);
4453089Swyllys 		}
4463089Swyllys 	}
4473089Swyllys 
4483089Swyllys 	/* No additional args allowed. */
4493089Swyllys 	argc -= optind_av;
4503089Swyllys 	argv += optind_av;
4513089Swyllys 	if (argc) {
4523089Swyllys 		return (PK_ERR_USAGE);
4533089Swyllys 	}
4543089Swyllys 
4553089Swyllys 	/* Check keytype. If not specified, default to AES */
4563089Swyllys 	if (keytype != NULL && Str2SymKeyType(keytype, &keyAlg) != 0) {
4573089Swyllys 		cryptoerror(LOG_STDERR, gettext("Unrecognized keytype(%s).\n"),
4585051Swyllys 		    keytype);
4593089Swyllys 		return (PK_ERR_USAGE);
4603089Swyllys 	}
4613089Swyllys 
4623089Swyllys 	/*
4633089Swyllys 	 * Check and set the key length.
4643089Swyllys 	 * - For DES and 3DES, the key size are fixed. Ingore the keylen
4653089Swyllys 	 *   option, even if it is specified.
4663089Swyllys 	 * - For AES and ARCFOUR, if keylen is not specified, default to
4673089Swyllys 	 *   128 bits.
4683089Swyllys 	 */
4693089Swyllys 	if (keyAlg == KMF_DES)
4703089Swyllys 		keylen = 64;  /* fixed size; ignore input */
4713089Swyllys 	else if (keyAlg == KMF_DES3)
4723089Swyllys 		keylen = 192; /* fixed size; ignore input */
4733812Shylee 	else /* AES, ARCFOUR, or GENERIC SECRET */ {
4743089Swyllys 		if (keylenstr == NULL) {
4753089Swyllys 			cryptoerror(LOG_STDERR,
4765051Swyllys 			    gettext("Key length must be specified for "
4775051Swyllys 			    "AES, ARCFOUR or GENERIC symmetric keys.\n"));
4783089Swyllys 			return (PK_ERR_USAGE);
4793089Swyllys 		}
4803089Swyllys 		if (sscanf(keylenstr, "%d", &keylen) != 1) {
4813089Swyllys 			cryptoerror(LOG_STDERR,
4825051Swyllys 			    gettext("Unrecognized key length (%s).\n"),
4835051Swyllys 			    keytype);
4843089Swyllys 			return (PK_ERR_USAGE);
4853089Swyllys 		}
4863089Swyllys 		if (keylen == 0 || (keylen % 8) != 0) {
4873089Swyllys 			cryptoerror(LOG_STDERR,
4885051Swyllys 			    gettext("Key length bitlength must be a "
4895051Swyllys 			    "multiple of 8.\n"));
4903089Swyllys 			return (PK_ERR_USAGE);
4913089Swyllys 		}
4923089Swyllys 	}
4933089Swyllys 
4943089Swyllys 	/* check the print option */
4953089Swyllys 	if (printstr != NULL) {
4963089Swyllys 		if (kstype == KMF_KEYSTORE_NSS) {
4973089Swyllys 			cryptoerror(LOG_STDERR,
4983089Swyllys 			    gettext("The print option does not apply "
4993089Swyllys 			    "to the NSS keystore.\n"));
5003089Swyllys 			return (PK_ERR_USAGE);
5013089Swyllys 		}
5023089Swyllys 
5033089Swyllys 		if (tolower(printstr[0]) == 'y')
5043089Swyllys 			print_hex = B_TRUE;
5053089Swyllys 		else if (tolower(printstr[0]) == 'n')
5063089Swyllys 			print_hex = B_FALSE;
5073089Swyllys 		else {
5083089Swyllys 			cryptoerror(LOG_STDERR,
5093089Swyllys 			    gettext("Incorrect print option value.\n"));
5103089Swyllys 			return (PK_ERR_USAGE);
5113089Swyllys 		}
5123089Swyllys 	}
5133089Swyllys 
5143089Swyllys 	/* check the sensitive and extractable options */
5153089Swyllys 	if ((senstr != NULL || extstr != NULL) &&
5163089Swyllys 	    (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_OPENSSL)) {
5173089Swyllys 		cryptoerror(LOG_STDERR,
5183089Swyllys 		    gettext("The sensitive or extractable option applies "
5193089Swyllys 		    "to the PKCS11 keystore only.\n"));
5203089Swyllys 		return (PK_ERR_USAGE);
5213089Swyllys 	}
5223089Swyllys 
5233089Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN && tokenname == NULL) {
5243089Swyllys 		tokenname = PK_DEFAULT_PK11TOKEN;
5253089Swyllys 	} else if (kstype == KMF_KEYSTORE_NSS && tokenname == NULL) {
5263089Swyllys 		tokenname = DEFAULT_NSS_TOKEN;
5273089Swyllys 	}
528*6884Swyllys 	DIR_OPTION_CHECK(kstype, dir);
5293089Swyllys 
5303089Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS)
5313089Swyllys 		(void) get_token_password(kstype, tokenname, &tokencred);
5323089Swyllys 
5335051Swyllys 	if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
5343089Swyllys 		cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n"));
5353089Swyllys 		goto end;
5363089Swyllys 	}
5373089Swyllys 
5383089Swyllys 	if (kstype == KMF_KEYSTORE_NSS) {
5393089Swyllys 		rv = genkey_nss(kmfhandle, tokenname, dir, prefix,
5403089Swyllys 		    keylabel, keyAlg, keylen, &tokencred);
5413089Swyllys 	} else if (kstype == KMF_KEYSTORE_OPENSSL) {
5423089Swyllys 		rv = genkey_file(kmfhandle, keyAlg, keylen, dir, outkey,
5433089Swyllys 		    print_hex);
5443089Swyllys 	} else {
5453089Swyllys 		rv = genkey_pkcs11(kmfhandle, tokenname, keylabel, keyAlg,
5463089Swyllys 		    keylen, senstr, extstr, print_hex, &tokencred);
5473089Swyllys 	}
5483089Swyllys 
5493089Swyllys end:
5503089Swyllys 	if (rv != KMF_OK)
5513089Swyllys 		display_error(kmfhandle, rv,
5525051Swyllys 		    gettext("Error generating key"));
5533089Swyllys 
5543089Swyllys 	if (tokencred.cred != NULL)
5553089Swyllys 		free(tokencred.cred);
5563089Swyllys 
5575051Swyllys 	(void) kmf_finalize(kmfhandle);
5583089Swyllys 	if (rv != KMF_OK)
5593089Swyllys 		return (PK_ERR_USAGE);
5603089Swyllys 
5613089Swyllys 	return (0);
5623089Swyllys }
563