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