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 38*3089Swyllys #include <kmfapi.h> 39*3089Swyllys 40*3089Swyllys #define SET_VALUE(f, s) \ 41*3089Swyllys kmfrv = f; \ 42*3089Swyllys if (kmfrv != KMF_OK) { \ 43*3089Swyllys cryptoerror(LOG_STDERR, \ 44*3089Swyllys gettext("Failed to %s: 0x%02\n"), \ 45*3089Swyllys s, kmfrv); \ 46*3089Swyllys goto cleanup; \ 47*3089Swyllys } 48*3089Swyllys 49*3089Swyllys static KMF_RETURN 50*3089Swyllys gencsr_pkcs11(KMF_HANDLE_T kmfhandle, 51*3089Swyllys char *token, char *subject, char *altname, 52*3089Swyllys KMF_GENERALNAMECHOICES alttype, int altcrit, 53*3089Swyllys char *certlabel, KMF_KEY_ALG keyAlg, 54*3089Swyllys int keylen, 55*3089Swyllys uint16_t kubits, int kucrit, 56*3089Swyllys KMF_ENCODE_FORMAT fmt, char *csrfile, 57*3089Swyllys KMF_CREDENTIAL *tokencred) 58*3089Swyllys { 59*3089Swyllys KMF_RETURN kmfrv = KMF_OK; 60*3089Swyllys KMF_CREATEKEYPAIR_PARAMS kp_params; 61*3089Swyllys KMF_DELETEKEY_PARAMS dk_params; 62*3089Swyllys KMF_KEY_HANDLE pubk, prik; 63*3089Swyllys KMF_X509_NAME csrSubject; 64*3089Swyllys KMF_CSR_DATA csr; 65*3089Swyllys KMF_ALGORITHM_INDEX sigAlg; 66*3089Swyllys KMF_DATA signedCsr = {NULL, 0}; 67*3089Swyllys 68*3089Swyllys (void) memset(&csr, 0, sizeof (csr)); 69*3089Swyllys (void) memset(&csrSubject, 0, sizeof (csrSubject)); 70*3089Swyllys (void) memset(&kp_params, 0, sizeof (kp_params)); 71*3089Swyllys 72*3089Swyllys if (keyAlg == KMF_DSA) 73*3089Swyllys sigAlg = KMF_ALGID_SHA1WithDSA; 74*3089Swyllys else 75*3089Swyllys sigAlg = KMF_ALGID_MD5WithRSA; 76*3089Swyllys 77*3089Swyllys 78*3089Swyllys /* If the subject name cannot be parsed, flag it now and exit */ 79*3089Swyllys if ((kmfrv = KMF_DNParser(subject, &csrSubject)) != KMF_OK) { 80*3089Swyllys return (kmfrv); 81*3089Swyllys } 82*3089Swyllys 83*3089Swyllys kp_params.kstype = KMF_KEYSTORE_PK11TOKEN; 84*3089Swyllys kp_params.keylabel = certlabel; 85*3089Swyllys kp_params.keylength = keylen; /* bits */ 86*3089Swyllys kp_params.keytype = keyAlg; 87*3089Swyllys kp_params.cred.cred = tokencred->cred; 88*3089Swyllys kp_params.cred.credlen = tokencred->credlen; 89*3089Swyllys 90*3089Swyllys /* Select a PKCS11 token */ 91*3089Swyllys kmfrv = select_token(kmfhandle, token, FALSE); 92*3089Swyllys if (kmfrv != KMF_OK) { 93*3089Swyllys return (kmfrv); 94*3089Swyllys } 95*3089Swyllys 96*3089Swyllys kmfrv = KMF_CreateKeypair(kmfhandle, &kp_params, &prik, &pubk); 97*3089Swyllys if (kmfrv != KMF_OK) { 98*3089Swyllys return (kmfrv); 99*3089Swyllys } 100*3089Swyllys 101*3089Swyllys SET_VALUE(KMF_SetCSRPubKey(kmfhandle, &pubk, &csr), "keypair"); 102*3089Swyllys 103*3089Swyllys SET_VALUE(KMF_SetCSRVersion(&csr, 2), "version number"); 104*3089Swyllys 105*3089Swyllys SET_VALUE(KMF_SetCSRSubjectName(&csr, &csrSubject), 106*3089Swyllys "subject name"); 107*3089Swyllys 108*3089Swyllys SET_VALUE(KMF_SetCSRSignatureAlgorithm(&csr, sigAlg), 109*3089Swyllys "SignatureAlgorithm"); 110*3089Swyllys 111*3089Swyllys if (altname != NULL) { 112*3089Swyllys SET_VALUE(KMF_SetCSRSubjectAltName(&csr, altname, altcrit, 113*3089Swyllys alttype), "SetCSRSubjectAltName"); 114*3089Swyllys } 115*3089Swyllys 116*3089Swyllys if (kubits != 0) { 117*3089Swyllys SET_VALUE(KMF_SetCSRKeyUsage(&csr, kucrit, kubits), 118*3089Swyllys "SetCSRKeyUsage"); 119*3089Swyllys } 120*3089Swyllys 121*3089Swyllys if ((kmfrv = KMF_SignCSR(kmfhandle, &csr, &prik, &signedCsr)) == 122*3089Swyllys KMF_OK) { 123*3089Swyllys kmfrv = KMF_CreateCSRFile(&signedCsr, fmt, csrfile); 124*3089Swyllys } 125*3089Swyllys 126*3089Swyllys cleanup: 127*3089Swyllys (void) KMF_FreeData(&signedCsr); 128*3089Swyllys (void) KMF_FreeKMFKey(kmfhandle, &prik); 129*3089Swyllys /* delete the key */ 130*3089Swyllys (void) memset(&dk_params, 0, sizeof (dk_params)); 131*3089Swyllys dk_params.kstype = KMF_KEYSTORE_PK11TOKEN; 132*3089Swyllys (void) KMF_DeleteKeyFromKeystore(kmfhandle, &dk_params, &pubk); 133*3089Swyllys (void) KMF_FreeSignedCSR(&csr); 134*3089Swyllys 135*3089Swyllys return (kmfrv); 136*3089Swyllys } 137*3089Swyllys 138*3089Swyllys static KMF_RETURN 139*3089Swyllys gencsr_file(KMF_HANDLE_T kmfhandle, 140*3089Swyllys KMF_KEY_ALG keyAlg, 141*3089Swyllys int keylen, KMF_ENCODE_FORMAT fmt, 142*3089Swyllys char *subject, char *altname, KMF_GENERALNAMECHOICES alttype, 143*3089Swyllys int altcrit, uint16_t kubits, int kucrit, 144*3089Swyllys char *dir, char *outcsr, char *outkey) 145*3089Swyllys { 146*3089Swyllys KMF_RETURN kmfrv; 147*3089Swyllys KMF_CREATEKEYPAIR_PARAMS kp_params; 148*3089Swyllys KMF_KEY_HANDLE pubk, prik; 149*3089Swyllys KMF_X509_NAME csrSubject; 150*3089Swyllys KMF_CSR_DATA csr; 151*3089Swyllys KMF_ALGORITHM_INDEX sigAlg; 152*3089Swyllys KMF_DATA signedCsr = {NULL, 0}; 153*3089Swyllys char *fullcsrpath = NULL; 154*3089Swyllys char *fullkeypath = NULL; 155*3089Swyllys 156*3089Swyllys (void) memset(&csr, 0, sizeof (csr)); 157*3089Swyllys (void) memset(&csrSubject, 0, sizeof (csrSubject)); 158*3089Swyllys (void) memset(&kp_params, 0, sizeof (kp_params)); 159*3089Swyllys 160*3089Swyllys if (EMPTYSTRING(outcsr) || EMPTYSTRING(outkey)) { 161*3089Swyllys cryptoerror(LOG_STDERR, 162*3089Swyllys gettext("No output file was specified for " 163*3089Swyllys "the csr or key\n")); 164*3089Swyllys return (KMF_ERR_BAD_PARAMETER); 165*3089Swyllys } 166*3089Swyllys if (dir != NULL) { 167*3089Swyllys fullcsrpath = get_fullpath(dir, outcsr); 168*3089Swyllys if (fullcsrpath == NULL) { 169*3089Swyllys cryptoerror(LOG_STDERR, 170*3089Swyllys gettext("Cannot create file %s in " 171*3089Swyllys "directory %s\n"), dir, outcsr); 172*3089Swyllys return (PK_ERR_USAGE); 173*3089Swyllys } 174*3089Swyllys } else { 175*3089Swyllys fullcsrpath = strdup(outcsr); 176*3089Swyllys } 177*3089Swyllys if (verify_file(fullcsrpath)) { 178*3089Swyllys cryptoerror(LOG_STDERR, 179*3089Swyllys gettext("Cannot write the indicated output " 180*3089Swyllys "certificate file (%s).\n"), fullcsrpath); 181*3089Swyllys free(fullcsrpath); 182*3089Swyllys return (PK_ERR_USAGE); 183*3089Swyllys } 184*3089Swyllys if (dir != NULL) { 185*3089Swyllys fullkeypath = get_fullpath(dir, outkey); 186*3089Swyllys if (fullkeypath == NULL) { 187*3089Swyllys cryptoerror(LOG_STDERR, 188*3089Swyllys gettext("Cannot create file %s in " 189*3089Swyllys "directory %s\n"), dir, outkey); 190*3089Swyllys free(fullcsrpath); 191*3089Swyllys return (PK_ERR_USAGE); 192*3089Swyllys } 193*3089Swyllys } else { 194*3089Swyllys fullkeypath = strdup(outkey); 195*3089Swyllys } 196*3089Swyllys if (verify_file(fullcsrpath)) { 197*3089Swyllys cryptoerror(LOG_STDERR, 198*3089Swyllys gettext("Cannot write the indicated output " 199*3089Swyllys "key file (%s).\n"), fullkeypath); 200*3089Swyllys free(fullcsrpath); 201*3089Swyllys return (PK_ERR_USAGE); 202*3089Swyllys } 203*3089Swyllys 204*3089Swyllys if (keyAlg == KMF_DSA) 205*3089Swyllys sigAlg = KMF_ALGID_SHA1WithDSA; 206*3089Swyllys else 207*3089Swyllys sigAlg = KMF_ALGID_MD5WithRSA; 208*3089Swyllys 209*3089Swyllys /* If the subject name cannot be parsed, flag it now and exit */ 210*3089Swyllys if ((kmfrv = KMF_DNParser(subject, &csrSubject)) != KMF_OK) { 211*3089Swyllys return (kmfrv); 212*3089Swyllys } 213*3089Swyllys 214*3089Swyllys kp_params.kstype = KMF_KEYSTORE_OPENSSL; 215*3089Swyllys kp_params.keylength = keylen; /* bits */ 216*3089Swyllys kp_params.keytype = keyAlg; 217*3089Swyllys 218*3089Swyllys kp_params.sslparms.keyfile = fullkeypath; 219*3089Swyllys kp_params.sslparms.format = fmt; 220*3089Swyllys 221*3089Swyllys kmfrv = KMF_CreateKeypair(kmfhandle, &kp_params, &prik, &pubk); 222*3089Swyllys if (kmfrv != KMF_OK) { 223*3089Swyllys goto cleanup; 224*3089Swyllys } 225*3089Swyllys SET_VALUE(KMF_SetCSRPubKey(kmfhandle, &pubk, &csr), 226*3089Swyllys "SetCSRPubKey"); 227*3089Swyllys 228*3089Swyllys SET_VALUE(KMF_SetCSRVersion(&csr, 2), "SetCSRVersion"); 229*3089Swyllys 230*3089Swyllys SET_VALUE(KMF_SetCSRSubjectName(&csr, &csrSubject), 231*3089Swyllys "SetCSRSubjectName"); 232*3089Swyllys 233*3089Swyllys SET_VALUE(KMF_SetCSRSignatureAlgorithm(&csr, sigAlg), 234*3089Swyllys "SetCSRSignatureAlgorithm"); 235*3089Swyllys 236*3089Swyllys if (altname != NULL) { 237*3089Swyllys SET_VALUE(KMF_SetCSRSubjectAltName(&csr, altname, altcrit, 238*3089Swyllys alttype), "SetCSRSubjectAltName"); 239*3089Swyllys } 240*3089Swyllys if (kubits != NULL) { 241*3089Swyllys SET_VALUE(KMF_SetCSRKeyUsage(&csr, kucrit, kubits), 242*3089Swyllys "SetCSRKeyUsage"); 243*3089Swyllys } 244*3089Swyllys if ((kmfrv = KMF_SignCSR(kmfhandle, &csr, &prik, &signedCsr)) == 245*3089Swyllys KMF_OK) { 246*3089Swyllys kmfrv = KMF_CreateCSRFile(&signedCsr, fmt, fullcsrpath); 247*3089Swyllys } 248*3089Swyllys 249*3089Swyllys cleanup: 250*3089Swyllys if (fullkeypath) 251*3089Swyllys free(fullkeypath); 252*3089Swyllys if (fullcsrpath) 253*3089Swyllys free(fullcsrpath); 254*3089Swyllys 255*3089Swyllys KMF_FreeData(&signedCsr); 256*3089Swyllys KMF_FreeKMFKey(kmfhandle, &prik); 257*3089Swyllys KMF_FreeSignedCSR(&csr); 258*3089Swyllys 259*3089Swyllys return (kmfrv); 260*3089Swyllys } 261*3089Swyllys 262*3089Swyllys static KMF_RETURN 263*3089Swyllys gencsr_nss(KMF_HANDLE_T kmfhandle, 264*3089Swyllys char *token, char *subject, char *altname, 265*3089Swyllys KMF_GENERALNAMECHOICES alttype, int altcrit, 266*3089Swyllys char *nickname, char *dir, char *prefix, 267*3089Swyllys KMF_KEY_ALG keyAlg, int keylen, 268*3089Swyllys uint16_t kubits, int kucrit, 269*3089Swyllys KMF_ENCODE_FORMAT fmt, char *csrfile, 270*3089Swyllys KMF_CREDENTIAL *tokencred) 271*3089Swyllys { 272*3089Swyllys KMF_RETURN kmfrv; 273*3089Swyllys KMF_CREATEKEYPAIR_PARAMS kp_params; 274*3089Swyllys KMF_KEY_HANDLE pubk, prik; 275*3089Swyllys KMF_X509_NAME csrSubject; 276*3089Swyllys KMF_CSR_DATA csr; 277*3089Swyllys KMF_ALGORITHM_INDEX sigAlg; 278*3089Swyllys KMF_DATA signedCsr = {NULL, 0}; 279*3089Swyllys KMF_DELETEKEY_PARAMS dk_params; 280*3089Swyllys 281*3089Swyllys if (token == NULL) 282*3089Swyllys token = DEFAULT_NSS_TOKEN; 283*3089Swyllys 284*3089Swyllys if (keyAlg == KMF_DSA) 285*3089Swyllys sigAlg = KMF_ALGID_SHA1WithDSA; 286*3089Swyllys else 287*3089Swyllys sigAlg = KMF_ALGID_MD5WithRSA; 288*3089Swyllys 289*3089Swyllys kmfrv = configure_nss(kmfhandle, dir, prefix); 290*3089Swyllys if (kmfrv != KMF_OK) 291*3089Swyllys return (kmfrv); 292*3089Swyllys 293*3089Swyllys (void) memset(&csr, 0, sizeof (csr)); 294*3089Swyllys (void) memset(&csrSubject, 0, sizeof (csrSubject)); 295*3089Swyllys 296*3089Swyllys /* If the subject name cannot be parsed, flag it now and exit */ 297*3089Swyllys if ((kmfrv = KMF_DNParser(subject, &csrSubject)) != KMF_OK) { 298*3089Swyllys return (kmfrv); 299*3089Swyllys } 300*3089Swyllys 301*3089Swyllys (void) memset(&kp_params, 0, sizeof (kp_params)); 302*3089Swyllys 303*3089Swyllys kp_params.kstype = KMF_KEYSTORE_NSS; 304*3089Swyllys kp_params.keylabel = nickname; 305*3089Swyllys kp_params.keylength = keylen; /* bits */ 306*3089Swyllys kp_params.keytype = keyAlg; 307*3089Swyllys kp_params.cred.cred = tokencred->cred; 308*3089Swyllys kp_params.cred.credlen = tokencred->credlen; 309*3089Swyllys kp_params.nssparms.slotlabel = token; 310*3089Swyllys 311*3089Swyllys kmfrv = KMF_CreateKeypair(kmfhandle, &kp_params, &prik, &pubk); 312*3089Swyllys if (kmfrv != KMF_OK) { 313*3089Swyllys goto cleanup; 314*3089Swyllys } 315*3089Swyllys 316*3089Swyllys SET_VALUE(KMF_SetCSRPubKey(kmfhandle, &pubk, &csr), "SetCSRPubKey"); 317*3089Swyllys SET_VALUE(KMF_SetCSRVersion(&csr, 2), "SetCSRVersion"); 318*3089Swyllys SET_VALUE(KMF_SetCSRSubjectName(&csr, &csrSubject), 319*3089Swyllys "SetCSRSubjectName"); 320*3089Swyllys SET_VALUE(KMF_SetCSRSignatureAlgorithm(&csr, sigAlg), 321*3089Swyllys "SetCSRSignatureAlgorithm"); 322*3089Swyllys 323*3089Swyllys if (altname != NULL) { 324*3089Swyllys SET_VALUE(KMF_SetCSRSubjectAltName(&csr, altname, altcrit, 325*3089Swyllys alttype), "SetCSRSubjectAltName"); 326*3089Swyllys } 327*3089Swyllys if (kubits != NULL) { 328*3089Swyllys SET_VALUE(KMF_SetCSRKeyUsage(&csr, kucrit, kubits), 329*3089Swyllys "SetCSRKeyUsage"); 330*3089Swyllys } 331*3089Swyllys if ((kmfrv = KMF_SignCSR(kmfhandle, &csr, &prik, &signedCsr)) == 332*3089Swyllys KMF_OK) { 333*3089Swyllys kmfrv = KMF_CreateCSRFile(&signedCsr, fmt, csrfile); 334*3089Swyllys } 335*3089Swyllys 336*3089Swyllys cleanup: 337*3089Swyllys (void) KMF_FreeData(&signedCsr); 338*3089Swyllys (void) KMF_FreeKMFKey(kmfhandle, &prik); 339*3089Swyllys /* delete the key */ 340*3089Swyllys (void) memset(&dk_params, 0, sizeof (dk_params)); 341*3089Swyllys dk_params.kstype = KMF_KEYSTORE_NSS; 342*3089Swyllys dk_params.cred.cred = tokencred->cred; 343*3089Swyllys dk_params.cred.credlen = tokencred->credlen; 344*3089Swyllys dk_params.nssparms.slotlabel = token; 345*3089Swyllys (void) KMF_DeleteKeyFromKeystore(kmfhandle, &dk_params, &pubk); 346*3089Swyllys (void) KMF_FreeSignedCSR(&csr); 347*3089Swyllys 348*3089Swyllys return (kmfrv); 349*3089Swyllys } 350*3089Swyllys 351*3089Swyllys int 352*3089Swyllys pk_gencsr(int argc, char *argv[]) 353*3089Swyllys { 354*3089Swyllys KMF_RETURN rv; 355*3089Swyllys int opt; 356*3089Swyllys extern int optind_av; 357*3089Swyllys extern char *optarg_av; 358*3089Swyllys KMF_KEYSTORE_TYPE kstype = 0; 359*3089Swyllys char *subject = NULL; 360*3089Swyllys char *tokenname = NULL; 361*3089Swyllys char *dir = NULL; 362*3089Swyllys char *prefix = NULL; 363*3089Swyllys int keylen = PK_DEFAULT_KEYLENGTH; 364*3089Swyllys char *certlabel = NULL; 365*3089Swyllys char *outcsr = NULL; 366*3089Swyllys char *outkey = NULL; 367*3089Swyllys char *format = NULL; 368*3089Swyllys char *altname = NULL; 369*3089Swyllys char *kustr = NULL; 370*3089Swyllys uint16_t kubits = 0; 371*3089Swyllys char *keytype = PK_DEFAULT_KEYTYPE; 372*3089Swyllys KMF_HANDLE_T kmfhandle = NULL; 373*3089Swyllys KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1; 374*3089Swyllys KMF_KEY_ALG keyAlg = KMF_RSA; 375*3089Swyllys KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_MD5WithRSA; 376*3089Swyllys boolean_t interactive = B_FALSE; 377*3089Swyllys char *subname = NULL; 378*3089Swyllys KMF_CREDENTIAL tokencred = {NULL, 0}; 379*3089Swyllys KMF_GENERALNAMECHOICES alttype = 0; 380*3089Swyllys int altcrit = 0, kucrit = 0; 381*3089Swyllys 382*3089Swyllys while ((opt = getopt_av(argc, argv, 383*3089Swyllys "ik:(keystore)s:(subject)n:(nickname)A:(altname)" 384*3089Swyllys "u:(keyusage)T:(token)d:(dir)p:(prefix)t:(keytype)" 385*3089Swyllys "y:(keylen)l:(label)c:(outcsr)" 386*3089Swyllys "K:(outkey)F:(format)")) != EOF) { 387*3089Swyllys 388*3089Swyllys if (opt != 'i' && EMPTYSTRING(optarg_av)) 389*3089Swyllys return (PK_ERR_USAGE); 390*3089Swyllys 391*3089Swyllys switch (opt) { 392*3089Swyllys case 'A': 393*3089Swyllys altname = optarg_av; 394*3089Swyllys break; 395*3089Swyllys case 'i': 396*3089Swyllys if (interactive || subject) 397*3089Swyllys return (PK_ERR_USAGE); 398*3089Swyllys else 399*3089Swyllys interactive = B_TRUE; 400*3089Swyllys break; 401*3089Swyllys case 'k': 402*3089Swyllys kstype = KS2Int(optarg_av); 403*3089Swyllys if (kstype == 0) 404*3089Swyllys return (PK_ERR_USAGE); 405*3089Swyllys break; 406*3089Swyllys case 's': 407*3089Swyllys if (interactive || subject) 408*3089Swyllys return (PK_ERR_USAGE); 409*3089Swyllys else 410*3089Swyllys subject = optarg_av; 411*3089Swyllys break; 412*3089Swyllys case 'l': 413*3089Swyllys case 'n': 414*3089Swyllys if (certlabel) 415*3089Swyllys return (PK_ERR_USAGE); 416*3089Swyllys certlabel = optarg_av; 417*3089Swyllys break; 418*3089Swyllys case 'T': 419*3089Swyllys if (tokenname) 420*3089Swyllys return (PK_ERR_USAGE); 421*3089Swyllys tokenname = optarg_av; 422*3089Swyllys break; 423*3089Swyllys case 'd': 424*3089Swyllys dir = optarg_av; 425*3089Swyllys break; 426*3089Swyllys case 'p': 427*3089Swyllys if (prefix) 428*3089Swyllys return (PK_ERR_USAGE); 429*3089Swyllys prefix = optarg_av; 430*3089Swyllys break; 431*3089Swyllys case 't': 432*3089Swyllys keytype = optarg_av; 433*3089Swyllys break; 434*3089Swyllys case 'u': 435*3089Swyllys kustr = optarg_av; 436*3089Swyllys break; 437*3089Swyllys case 'y': 438*3089Swyllys if (sscanf(optarg_av, "%d", 439*3089Swyllys &keylen) != 1) { 440*3089Swyllys cryptoerror(LOG_STDERR, 441*3089Swyllys gettext("Unrecognized " 442*3089Swyllys "key length (%s)\n"), 443*3089Swyllys optarg_av); 444*3089Swyllys return (PK_ERR_USAGE); 445*3089Swyllys } 446*3089Swyllys break; 447*3089Swyllys case 'c': 448*3089Swyllys if (outcsr) 449*3089Swyllys return (PK_ERR_USAGE); 450*3089Swyllys outcsr = optarg_av; 451*3089Swyllys break; 452*3089Swyllys case 'K': 453*3089Swyllys if (outkey) 454*3089Swyllys return (PK_ERR_USAGE); 455*3089Swyllys outkey = optarg_av; 456*3089Swyllys break; 457*3089Swyllys case 'F': 458*3089Swyllys if (format) 459*3089Swyllys return (PK_ERR_USAGE); 460*3089Swyllys format = optarg_av; 461*3089Swyllys break; 462*3089Swyllys default: 463*3089Swyllys cryptoerror(LOG_STDERR, gettext( 464*3089Swyllys "unrecognized gencsr option '%s'\n"), 465*3089Swyllys argv[optind_av]); 466*3089Swyllys return (PK_ERR_USAGE); 467*3089Swyllys } 468*3089Swyllys } 469*3089Swyllys /* No additional args allowed. */ 470*3089Swyllys argc -= optind_av; 471*3089Swyllys argv += optind_av; 472*3089Swyllys if (argc) { 473*3089Swyllys return (PK_ERR_USAGE); 474*3089Swyllys } 475*3089Swyllys 476*3089Swyllys if ((rv = KMF_Initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 477*3089Swyllys cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n")); 478*3089Swyllys return (PK_ERR_USAGE); 479*3089Swyllys } 480*3089Swyllys 481*3089Swyllys /* Assume keystore = PKCS#11 if not specified. */ 482*3089Swyllys if (kstype == 0) 483*3089Swyllys kstype = KMF_KEYSTORE_PK11TOKEN; 484*3089Swyllys 485*3089Swyllys if (EMPTYSTRING(outcsr)) { 486*3089Swyllys (void) printf(gettext("A filename must be specified to hold" 487*3089Swyllys "the final certificate request data.\n")); 488*3089Swyllys return (PK_ERR_USAGE); 489*3089Swyllys } else { 490*3089Swyllys /* 491*3089Swyllys * verify that the outcsr file does not already exist 492*3089Swyllys * and that it can be created. 493*3089Swyllys */ 494*3089Swyllys rv = verify_file(outcsr); 495*3089Swyllys if (rv != KMF_OK) { 496*3089Swyllys cryptoerror(LOG_STDERR, gettext("output file (%s) " 497*3089Swyllys "cannot be created.\n"), outcsr); 498*3089Swyllys return (PK_ERR_USAGE); 499*3089Swyllys } 500*3089Swyllys } 501*3089Swyllys 502*3089Swyllys if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) && 503*3089Swyllys EMPTYSTRING(certlabel)) { 504*3089Swyllys cryptoerror(LOG_STDERR, gettext("A label must be specified " 505*3089Swyllys "to create a certificate request.\n")); 506*3089Swyllys return (PK_ERR_USAGE); 507*3089Swyllys } else if (kstype == KMF_KEYSTORE_OPENSSL && EMPTYSTRING(outkey)) { 508*3089Swyllys cryptoerror(LOG_STDERR, gettext("A key filename must be " 509*3089Swyllys "specified to create a certificate request.\n")); 510*3089Swyllys return (PK_ERR_USAGE); 511*3089Swyllys } 512*3089Swyllys 513*3089Swyllys if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) { 514*3089Swyllys cryptoerror(LOG_STDERR, 515*3089Swyllys gettext("Error parsing format string (%s).\n"), 516*3089Swyllys format); 517*3089Swyllys return (PK_ERR_USAGE); 518*3089Swyllys } 519*3089Swyllys if (format && fmt != KMF_FORMAT_ASN1 && fmt != KMF_FORMAT_PEM) { 520*3089Swyllys cryptoerror(LOG_STDERR, 521*3089Swyllys gettext("CSR must be DER or PEM format.\n")); 522*3089Swyllys return (PK_ERR_USAGE); 523*3089Swyllys } 524*3089Swyllys 525*3089Swyllys /* 526*3089Swyllys * Check the subject name. 527*3089Swyllys * If interactive is true, get it now interactively. 528*3089Swyllys */ 529*3089Swyllys if (interactive) { 530*3089Swyllys if (get_subname(&subname) != KMF_OK) { 531*3089Swyllys cryptoerror(LOG_STDERR, gettext("Failed to get the " 532*3089Swyllys "subject name interactively.\n")); 533*3089Swyllys return (PK_ERR_USAGE); 534*3089Swyllys } 535*3089Swyllys } else { 536*3089Swyllys if (EMPTYSTRING(subject)) { 537*3089Swyllys cryptoerror(LOG_STDERR, gettext("A subject name or " 538*3089Swyllys "-i must be specified to create a certificate " 539*3089Swyllys "request.\n")); 540*3089Swyllys return (PK_ERR_USAGE); 541*3089Swyllys } else { 542*3089Swyllys subname = strdup(subject); 543*3089Swyllys if (subname == NULL) { 544*3089Swyllys cryptoerror(LOG_STDERR, 545*3089Swyllys gettext("Out of memory.\n")); 546*3089Swyllys return (PK_ERR_SYSTEM); 547*3089Swyllys } 548*3089Swyllys } 549*3089Swyllys } 550*3089Swyllys if (altname != NULL) { 551*3089Swyllys rv = verify_altname(altname, &alttype, &altcrit); 552*3089Swyllys if (rv != KMF_OK) { 553*3089Swyllys cryptoerror(LOG_STDERR, gettext("Subject AltName " 554*3089Swyllys "must be specified as a name=value pair. " 555*3089Swyllys "See the man page for details.")); 556*3089Swyllys goto end; 557*3089Swyllys } else { 558*3089Swyllys /* advance the altname past the '=' sign */ 559*3089Swyllys char *p = strchr(altname, '='); 560*3089Swyllys if (p != NULL) 561*3089Swyllys altname = p + 1; 562*3089Swyllys } 563*3089Swyllys } 564*3089Swyllys 565*3089Swyllys if (kustr != NULL) { 566*3089Swyllys rv = verify_keyusage(kustr, &kubits, &kucrit); 567*3089Swyllys if (rv != KMF_OK) { 568*3089Swyllys cryptoerror(LOG_STDERR, gettext("KeyUsage " 569*3089Swyllys "must be specified as a comma-separated list. " 570*3089Swyllys "See the man page for details.")); 571*3089Swyllys goto end; 572*3089Swyllys } 573*3089Swyllys } 574*3089Swyllys if ((rv = Str2KeyType(keytype, &keyAlg, &sigAlg)) != 0) { 575*3089Swyllys cryptoerror(LOG_STDERR, gettext("Unrecognized keytype (%s).\n"), 576*3089Swyllys keytype); 577*3089Swyllys goto end; 578*3089Swyllys } 579*3089Swyllys 580*3089Swyllys if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) { 581*3089Swyllys if (tokenname == NULL || !strlen(tokenname)) { 582*3089Swyllys if (kstype == KMF_KEYSTORE_NSS) { 583*3089Swyllys tokenname = "internal"; 584*3089Swyllys } else { 585*3089Swyllys tokenname = PK_DEFAULT_PK11TOKEN; 586*3089Swyllys } 587*3089Swyllys } 588*3089Swyllys 589*3089Swyllys (void) get_token_password(kstype, tokenname, &tokencred); 590*3089Swyllys } 591*3089Swyllys 592*3089Swyllys if (kstype == KMF_KEYSTORE_NSS) { 593*3089Swyllys if (dir == NULL) 594*3089Swyllys dir = PK_DEFAULT_DIRECTORY; 595*3089Swyllys 596*3089Swyllys rv = gencsr_nss(kmfhandle, 597*3089Swyllys tokenname, subname, altname, alttype, altcrit, 598*3089Swyllys certlabel, dir, prefix, 599*3089Swyllys keyAlg, keylen, kubits, kucrit, 600*3089Swyllys fmt, outcsr, &tokencred); 601*3089Swyllys 602*3089Swyllys } else if (kstype == KMF_KEYSTORE_PK11TOKEN) { 603*3089Swyllys rv = gencsr_pkcs11(kmfhandle, 604*3089Swyllys tokenname, subname, altname, alttype, altcrit, 605*3089Swyllys certlabel, keyAlg, keylen, 606*3089Swyllys kubits, kucrit, fmt, outcsr, &tokencred); 607*3089Swyllys 608*3089Swyllys } else if (kstype == KMF_KEYSTORE_OPENSSL) { 609*3089Swyllys rv = gencsr_file(kmfhandle, 610*3089Swyllys keyAlg, keylen, fmt, subname, altname, 611*3089Swyllys alttype, altcrit, kubits, kucrit, 612*3089Swyllys dir, outcsr, outkey); 613*3089Swyllys } 614*3089Swyllys 615*3089Swyllys end: 616*3089Swyllys if (rv != KMF_OK) 617*3089Swyllys display_error(kmfhandle, rv, 618*3089Swyllys gettext("Error creating CSR or keypair")); 619*3089Swyllys 620*3089Swyllys if (subname) 621*3089Swyllys free(subname); 622*3089Swyllys 623*3089Swyllys if (tokencred.cred != NULL) 624*3089Swyllys free(tokencred.cred); 625*3089Swyllys 626*3089Swyllys (void) KMF_Finalize(kmfhandle); 627*3089Swyllys if (rv != KMF_OK) 628*3089Swyllys return (PK_ERR_USAGE); 629*3089Swyllys 630*3089Swyllys return (0); 631*3089Swyllys } 632