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*fa60c371Swyllys * Copyright 2008 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_KEY_HANDLE key; 4630a5e8faSwyllys KMF_ATTRIBUTE attlist[20]; 4730a5e8faSwyllys int i = 0; 4830a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; 4930a5e8faSwyllys KMF_KEY_ALG keytype; 5030a5e8faSwyllys uint32_t keylength; 5199ebb4caSwyllys 5299ebb4caSwyllys if (keylabel == NULL) { 5399ebb4caSwyllys cryptoerror(LOG_STDERR, 5499ebb4caSwyllys gettext("A key label must be specified \n")); 5599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 5699ebb4caSwyllys } 5799ebb4caSwyllys 5899ebb4caSwyllys kmfrv = configure_nss(kmfhandle, dir, prefix); 5999ebb4caSwyllys if (kmfrv != KMF_OK) 6099ebb4caSwyllys return (kmfrv); 6199ebb4caSwyllys 6299ebb4caSwyllys (void) memset(&key, 0, sizeof (KMF_KEY_HANDLE)); 6330a5e8faSwyllys 6430a5e8faSwyllys keytype = keyAlg; 6530a5e8faSwyllys keylength = keylen; 6630a5e8faSwyllys 6730a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 6830a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 6930a5e8faSwyllys i++; 7030a5e8faSwyllys 7130a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 7230a5e8faSwyllys KMF_KEY_HANDLE_ATTR, &key, sizeof (KMF_KEY_HANDLE)); 7330a5e8faSwyllys i++; 7430a5e8faSwyllys 7530a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 7630a5e8faSwyllys KMF_KEYALG_ATTR, &keytype, sizeof (keytype)); 7730a5e8faSwyllys i++; 7830a5e8faSwyllys 7930a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 8030a5e8faSwyllys KMF_KEYLENGTH_ATTR, &keylength, sizeof (keylength)); 8130a5e8faSwyllys i++; 8230a5e8faSwyllys 8330a5e8faSwyllys if (keylabel != NULL) { 8430a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 8530a5e8faSwyllys KMF_KEYLABEL_ATTR, keylabel, 8630a5e8faSwyllys strlen(keylabel)); 8730a5e8faSwyllys i++; 8830a5e8faSwyllys } 8930a5e8faSwyllys 90*fa60c371Swyllys if (tokencred != NULL && tokencred->cred != NULL) { 9130a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 9230a5e8faSwyllys KMF_CREDENTIAL_ATTR, tokencred, 9330a5e8faSwyllys sizeof (KMF_CREDENTIAL)); 9430a5e8faSwyllys i++; 9530a5e8faSwyllys } 9630a5e8faSwyllys 9730a5e8faSwyllys if (token != NULL) { 9830a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 9930a5e8faSwyllys KMF_TOKEN_LABEL_ATTR, token, 10030a5e8faSwyllys strlen(token)); 10130a5e8faSwyllys i++; 10230a5e8faSwyllys } 10330a5e8faSwyllys 10430a5e8faSwyllys kmfrv = kmf_create_sym_key(kmfhandle, i, attlist); 10599ebb4caSwyllys 10699ebb4caSwyllys return (kmfrv); 10799ebb4caSwyllys } 10899ebb4caSwyllys 10999ebb4caSwyllys static KMF_RETURN 11099ebb4caSwyllys genkey_pkcs11(KMF_HANDLE_T kmfhandle, char *token, 11199ebb4caSwyllys char *keylabel, KMF_KEY_ALG keyAlg, int keylen, 11299ebb4caSwyllys char *senstr, char *extstr, boolean_t print_hex, 11399ebb4caSwyllys KMF_CREDENTIAL *tokencred) 11499ebb4caSwyllys { 11599ebb4caSwyllys KMF_RETURN kmfrv = KMF_OK; 11699ebb4caSwyllys KMF_KEY_HANDLE key; 11799ebb4caSwyllys KMF_RAW_SYM_KEY *rkey = NULL; 11899ebb4caSwyllys boolean_t sensitive = B_FALSE; 11999ebb4caSwyllys boolean_t not_extractable = B_FALSE; 12099ebb4caSwyllys char *hexstr = NULL; 12199ebb4caSwyllys int hexstrlen; 12230a5e8faSwyllys KMF_ATTRIBUTE attlist[20]; 12330a5e8faSwyllys int i = 0; 12430a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 12530a5e8faSwyllys KMF_KEY_ALG keytype; 12630a5e8faSwyllys uint32_t keylength; 12799ebb4caSwyllys 12899ebb4caSwyllys if (keylabel == NULL) { 12999ebb4caSwyllys cryptoerror(LOG_STDERR, 13099ebb4caSwyllys gettext("A key label must be specified \n")); 13199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 13299ebb4caSwyllys } 13399ebb4caSwyllys 13499ebb4caSwyllys /* Check the sensitive option value if specified. */ 13599ebb4caSwyllys if (senstr != NULL) { 13699ebb4caSwyllys if (tolower(senstr[0]) == 'y') 13799ebb4caSwyllys sensitive = B_TRUE; 13899ebb4caSwyllys else if (tolower(senstr[0]) == 'n') 13999ebb4caSwyllys sensitive = B_FALSE; 14099ebb4caSwyllys else { 14199ebb4caSwyllys cryptoerror(LOG_STDERR, 14299ebb4caSwyllys gettext("Incorrect sensitive option value.\n")); 14399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 14499ebb4caSwyllys } 14599ebb4caSwyllys } 14699ebb4caSwyllys 14799ebb4caSwyllys /* Check the extractable option value if specified. */ 14899ebb4caSwyllys if (extstr != NULL) { 14999ebb4caSwyllys if (tolower(extstr[0]) == 'y') 15099ebb4caSwyllys not_extractable = B_FALSE; 15199ebb4caSwyllys else if (tolower(extstr[0]) == 'n') 15299ebb4caSwyllys not_extractable = B_TRUE; 15399ebb4caSwyllys else { 15499ebb4caSwyllys cryptoerror(LOG_STDERR, 15599ebb4caSwyllys gettext("Incorrect extractable option value.\n")); 15699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 15799ebb4caSwyllys } 15899ebb4caSwyllys } 15999ebb4caSwyllys 16099ebb4caSwyllys /* Select a PKCS11 token first */ 16199ebb4caSwyllys kmfrv = select_token(kmfhandle, token, FALSE); 16299ebb4caSwyllys if (kmfrv != KMF_OK) { 16399ebb4caSwyllys return (kmfrv); 16499ebb4caSwyllys } 16599ebb4caSwyllys 16699ebb4caSwyllys (void) memset(&key, 0, sizeof (KMF_KEY_HANDLE)); 16730a5e8faSwyllys 16830a5e8faSwyllys keytype = keyAlg; 16930a5e8faSwyllys keylength = keylen; /* bits */ 17030a5e8faSwyllys 17130a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 17230a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 17330a5e8faSwyllys i++; 17430a5e8faSwyllys 17530a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 17630a5e8faSwyllys KMF_KEY_HANDLE_ATTR, &key, sizeof (KMF_KEY_HANDLE)); 17730a5e8faSwyllys i++; 17830a5e8faSwyllys 17930a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 18030a5e8faSwyllys KMF_KEYALG_ATTR, &keytype, sizeof (keytype)); 18130a5e8faSwyllys i++; 18230a5e8faSwyllys 18330a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 18430a5e8faSwyllys KMF_KEYLENGTH_ATTR, &keylength, sizeof (keylength)); 18530a5e8faSwyllys i++; 18630a5e8faSwyllys 18730a5e8faSwyllys if (keylabel != NULL) { 18830a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 18930a5e8faSwyllys KMF_KEYLABEL_ATTR, keylabel, 19030a5e8faSwyllys strlen(keylabel)); 19130a5e8faSwyllys i++; 19230a5e8faSwyllys } 19330a5e8faSwyllys 194*fa60c371Swyllys if (tokencred != NULL && tokencred->cred != NULL) { 19530a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 19630a5e8faSwyllys KMF_CREDENTIAL_ATTR, tokencred, 19730a5e8faSwyllys sizeof (KMF_CREDENTIAL)); 19830a5e8faSwyllys i++; 19930a5e8faSwyllys } 20030a5e8faSwyllys 20130a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 20230a5e8faSwyllys KMF_SENSITIVE_BOOL_ATTR, &sensitive, 20330a5e8faSwyllys sizeof (sensitive)); 20430a5e8faSwyllys i++; 20530a5e8faSwyllys 20630a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 20730a5e8faSwyllys KMF_NON_EXTRACTABLE_BOOL_ATTR, ¬_extractable, 20830a5e8faSwyllys sizeof (not_extractable)); 20930a5e8faSwyllys i++; 21030a5e8faSwyllys 21130a5e8faSwyllys kmfrv = kmf_create_sym_key(kmfhandle, i, attlist); 21299ebb4caSwyllys if (kmfrv != KMF_OK) { 21399ebb4caSwyllys goto out; 21499ebb4caSwyllys } 21599ebb4caSwyllys 21699ebb4caSwyllys if (print_hex) { 21799ebb4caSwyllys if (sensitive == B_TRUE || not_extractable == B_TRUE) { 21899ebb4caSwyllys cryptoerror(LOG_STDERR, 21999ebb4caSwyllys gettext("Warning: can not reveal the key value " 22099ebb4caSwyllys "for a sensitive or non-extractable key.\n")); 22199ebb4caSwyllys goto out; 22299ebb4caSwyllys } else { 22399ebb4caSwyllys rkey = malloc(sizeof (KMF_RAW_SYM_KEY)); 22499ebb4caSwyllys if (rkey == NULL) { 22599ebb4caSwyllys kmfrv = KMF_ERR_MEMORY; 22699ebb4caSwyllys goto out; 22799ebb4caSwyllys } 22899ebb4caSwyllys (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 22930a5e8faSwyllys kmfrv = kmf_get_sym_key_value(kmfhandle, &key, rkey); 23099ebb4caSwyllys if (kmfrv != KMF_OK) { 23199ebb4caSwyllys goto out; 23299ebb4caSwyllys } 23399ebb4caSwyllys hexstrlen = 2 * rkey->keydata.len + 1; 23499ebb4caSwyllys hexstr = malloc(hexstrlen); 23599ebb4caSwyllys if (hexstr == NULL) { 23699ebb4caSwyllys kmfrv = KMF_ERR_MEMORY; 23799ebb4caSwyllys goto out; 23899ebb4caSwyllys } 23999ebb4caSwyllys 24099ebb4caSwyllys tohexstr(rkey->keydata.val, rkey->keydata.len, hexstr, 24199ebb4caSwyllys hexstrlen); 24299ebb4caSwyllys (void) printf(gettext("\tKey Value =\"%s\"\n"), hexstr); 24399ebb4caSwyllys } 24499ebb4caSwyllys } 24599ebb4caSwyllys 24699ebb4caSwyllys out: 24730a5e8faSwyllys kmf_free_raw_sym_key(rkey); 24899ebb4caSwyllys 24999ebb4caSwyllys if (hexstr != NULL) 25099ebb4caSwyllys free(hexstr); 25199ebb4caSwyllys 25299ebb4caSwyllys return (kmfrv); 25399ebb4caSwyllys } 25499ebb4caSwyllys 25599ebb4caSwyllys 25699ebb4caSwyllys static KMF_RETURN 25799ebb4caSwyllys genkey_file(KMF_HANDLE_T kmfhandle, KMF_KEY_ALG keyAlg, int keylen, char *dir, 25899ebb4caSwyllys char *outkey, boolean_t print_hex) 25999ebb4caSwyllys { 26099ebb4caSwyllys KMF_RETURN kmfrv = KMF_OK; 26199ebb4caSwyllys KMF_KEY_HANDLE key; 26299ebb4caSwyllys KMF_RAW_SYM_KEY *rkey = NULL; 26399ebb4caSwyllys char *hexstr = NULL; 26499ebb4caSwyllys int hexstrlen; 26530a5e8faSwyllys KMF_ATTRIBUTE attlist[20]; 26630a5e8faSwyllys int i = 0; 26730a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 26830a5e8faSwyllys KMF_KEY_ALG keytype; 26930a5e8faSwyllys uint32_t keylength; 27030a5e8faSwyllys char *dirpath; 27199ebb4caSwyllys 27299ebb4caSwyllys if (EMPTYSTRING(outkey)) { 27399ebb4caSwyllys cryptoerror(LOG_STDERR, 27499ebb4caSwyllys gettext("No output key file was specified for the key\n")); 27599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 27699ebb4caSwyllys } 27799ebb4caSwyllys 27899ebb4caSwyllys if (verify_file(outkey)) { 27999ebb4caSwyllys cryptoerror(LOG_STDERR, 28099ebb4caSwyllys gettext("Cannot write the indicated output " 28199ebb4caSwyllys "key file (%s).\n"), outkey); 28299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 28399ebb4caSwyllys } 28499ebb4caSwyllys 28599ebb4caSwyllys (void) memset(&key, 0, sizeof (KMF_KEY_HANDLE)); 28699ebb4caSwyllys 28730a5e8faSwyllys keytype = keyAlg; 28830a5e8faSwyllys keylength = keylen; 28930a5e8faSwyllys 2902cbed729Swyllys dirpath = dir; 29130a5e8faSwyllys 29230a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 29330a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 29430a5e8faSwyllys i++; 29530a5e8faSwyllys 29630a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 29730a5e8faSwyllys KMF_KEY_HANDLE_ATTR, &key, sizeof (KMF_KEY_HANDLE)); 29830a5e8faSwyllys i++; 29930a5e8faSwyllys 30030a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 30130a5e8faSwyllys KMF_KEYALG_ATTR, &keytype, sizeof (keytype)); 30230a5e8faSwyllys i++; 30330a5e8faSwyllys 30430a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 30530a5e8faSwyllys KMF_KEYLENGTH_ATTR, &keylength, sizeof (keylength)); 30630a5e8faSwyllys i++; 30730a5e8faSwyllys 30830a5e8faSwyllys if (dirpath != NULL) { 30930a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 31030a5e8faSwyllys KMF_DIRPATH_ATTR, dirpath, 31130a5e8faSwyllys strlen(dirpath)); 31230a5e8faSwyllys i++; 31330a5e8faSwyllys } 31430a5e8faSwyllys 31530a5e8faSwyllys if (outkey != NULL) { 31630a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 31730a5e8faSwyllys KMF_KEY_FILENAME_ATTR, outkey, 31830a5e8faSwyllys strlen(outkey)); 31930a5e8faSwyllys i++; 32030a5e8faSwyllys } 32130a5e8faSwyllys 32230a5e8faSwyllys kmfrv = kmf_create_sym_key(kmfhandle, i, attlist); 32399ebb4caSwyllys if (kmfrv != KMF_OK) { 32499ebb4caSwyllys goto out; 32599ebb4caSwyllys } 32699ebb4caSwyllys 32799ebb4caSwyllys if (print_hex) { 32899ebb4caSwyllys rkey = malloc(sizeof (KMF_RAW_SYM_KEY)); 32999ebb4caSwyllys if (rkey == NULL) { 33099ebb4caSwyllys kmfrv = KMF_ERR_MEMORY; 33199ebb4caSwyllys goto out; 33299ebb4caSwyllys } 33399ebb4caSwyllys (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 33430a5e8faSwyllys kmfrv = kmf_get_sym_key_value(kmfhandle, &key, rkey); 33599ebb4caSwyllys if (kmfrv != KMF_OK) { 33699ebb4caSwyllys goto out; 33799ebb4caSwyllys } 33899ebb4caSwyllys 33999ebb4caSwyllys hexstrlen = 2 * rkey->keydata.len + 1; 34099ebb4caSwyllys hexstr = malloc(hexstrlen); 34199ebb4caSwyllys if (hexstr == NULL) { 34299ebb4caSwyllys kmfrv = KMF_ERR_MEMORY; 34399ebb4caSwyllys goto out; 34499ebb4caSwyllys } 34599ebb4caSwyllys tohexstr(rkey->keydata.val, rkey->keydata.len, hexstr, 34699ebb4caSwyllys hexstrlen); 34799ebb4caSwyllys (void) printf(gettext("\tKey Value =\"%s\"\n"), hexstr); 34899ebb4caSwyllys } 34999ebb4caSwyllys 35099ebb4caSwyllys out: 35130a5e8faSwyllys kmf_free_raw_sym_key(rkey); 35299ebb4caSwyllys 35399ebb4caSwyllys if (hexstr != NULL) 35499ebb4caSwyllys free(hexstr); 35599ebb4caSwyllys 35699ebb4caSwyllys return (kmfrv); 35799ebb4caSwyllys } 35899ebb4caSwyllys 35999ebb4caSwyllys int 36099ebb4caSwyllys pk_genkey(int argc, char *argv[]) 36199ebb4caSwyllys { 36299ebb4caSwyllys int rv; 36399ebb4caSwyllys int opt; 36499ebb4caSwyllys extern int optind_av; 36599ebb4caSwyllys extern char *optarg_av; 36699ebb4caSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 36799ebb4caSwyllys char *tokenname = NULL; 36899ebb4caSwyllys char *dir = NULL; 36999ebb4caSwyllys char *prefix = NULL; 37030a5e8faSwyllys char *keytype = "generic"; 37199ebb4caSwyllys char *keylenstr = NULL; 37299ebb4caSwyllys int keylen = 0; 37399ebb4caSwyllys char *keylabel = NULL; 37499ebb4caSwyllys char *outkey = NULL; 37599ebb4caSwyllys char *senstr = NULL; 37699ebb4caSwyllys char *extstr = NULL; 37799ebb4caSwyllys char *printstr = NULL; 37899ebb4caSwyllys KMF_HANDLE_T kmfhandle = NULL; 37930a5e8faSwyllys KMF_KEY_ALG keyAlg = KMF_GENERIC_SECRET; 38099ebb4caSwyllys boolean_t print_hex = B_FALSE; 38199ebb4caSwyllys KMF_CREDENTIAL tokencred = {NULL, 0}; 38299ebb4caSwyllys 38399ebb4caSwyllys while ((opt = getopt_av(argc, argv, 38499ebb4caSwyllys "k:(keystore)l:(label)T:(token)d:(dir)p:(prefix)" 38599ebb4caSwyllys "t:(keytype)y:(keylen)K:(outkey)P:(print)" 38699ebb4caSwyllys "s:(sensitive)e:(extractable)")) != EOF) { 38799ebb4caSwyllys if (EMPTYSTRING(optarg_av)) 38899ebb4caSwyllys return (PK_ERR_USAGE); 38999ebb4caSwyllys switch (opt) { 39099ebb4caSwyllys case 'k': 39199ebb4caSwyllys kstype = KS2Int(optarg_av); 39299ebb4caSwyllys if (kstype == 0) 39399ebb4caSwyllys return (PK_ERR_USAGE); 39499ebb4caSwyllys break; 39599ebb4caSwyllys case 'l': 39699ebb4caSwyllys if (keylabel) 39799ebb4caSwyllys return (PK_ERR_USAGE); 39899ebb4caSwyllys keylabel = optarg_av; 39999ebb4caSwyllys break; 40099ebb4caSwyllys case 'T': 40199ebb4caSwyllys if (tokenname) 40299ebb4caSwyllys return (PK_ERR_USAGE); 40399ebb4caSwyllys tokenname = optarg_av; 40499ebb4caSwyllys break; 40599ebb4caSwyllys case 'd': 40699ebb4caSwyllys if (dir) 40799ebb4caSwyllys return (PK_ERR_USAGE); 40899ebb4caSwyllys dir = optarg_av; 40999ebb4caSwyllys break; 41099ebb4caSwyllys case 'p': 41199ebb4caSwyllys if (prefix) 41299ebb4caSwyllys return (PK_ERR_USAGE); 41399ebb4caSwyllys prefix = optarg_av; 41499ebb4caSwyllys break; 41599ebb4caSwyllys case 't': 41699ebb4caSwyllys keytype = optarg_av; 41799ebb4caSwyllys break; 41899ebb4caSwyllys case 'y': 41999ebb4caSwyllys if (keylenstr) 42099ebb4caSwyllys return (PK_ERR_USAGE); 42199ebb4caSwyllys keylenstr = optarg_av; 42299ebb4caSwyllys break; 42399ebb4caSwyllys case 'K': 42499ebb4caSwyllys if (outkey) 42599ebb4caSwyllys return (PK_ERR_USAGE); 42699ebb4caSwyllys outkey = optarg_av; 42799ebb4caSwyllys break; 42899ebb4caSwyllys case 'P': 42999ebb4caSwyllys if (printstr) 43099ebb4caSwyllys return (PK_ERR_USAGE); 43199ebb4caSwyllys printstr = optarg_av; 43299ebb4caSwyllys break; 43399ebb4caSwyllys case 's': 43499ebb4caSwyllys if (senstr) 43599ebb4caSwyllys return (PK_ERR_USAGE); 43699ebb4caSwyllys senstr = optarg_av; 43799ebb4caSwyllys break; 43899ebb4caSwyllys case 'e': 43999ebb4caSwyllys if (extstr) 44099ebb4caSwyllys return (PK_ERR_USAGE); 44199ebb4caSwyllys extstr = optarg_av; 44299ebb4caSwyllys break; 44399ebb4caSwyllys default: 44499ebb4caSwyllys return (PK_ERR_USAGE); 44599ebb4caSwyllys } 44699ebb4caSwyllys } 44799ebb4caSwyllys 44899ebb4caSwyllys /* No additional args allowed. */ 44999ebb4caSwyllys argc -= optind_av; 45099ebb4caSwyllys argv += optind_av; 45199ebb4caSwyllys if (argc) { 45299ebb4caSwyllys return (PK_ERR_USAGE); 45399ebb4caSwyllys } 45499ebb4caSwyllys 45599ebb4caSwyllys /* Check keytype. If not specified, default to AES */ 45699ebb4caSwyllys if (keytype != NULL && Str2SymKeyType(keytype, &keyAlg) != 0) { 45799ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("Unrecognized keytype(%s).\n"), 45899ebb4caSwyllys keytype); 45999ebb4caSwyllys return (PK_ERR_USAGE); 46099ebb4caSwyllys } 46199ebb4caSwyllys 46299ebb4caSwyllys /* 46399ebb4caSwyllys * Check and set the key length. 46499ebb4caSwyllys * - For DES and 3DES, the key size are fixed. Ingore the keylen 46599ebb4caSwyllys * option, even if it is specified. 46699ebb4caSwyllys * - For AES and ARCFOUR, if keylen is not specified, default to 46799ebb4caSwyllys * 128 bits. 46899ebb4caSwyllys */ 46999ebb4caSwyllys if (keyAlg == KMF_DES) 47099ebb4caSwyllys keylen = 64; /* fixed size; ignore input */ 47199ebb4caSwyllys else if (keyAlg == KMF_DES3) 47299ebb4caSwyllys keylen = 192; /* fixed size; ignore input */ 473c197cb9dShylee else /* AES, ARCFOUR, or GENERIC SECRET */ { 47499ebb4caSwyllys if (keylenstr == NULL) { 47599ebb4caSwyllys cryptoerror(LOG_STDERR, 476c197cb9dShylee gettext("Key length must be specified for " 477c197cb9dShylee "AES, ARCFOUR or GENERIC symmetric keys.\n")); 47899ebb4caSwyllys return (PK_ERR_USAGE); 47999ebb4caSwyllys } 48099ebb4caSwyllys if (sscanf(keylenstr, "%d", &keylen) != 1) { 48199ebb4caSwyllys cryptoerror(LOG_STDERR, 48299ebb4caSwyllys gettext("Unrecognized key length (%s).\n"), 48399ebb4caSwyllys keytype); 48499ebb4caSwyllys return (PK_ERR_USAGE); 48599ebb4caSwyllys } 48699ebb4caSwyllys if (keylen == 0 || (keylen % 8) != 0) { 48799ebb4caSwyllys cryptoerror(LOG_STDERR, 48899ebb4caSwyllys gettext("Key length bitlength must be a " 48999ebb4caSwyllys "multiple of 8.\n")); 49099ebb4caSwyllys return (PK_ERR_USAGE); 49199ebb4caSwyllys } 49299ebb4caSwyllys } 49399ebb4caSwyllys 49499ebb4caSwyllys /* check the print option */ 49599ebb4caSwyllys if (printstr != NULL) { 49699ebb4caSwyllys if (kstype == KMF_KEYSTORE_NSS) { 49799ebb4caSwyllys cryptoerror(LOG_STDERR, 49899ebb4caSwyllys gettext("The print option does not apply " 49999ebb4caSwyllys "to the NSS keystore.\n")); 50099ebb4caSwyllys return (PK_ERR_USAGE); 50199ebb4caSwyllys } 50299ebb4caSwyllys 50399ebb4caSwyllys if (tolower(printstr[0]) == 'y') 50499ebb4caSwyllys print_hex = B_TRUE; 50599ebb4caSwyllys else if (tolower(printstr[0]) == 'n') 50699ebb4caSwyllys print_hex = B_FALSE; 50799ebb4caSwyllys else { 50899ebb4caSwyllys cryptoerror(LOG_STDERR, 50999ebb4caSwyllys gettext("Incorrect print option value.\n")); 51099ebb4caSwyllys return (PK_ERR_USAGE); 51199ebb4caSwyllys } 51299ebb4caSwyllys } 51399ebb4caSwyllys 51499ebb4caSwyllys /* check the sensitive and extractable options */ 51599ebb4caSwyllys if ((senstr != NULL || extstr != NULL) && 51699ebb4caSwyllys (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_OPENSSL)) { 51799ebb4caSwyllys cryptoerror(LOG_STDERR, 51899ebb4caSwyllys gettext("The sensitive or extractable option applies " 51999ebb4caSwyllys "to the PKCS11 keystore only.\n")); 52099ebb4caSwyllys return (PK_ERR_USAGE); 52199ebb4caSwyllys } 52299ebb4caSwyllys 52399ebb4caSwyllys if (kstype == KMF_KEYSTORE_PK11TOKEN && tokenname == NULL) { 52499ebb4caSwyllys tokenname = PK_DEFAULT_PK11TOKEN; 52599ebb4caSwyllys } else if (kstype == KMF_KEYSTORE_NSS && tokenname == NULL) { 52699ebb4caSwyllys tokenname = DEFAULT_NSS_TOKEN; 52799ebb4caSwyllys } 52899ebb4caSwyllys 52999ebb4caSwyllys if (kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS) 53099ebb4caSwyllys (void) get_token_password(kstype, tokenname, &tokencred); 53199ebb4caSwyllys 53230a5e8faSwyllys if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 53399ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n")); 53499ebb4caSwyllys goto end; 53599ebb4caSwyllys } 53699ebb4caSwyllys 53799ebb4caSwyllys if (kstype == KMF_KEYSTORE_NSS) { 53899ebb4caSwyllys rv = genkey_nss(kmfhandle, tokenname, dir, prefix, 53999ebb4caSwyllys keylabel, keyAlg, keylen, &tokencred); 54099ebb4caSwyllys } else if (kstype == KMF_KEYSTORE_OPENSSL) { 54199ebb4caSwyllys rv = genkey_file(kmfhandle, keyAlg, keylen, dir, outkey, 54299ebb4caSwyllys print_hex); 54399ebb4caSwyllys } else { 54499ebb4caSwyllys rv = genkey_pkcs11(kmfhandle, tokenname, keylabel, keyAlg, 54599ebb4caSwyllys keylen, senstr, extstr, print_hex, &tokencred); 54699ebb4caSwyllys } 54799ebb4caSwyllys 54899ebb4caSwyllys end: 54999ebb4caSwyllys if (rv != KMF_OK) 55099ebb4caSwyllys display_error(kmfhandle, rv, 55199ebb4caSwyllys gettext("Error generating key")); 55299ebb4caSwyllys 55399ebb4caSwyllys if (tokencred.cred != NULL) 55499ebb4caSwyllys free(tokencred.cred); 55599ebb4caSwyllys 55630a5e8faSwyllys (void) kmf_finalize(kmfhandle); 55799ebb4caSwyllys if (rv != KMF_OK) 55899ebb4caSwyllys return (PK_ERR_USAGE); 55999ebb4caSwyllys 56099ebb4caSwyllys return (0); 56199ebb4caSwyllys } 562