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, ¬_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