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 /* 22985be8f1Swyllys * Copyright 2007 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 3899ebb4caSwyllys #include <kmfapi.h> 3999ebb4caSwyllys 4099ebb4caSwyllys #define SET_VALUE(f, s) \ 4199ebb4caSwyllys kmfrv = f; \ 4299ebb4caSwyllys if (kmfrv != KMF_OK) { \ 4399ebb4caSwyllys cryptoerror(LOG_STDERR, \ 4499ebb4caSwyllys gettext("Failed to set %s: 0x%02x\n"), \ 4599ebb4caSwyllys s, kmfrv); \ 4699ebb4caSwyllys goto cleanup; \ 4799ebb4caSwyllys } 4899ebb4caSwyllys 4999ebb4caSwyllys static int 5099ebb4caSwyllys gencert_pkcs11(KMF_HANDLE_T kmfhandle, 5199ebb4caSwyllys char *token, char *subject, char *altname, 5299ebb4caSwyllys KMF_GENERALNAMECHOICES alttype, int altcrit, 5399ebb4caSwyllys char *certlabel, KMF_KEY_ALG keyAlg, 5499ebb4caSwyllys KMF_ALGORITHM_INDEX sigAlg, 5599ebb4caSwyllys int keylen, uint32_t ltime, KMF_BIGINT *serial, 5699ebb4caSwyllys uint16_t kubits, int kucrit, KMF_CREDENTIAL *tokencred) 5799ebb4caSwyllys { 5899ebb4caSwyllys KMF_RETURN kmfrv = KMF_OK; 5999ebb4caSwyllys KMF_KEY_HANDLE pubk, prik; 6099ebb4caSwyllys KMF_X509_CERTIFICATE signedCert; 6199ebb4caSwyllys KMF_X509_NAME certSubject; 6299ebb4caSwyllys KMF_X509_NAME certIssuer; 6399ebb4caSwyllys KMF_DATA x509DER; 64*30a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 65*30a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 66*30a5e8faSwyllys int numattr = 0; 67*30a5e8faSwyllys KMF_KEY_ALG keytype; 68*30a5e8faSwyllys uint32_t keylength; 6999ebb4caSwyllys 7099ebb4caSwyllys (void) memset(&signedCert, 0, sizeof (signedCert)); 7199ebb4caSwyllys (void) memset(&certSubject, 0, sizeof (certSubject)); 7299ebb4caSwyllys (void) memset(&certIssuer, 0, sizeof (certIssuer)); 7399ebb4caSwyllys (void) memset(&x509DER, 0, sizeof (x509DER)); 7499ebb4caSwyllys 7599ebb4caSwyllys /* If the subject name cannot be parsed, flag it now and exit */ 76*30a5e8faSwyllys if (kmf_dn_parser(subject, &certSubject) != KMF_OK) { 7799ebb4caSwyllys cryptoerror(LOG_STDERR, 7899ebb4caSwyllys gettext("Subject name cannot be parsed.\n")); 7999ebb4caSwyllys return (PK_ERR_USAGE); 8099ebb4caSwyllys } 8199ebb4caSwyllys 8299ebb4caSwyllys /* For a self-signed cert, the issuser and subject are the same */ 83*30a5e8faSwyllys if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) { 8499ebb4caSwyllys cryptoerror(LOG_STDERR, 8599ebb4caSwyllys gettext("Subject name cannot be parsed.\n")); 8699ebb4caSwyllys return (PK_ERR_USAGE); 8799ebb4caSwyllys } 8899ebb4caSwyllys 89*30a5e8faSwyllys keylength = keylen; /* bits */ 90*30a5e8faSwyllys keytype = keyAlg; 9199ebb4caSwyllys 9299ebb4caSwyllys /* Select a PKCS11 token */ 9399ebb4caSwyllys kmfrv = select_token(kmfhandle, token, FALSE); 9499ebb4caSwyllys 9599ebb4caSwyllys if (kmfrv != KMF_OK) { 9699ebb4caSwyllys return (kmfrv); 9799ebb4caSwyllys } 9899ebb4caSwyllys 99*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 100*30a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, 101*30a5e8faSwyllys sizeof (kstype)); 102*30a5e8faSwyllys numattr++; 103*30a5e8faSwyllys 104*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 105*30a5e8faSwyllys KMF_KEYALG_ATTR, &keytype, 106*30a5e8faSwyllys sizeof (keytype)); 107*30a5e8faSwyllys numattr++; 108*30a5e8faSwyllys 109*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 110*30a5e8faSwyllys KMF_KEYLENGTH_ATTR, &keylength, 111*30a5e8faSwyllys sizeof (keylength)); 112*30a5e8faSwyllys numattr++; 113*30a5e8faSwyllys 114*30a5e8faSwyllys if (certlabel != NULL) { 115*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 116*30a5e8faSwyllys KMF_KEYLABEL_ATTR, certlabel, 117*30a5e8faSwyllys strlen(certlabel)); 118*30a5e8faSwyllys numattr++; 119*30a5e8faSwyllys } 120*30a5e8faSwyllys 121*30a5e8faSwyllys if (tokencred != NULL && tokencred->credlen > 0) { 122*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 123*30a5e8faSwyllys KMF_CREDENTIAL_ATTR, tokencred, 124*30a5e8faSwyllys sizeof (KMF_CREDENTIAL)); 125*30a5e8faSwyllys numattr++; 126*30a5e8faSwyllys } 127*30a5e8faSwyllys 128*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 129*30a5e8faSwyllys KMF_PRIVKEY_HANDLE_ATTR, &prik, 130*30a5e8faSwyllys sizeof (KMF_KEY_HANDLE)); 131*30a5e8faSwyllys numattr++; 132*30a5e8faSwyllys 133*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 134*30a5e8faSwyllys KMF_PUBKEY_HANDLE_ATTR, &pubk, 135*30a5e8faSwyllys sizeof (KMF_KEY_HANDLE)); 136*30a5e8faSwyllys numattr++; 137*30a5e8faSwyllys 138*30a5e8faSwyllys kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); 13999ebb4caSwyllys if (kmfrv != KMF_OK) { 14099ebb4caSwyllys return (kmfrv); 14199ebb4caSwyllys } 14299ebb4caSwyllys 143*30a5e8faSwyllys SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert), 14499ebb4caSwyllys "keypair"); 14599ebb4caSwyllys 146*30a5e8faSwyllys SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number"); 14799ebb4caSwyllys 148*30a5e8faSwyllys SET_VALUE(kmf_set_cert_serial(&signedCert, serial), 14999ebb4caSwyllys "serial number"); 15099ebb4caSwyllys 151*30a5e8faSwyllys SET_VALUE(kmf_set_cert_validity(&signedCert, NULL, ltime), 15299ebb4caSwyllys "validity time"); 15399ebb4caSwyllys 154*30a5e8faSwyllys SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg), 15599ebb4caSwyllys "signature algorithm"); 15699ebb4caSwyllys 157*30a5e8faSwyllys SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject), 15899ebb4caSwyllys "subject name"); 15999ebb4caSwyllys 160*30a5e8faSwyllys SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer), 16199ebb4caSwyllys "issuer name"); 16299ebb4caSwyllys 16399ebb4caSwyllys if (altname != NULL) 164*30a5e8faSwyllys SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit, 16599ebb4caSwyllys alttype, altname), "subjectAltName"); 16699ebb4caSwyllys 16799ebb4caSwyllys if (kubits != 0) 168*30a5e8faSwyllys SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits), 16999ebb4caSwyllys "KeyUsage"); 17099ebb4caSwyllys 171*30a5e8faSwyllys /* 172*30a5e8faSwyllys * Construct attributes for the kmf_sign_cert operation. 173*30a5e8faSwyllys */ 174*30a5e8faSwyllys numattr = 0; 175*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 176*30a5e8faSwyllys &kstype, sizeof (kstype)); 177*30a5e8faSwyllys numattr++; 178*30a5e8faSwyllys 179*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 180*30a5e8faSwyllys &prik, sizeof (KMF_KEY_HANDLE_ATTR)); 181*30a5e8faSwyllys numattr++; 182*30a5e8faSwyllys 183*30a5e8faSwyllys /* cert data that is to be signed */ 184*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR, 185*30a5e8faSwyllys &signedCert, sizeof (KMF_X509_CERTIFICATE)); 186*30a5e8faSwyllys numattr++; 187*30a5e8faSwyllys 188*30a5e8faSwyllys /* output buffer for the signed cert */ 189*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 190*30a5e8faSwyllys &x509DER, sizeof (KMF_DATA)); 191*30a5e8faSwyllys numattr++; 192*30a5e8faSwyllys 193*30a5e8faSwyllys if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) != 194*30a5e8faSwyllys KMF_OK) { 19599ebb4caSwyllys goto cleanup; 19699ebb4caSwyllys } 19799ebb4caSwyllys 19899ebb4caSwyllys /* 19999ebb4caSwyllys * Store the cert in the DB. 20099ebb4caSwyllys */ 201*30a5e8faSwyllys numattr = 0; 202*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 203*30a5e8faSwyllys &kstype, sizeof (kstype)); 204*30a5e8faSwyllys numattr++; 205*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 206*30a5e8faSwyllys &x509DER, sizeof (KMF_DATA)); 207*30a5e8faSwyllys numattr++; 208*30a5e8faSwyllys 209*30a5e8faSwyllys if (certlabel != NULL) { 210*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR, 211*30a5e8faSwyllys certlabel, strlen(certlabel)); 212*30a5e8faSwyllys numattr++; 213*30a5e8faSwyllys } 214*30a5e8faSwyllys 215*30a5e8faSwyllys kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist); 216*30a5e8faSwyllys 21799ebb4caSwyllys 21899ebb4caSwyllys cleanup: 219*30a5e8faSwyllys kmf_free_data(&x509DER); 220*30a5e8faSwyllys kmf_free_dn(&certSubject); 221*30a5e8faSwyllys kmf_free_dn(&certIssuer); 22299ebb4caSwyllys return (kmfrv); 22399ebb4caSwyllys } 22499ebb4caSwyllys 22599ebb4caSwyllys static int 22699ebb4caSwyllys gencert_file(KMF_HANDLE_T kmfhandle, 22799ebb4caSwyllys KMF_KEY_ALG keyAlg, KMF_ALGORITHM_INDEX sigAlg, 22899ebb4caSwyllys int keylen, KMF_ENCODE_FORMAT fmt, 22999ebb4caSwyllys uint32_t ltime, char *subject, char *altname, 23099ebb4caSwyllys KMF_GENERALNAMECHOICES alttype, int altcrit, 23199ebb4caSwyllys KMF_BIGINT *serial, uint16_t kubits, int kucrit, 23299ebb4caSwyllys char *dir, char *outcert, char *outkey) 23399ebb4caSwyllys { 23499ebb4caSwyllys KMF_RETURN kmfrv; 23599ebb4caSwyllys KMF_KEY_HANDLE pubk, prik; 23699ebb4caSwyllys KMF_X509_CERTIFICATE signedCert; 23799ebb4caSwyllys KMF_X509_NAME certSubject; 23899ebb4caSwyllys KMF_X509_NAME certIssuer; 23999ebb4caSwyllys KMF_DATA x509DER; 24099ebb4caSwyllys char *fullcertpath = NULL; 24199ebb4caSwyllys char *fullkeypath = NULL; 242*30a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 243*30a5e8faSwyllys KMF_ATTRIBUTE attrlist[10]; 244*30a5e8faSwyllys int numattr = 0; 245*30a5e8faSwyllys KMF_KEY_ALG keytype; 246*30a5e8faSwyllys uint32_t keylength; 247*30a5e8faSwyllys KMF_ENCODE_FORMAT format; 24899ebb4caSwyllys 24999ebb4caSwyllys (void) memset(&signedCert, 0, sizeof (signedCert)); 25099ebb4caSwyllys (void) memset(&certSubject, 0, sizeof (certSubject)); 25199ebb4caSwyllys (void) memset(&certIssuer, 0, sizeof (certIssuer)); 25299ebb4caSwyllys (void) memset(&x509DER, 0, sizeof (x509DER)); 25399ebb4caSwyllys 25499ebb4caSwyllys if (EMPTYSTRING(outcert) || EMPTYSTRING(outkey)) { 25599ebb4caSwyllys cryptoerror(LOG_STDERR, 25699ebb4caSwyllys gettext("No output file was specified for " 25799ebb4caSwyllys "the cert or key\n")); 25899ebb4caSwyllys return (PK_ERR_USAGE); 25999ebb4caSwyllys } 26099ebb4caSwyllys if (dir != NULL) { 26199ebb4caSwyllys fullcertpath = get_fullpath(dir, outcert); 26299ebb4caSwyllys if (fullcertpath == NULL) { 26399ebb4caSwyllys cryptoerror(LOG_STDERR, 264*30a5e8faSwyllys gettext("Cannot create file %s in directory %s\n"), 265*30a5e8faSwyllys dir, outcert); 26699ebb4caSwyllys return (PK_ERR_USAGE); 26799ebb4caSwyllys } 26899ebb4caSwyllys } else { 26999ebb4caSwyllys fullcertpath = strdup(outcert); 27099ebb4caSwyllys } 27199ebb4caSwyllys if (verify_file(fullcertpath)) { 27299ebb4caSwyllys cryptoerror(LOG_STDERR, 27399ebb4caSwyllys gettext("Cannot write the indicated output " 274*30a5e8faSwyllys "certificate file (%s).\n"), fullcertpath); 27599ebb4caSwyllys free(fullcertpath); 27699ebb4caSwyllys return (PK_ERR_USAGE); 27799ebb4caSwyllys } 27899ebb4caSwyllys if (dir != NULL) { 27999ebb4caSwyllys fullkeypath = get_fullpath(dir, outkey); 28099ebb4caSwyllys if (fullkeypath == NULL) { 28199ebb4caSwyllys cryptoerror(LOG_STDERR, 282*30a5e8faSwyllys gettext("Cannot create file %s in directory %s\n"), 283*30a5e8faSwyllys dir, outkey); 28499ebb4caSwyllys free(fullcertpath); 28599ebb4caSwyllys return (PK_ERR_USAGE); 28699ebb4caSwyllys } 28799ebb4caSwyllys } else { 28899ebb4caSwyllys fullkeypath = strdup(outkey); 28999ebb4caSwyllys } 29099ebb4caSwyllys if (verify_file(fullkeypath)) { 29199ebb4caSwyllys cryptoerror(LOG_STDERR, 29299ebb4caSwyllys gettext("Cannot write the indicated output " 293*30a5e8faSwyllys "key file (%s).\n"), fullkeypath); 29499ebb4caSwyllys free(fullkeypath); 29599ebb4caSwyllys free(fullcertpath); 29699ebb4caSwyllys return (PK_ERR_USAGE); 29799ebb4caSwyllys } 29899ebb4caSwyllys 29999ebb4caSwyllys /* If the subject name cannot be parsed, flag it now and exit */ 300*30a5e8faSwyllys if (kmf_dn_parser(subject, &certSubject) != KMF_OK) { 30199ebb4caSwyllys cryptoerror(LOG_STDERR, 302*30a5e8faSwyllys gettext("Subject name cannot be parsed (%s)\n"), subject); 30399ebb4caSwyllys return (PK_ERR_USAGE); 30499ebb4caSwyllys } 30599ebb4caSwyllys 30699ebb4caSwyllys /* For a self-signed cert, the issuser and subject are the same */ 307*30a5e8faSwyllys if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) { 30899ebb4caSwyllys cryptoerror(LOG_STDERR, 309*30a5e8faSwyllys gettext("Subject name cannot be parsed (%s)\n"), subject); 310*30a5e8faSwyllys kmf_free_dn(&certSubject); 31199ebb4caSwyllys return (PK_ERR_USAGE); 31299ebb4caSwyllys } 31399ebb4caSwyllys 314*30a5e8faSwyllys keylength = keylen; /* bits */ 315*30a5e8faSwyllys keytype = keyAlg; 316*30a5e8faSwyllys format = fmt; 31799ebb4caSwyllys 318*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 319*30a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, 320*30a5e8faSwyllys sizeof (kstype)); 321*30a5e8faSwyllys numattr++; 32299ebb4caSwyllys 323*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 324*30a5e8faSwyllys KMF_KEYALG_ATTR, &keytype, 325*30a5e8faSwyllys sizeof (keytype)); 326*30a5e8faSwyllys numattr++; 327*30a5e8faSwyllys 328*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 329*30a5e8faSwyllys KMF_KEYLENGTH_ATTR, &keylength, 330*30a5e8faSwyllys sizeof (keylength)); 331*30a5e8faSwyllys numattr++; 332*30a5e8faSwyllys 333*30a5e8faSwyllys if (fullkeypath != NULL) { 334*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 335*30a5e8faSwyllys KMF_KEY_FILENAME_ATTR, fullkeypath, 336*30a5e8faSwyllys strlen(fullkeypath)); 337*30a5e8faSwyllys numattr++; 338*30a5e8faSwyllys } 339*30a5e8faSwyllys 340*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 341*30a5e8faSwyllys KMF_ENCODE_FORMAT_ATTR, &format, 342*30a5e8faSwyllys sizeof (format)); 343*30a5e8faSwyllys numattr++; 344*30a5e8faSwyllys 345*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 346*30a5e8faSwyllys KMF_PRIVKEY_HANDLE_ATTR, &prik, 347*30a5e8faSwyllys sizeof (KMF_KEY_HANDLE)); 348*30a5e8faSwyllys numattr++; 349*30a5e8faSwyllys 350*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 351*30a5e8faSwyllys KMF_PUBKEY_HANDLE_ATTR, &pubk, 352*30a5e8faSwyllys sizeof (KMF_KEY_HANDLE)); 353*30a5e8faSwyllys numattr++; 354*30a5e8faSwyllys 355*30a5e8faSwyllys kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); 35699ebb4caSwyllys if (kmfrv != KMF_OK) { 35799ebb4caSwyllys goto cleanup; 35899ebb4caSwyllys } 359*30a5e8faSwyllys 360*30a5e8faSwyllys SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert), 36199ebb4caSwyllys "keypair"); 36299ebb4caSwyllys 363*30a5e8faSwyllys SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number"); 36499ebb4caSwyllys 365*30a5e8faSwyllys SET_VALUE(kmf_set_cert_serial(&signedCert, serial), 36699ebb4caSwyllys "serial number"); 36799ebb4caSwyllys 368*30a5e8faSwyllys SET_VALUE(kmf_set_cert_validity(&signedCert, NULL, ltime), 36999ebb4caSwyllys "validity time"); 37099ebb4caSwyllys 371*30a5e8faSwyllys SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg), 37299ebb4caSwyllys "signature algorithm"); 37399ebb4caSwyllys 374*30a5e8faSwyllys SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject), 37599ebb4caSwyllys "subject name"); 37699ebb4caSwyllys 377*30a5e8faSwyllys SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer), 37899ebb4caSwyllys "issuer name"); 37999ebb4caSwyllys 38099ebb4caSwyllys if (altname != NULL) 381*30a5e8faSwyllys SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit, 38299ebb4caSwyllys alttype, altname), "subjectAltName"); 38399ebb4caSwyllys 38499ebb4caSwyllys if (kubits != 0) 385*30a5e8faSwyllys SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits), 38699ebb4caSwyllys "KeyUsage"); 387*30a5e8faSwyllys /* 388*30a5e8faSwyllys * Construct attributes for the kmf_sign_cert operation. 389*30a5e8faSwyllys */ 390*30a5e8faSwyllys numattr = 0; 391*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 392*30a5e8faSwyllys &kstype, sizeof (kstype)); 393*30a5e8faSwyllys numattr++; 39499ebb4caSwyllys 395*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 396*30a5e8faSwyllys &prik, sizeof (KMF_KEY_HANDLE_ATTR)); 397*30a5e8faSwyllys numattr++; 398*30a5e8faSwyllys 399*30a5e8faSwyllys /* cert data that is to be signed */ 400*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR, 401*30a5e8faSwyllys &signedCert, sizeof (KMF_X509_CERTIFICATE)); 402*30a5e8faSwyllys numattr++; 403*30a5e8faSwyllys 404*30a5e8faSwyllys /* output buffer for the signed cert */ 405*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 406*30a5e8faSwyllys &x509DER, sizeof (KMF_DATA)); 407*30a5e8faSwyllys numattr++; 408*30a5e8faSwyllys 409*30a5e8faSwyllys if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) != 410*30a5e8faSwyllys KMF_OK) { 41199ebb4caSwyllys goto cleanup; 41299ebb4caSwyllys } 41399ebb4caSwyllys 41499ebb4caSwyllys /* 41599ebb4caSwyllys * Store the cert in the DB. 41699ebb4caSwyllys */ 417*30a5e8faSwyllys numattr = 0; 418*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 419*30a5e8faSwyllys &kstype, sizeof (kstype)); 420*30a5e8faSwyllys numattr++; 421*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 422*30a5e8faSwyllys &x509DER, sizeof (KMF_DATA)); 423*30a5e8faSwyllys numattr++; 424*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_FILENAME_ATTR, 425*30a5e8faSwyllys fullcertpath, strlen(fullcertpath)); 426*30a5e8faSwyllys numattr++; 427*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, 428*30a5e8faSwyllys &fmt, sizeof (fmt)); 429*30a5e8faSwyllys numattr++; 430*30a5e8faSwyllys 431*30a5e8faSwyllys kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist); 43299ebb4caSwyllys 43399ebb4caSwyllys cleanup: 43499ebb4caSwyllys if (fullkeypath != NULL) 43599ebb4caSwyllys free(fullkeypath); 43699ebb4caSwyllys if (fullcertpath != NULL) 43799ebb4caSwyllys free(fullcertpath); 43899ebb4caSwyllys 439*30a5e8faSwyllys kmf_free_data(&x509DER); 440*30a5e8faSwyllys kmf_free_dn(&certSubject); 441*30a5e8faSwyllys kmf_free_dn(&certIssuer); 44299ebb4caSwyllys return (kmfrv); 44399ebb4caSwyllys } 44499ebb4caSwyllys 44599ebb4caSwyllys static KMF_RETURN 44699ebb4caSwyllys gencert_nss(KMF_HANDLE_T kmfhandle, 44799ebb4caSwyllys char *token, char *subject, char *altname, 44899ebb4caSwyllys KMF_GENERALNAMECHOICES alttype, int altcrit, 44999ebb4caSwyllys char *nickname, char *dir, char *prefix, 45099ebb4caSwyllys KMF_KEY_ALG keyAlg, 45199ebb4caSwyllys KMF_ALGORITHM_INDEX sigAlg, 45299ebb4caSwyllys int keylen, char *trust, 45399ebb4caSwyllys uint32_t ltime, KMF_BIGINT *serial, uint16_t kubits, 45499ebb4caSwyllys int kucrit, KMF_CREDENTIAL *tokencred) 45599ebb4caSwyllys { 45699ebb4caSwyllys KMF_RETURN kmfrv; 45799ebb4caSwyllys KMF_KEY_HANDLE pubk, prik; 45899ebb4caSwyllys KMF_X509_CERTIFICATE signedCert; 45999ebb4caSwyllys KMF_X509_NAME certSubject; 46099ebb4caSwyllys KMF_X509_NAME certIssuer; 46199ebb4caSwyllys KMF_DATA x509DER; 462*30a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; 463*30a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 464*30a5e8faSwyllys int numattr = 0; 465*30a5e8faSwyllys KMF_KEY_ALG keytype; 466*30a5e8faSwyllys uint32_t keylength; 46799ebb4caSwyllys 46899ebb4caSwyllys if (token == NULL) 46999ebb4caSwyllys token = DEFAULT_NSS_TOKEN; 47099ebb4caSwyllys 47199ebb4caSwyllys kmfrv = configure_nss(kmfhandle, dir, prefix); 47299ebb4caSwyllys if (kmfrv != KMF_OK) 47399ebb4caSwyllys return (kmfrv); 47499ebb4caSwyllys 47599ebb4caSwyllys (void) memset(&signedCert, 0, sizeof (signedCert)); 47699ebb4caSwyllys (void) memset(&certSubject, 0, sizeof (certSubject)); 47799ebb4caSwyllys (void) memset(&certIssuer, 0, sizeof (certIssuer)); 47899ebb4caSwyllys (void) memset(&x509DER, 0, sizeof (x509DER)); 47999ebb4caSwyllys 48099ebb4caSwyllys /* If the subject name cannot be parsed, flag it now and exit */ 481*30a5e8faSwyllys if (kmf_dn_parser(subject, &certSubject) != KMF_OK) { 48299ebb4caSwyllys cryptoerror(LOG_STDERR, 48399ebb4caSwyllys gettext("Subject name cannot be parsed.\n")); 48499ebb4caSwyllys return (PK_ERR_USAGE); 48599ebb4caSwyllys } 48699ebb4caSwyllys 48799ebb4caSwyllys /* For a self-signed cert, the issuser and subject are the same */ 488*30a5e8faSwyllys if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) { 48999ebb4caSwyllys cryptoerror(LOG_STDERR, 49099ebb4caSwyllys gettext("Subject name cannot be parsed.\n")); 49199ebb4caSwyllys return (PK_ERR_USAGE); 49299ebb4caSwyllys } 49399ebb4caSwyllys 494*30a5e8faSwyllys keylength = keylen; /* bits */ 495*30a5e8faSwyllys keytype = keyAlg; 49699ebb4caSwyllys 497*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 498*30a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, 499*30a5e8faSwyllys sizeof (kstype)); 500*30a5e8faSwyllys numattr++; 50199ebb4caSwyllys 502*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 503*30a5e8faSwyllys KMF_KEYALG_ATTR, &keytype, 504*30a5e8faSwyllys sizeof (keytype)); 505*30a5e8faSwyllys numattr++; 506*30a5e8faSwyllys 507*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 508*30a5e8faSwyllys KMF_KEYLENGTH_ATTR, &keylength, 509*30a5e8faSwyllys sizeof (keylength)); 510*30a5e8faSwyllys numattr++; 511*30a5e8faSwyllys 512*30a5e8faSwyllys if (nickname != NULL) { 513*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 514*30a5e8faSwyllys KMF_KEYLABEL_ATTR, nickname, 515*30a5e8faSwyllys strlen(nickname)); 516*30a5e8faSwyllys numattr++; 517*30a5e8faSwyllys } 518*30a5e8faSwyllys 519*30a5e8faSwyllys if (tokencred != NULL && tokencred->credlen > 0) { 520*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 521*30a5e8faSwyllys KMF_CREDENTIAL_ATTR, tokencred, 522*30a5e8faSwyllys sizeof (KMF_CREDENTIAL)); 523*30a5e8faSwyllys numattr++; 524*30a5e8faSwyllys } 525*30a5e8faSwyllys 526*30a5e8faSwyllys if (token != NULL) { 527*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 528*30a5e8faSwyllys KMF_TOKEN_LABEL_ATTR, token, 529*30a5e8faSwyllys strlen(token)); 530*30a5e8faSwyllys numattr++; 531*30a5e8faSwyllys } 532*30a5e8faSwyllys 533*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 534*30a5e8faSwyllys KMF_PRIVKEY_HANDLE_ATTR, &prik, 535*30a5e8faSwyllys sizeof (KMF_KEY_HANDLE)); 536*30a5e8faSwyllys numattr++; 537*30a5e8faSwyllys 538*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 539*30a5e8faSwyllys KMF_PUBKEY_HANDLE_ATTR, &pubk, 540*30a5e8faSwyllys sizeof (KMF_KEY_HANDLE)); 541*30a5e8faSwyllys numattr++; 542*30a5e8faSwyllys 543*30a5e8faSwyllys kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); 54499ebb4caSwyllys if (kmfrv != KMF_OK) { 54599ebb4caSwyllys return (kmfrv); 54699ebb4caSwyllys } 54799ebb4caSwyllys 548*30a5e8faSwyllys SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert), 54999ebb4caSwyllys "keypair"); 55099ebb4caSwyllys 551*30a5e8faSwyllys SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number"); 55299ebb4caSwyllys 553*30a5e8faSwyllys SET_VALUE(kmf_set_cert_serial(&signedCert, serial), 55499ebb4caSwyllys "serial number"); 55599ebb4caSwyllys 556*30a5e8faSwyllys SET_VALUE(kmf_set_cert_validity(&signedCert, NULL, ltime), 55799ebb4caSwyllys "validity time"); 55899ebb4caSwyllys 559*30a5e8faSwyllys SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg), 56099ebb4caSwyllys "signature algorithm"); 56199ebb4caSwyllys 562*30a5e8faSwyllys SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject), 56399ebb4caSwyllys "subject name"); 56499ebb4caSwyllys 565*30a5e8faSwyllys SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer), 56699ebb4caSwyllys "issuer name"); 56799ebb4caSwyllys 56899ebb4caSwyllys if (altname != NULL) 569*30a5e8faSwyllys SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit, 57099ebb4caSwyllys alttype, altname), "subjectAltName"); 57199ebb4caSwyllys 57299ebb4caSwyllys if (kubits) 573*30a5e8faSwyllys SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits), 57499ebb4caSwyllys "subjectAltName"); 57599ebb4caSwyllys 576*30a5e8faSwyllys /* 577*30a5e8faSwyllys * Construct attributes for the kmf_sign_cert operation. 578*30a5e8faSwyllys */ 579*30a5e8faSwyllys numattr = 0; 580*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 581*30a5e8faSwyllys &kstype, sizeof (kstype)); 582*30a5e8faSwyllys numattr++; 583*30a5e8faSwyllys 584*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 585*30a5e8faSwyllys &prik, sizeof (KMF_KEY_HANDLE_ATTR)); 586*30a5e8faSwyllys numattr++; 587*30a5e8faSwyllys 588*30a5e8faSwyllys /* cert data that is to be signed */ 589*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR, 590*30a5e8faSwyllys &signedCert, sizeof (KMF_X509_CERTIFICATE)); 591*30a5e8faSwyllys numattr++; 592*30a5e8faSwyllys 593*30a5e8faSwyllys /* output buffer for the signed cert */ 594*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 595*30a5e8faSwyllys &x509DER, sizeof (KMF_DATA)); 596*30a5e8faSwyllys numattr++; 597*30a5e8faSwyllys 598*30a5e8faSwyllys if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) != 599*30a5e8faSwyllys KMF_OK) { 60099ebb4caSwyllys goto cleanup; 60199ebb4caSwyllys } 60299ebb4caSwyllys 60399ebb4caSwyllys /* 60499ebb4caSwyllys * Store the cert in the DB. 60599ebb4caSwyllys */ 606*30a5e8faSwyllys numattr = 0; 607*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 608*30a5e8faSwyllys &kstype, sizeof (kstype)); 609*30a5e8faSwyllys numattr++; 610*30a5e8faSwyllys 611*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 612*30a5e8faSwyllys &x509DER, sizeof (KMF_DATA)); 613*30a5e8faSwyllys numattr++; 614*30a5e8faSwyllys 615*30a5e8faSwyllys if (nickname != NULL) { 616*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR, 617*30a5e8faSwyllys nickname, strlen(nickname)); 618*30a5e8faSwyllys numattr++; 619*30a5e8faSwyllys } 620*30a5e8faSwyllys 621*30a5e8faSwyllys if (trust != NULL) { 622*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_TRUSTFLAG_ATTR, 623*30a5e8faSwyllys trust, strlen(trust)); 624*30a5e8faSwyllys numattr++; 625*30a5e8faSwyllys } 626*30a5e8faSwyllys 627*30a5e8faSwyllys if (token != NULL) { 628*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, 629*30a5e8faSwyllys token, strlen(token)); 630*30a5e8faSwyllys numattr++; 631*30a5e8faSwyllys } 632*30a5e8faSwyllys 633*30a5e8faSwyllys kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist); 63499ebb4caSwyllys 63599ebb4caSwyllys cleanup: 636*30a5e8faSwyllys kmf_free_data(&x509DER); 637*30a5e8faSwyllys kmf_free_dn(&certSubject); 638*30a5e8faSwyllys kmf_free_dn(&certIssuer); 63999ebb4caSwyllys return (kmfrv); 64099ebb4caSwyllys } 64199ebb4caSwyllys 64299ebb4caSwyllys int 64399ebb4caSwyllys pk_gencert(int argc, char *argv[]) 64499ebb4caSwyllys { 64599ebb4caSwyllys int rv; 64699ebb4caSwyllys int opt; 64799ebb4caSwyllys extern int optind_av; 64899ebb4caSwyllys extern char *optarg_av; 64999ebb4caSwyllys KMF_KEYSTORE_TYPE kstype = 0; 65099ebb4caSwyllys char *subject = NULL; 65199ebb4caSwyllys char *tokenname = NULL; 65299ebb4caSwyllys char *dir = NULL; 65399ebb4caSwyllys char *prefix = NULL; 65499ebb4caSwyllys char *keytype = PK_DEFAULT_KEYTYPE; 65599ebb4caSwyllys int keylen = PK_DEFAULT_KEYLENGTH; 65699ebb4caSwyllys char *trust = NULL; 65799ebb4caSwyllys char *lifetime = NULL; 65899ebb4caSwyllys char *certlabel = NULL; 65999ebb4caSwyllys char *outcert = NULL; 66099ebb4caSwyllys char *outkey = NULL; 66199ebb4caSwyllys char *format = NULL; 66299ebb4caSwyllys char *serstr = NULL; 66399ebb4caSwyllys char *altname = NULL; 66499ebb4caSwyllys char *keyusagestr = NULL; 66599ebb4caSwyllys KMF_GENERALNAMECHOICES alttype = 0; 66699ebb4caSwyllys KMF_BIGINT serial = { NULL, 0 }; 66799ebb4caSwyllys uint32_t ltime; 66899ebb4caSwyllys KMF_HANDLE_T kmfhandle = NULL; 66999ebb4caSwyllys KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1; 67099ebb4caSwyllys KMF_KEY_ALG keyAlg = KMF_RSA; 67199ebb4caSwyllys KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_MD5WithRSA; 67299ebb4caSwyllys boolean_t interactive = B_FALSE; 67399ebb4caSwyllys char *subname = NULL; 67499ebb4caSwyllys KMF_CREDENTIAL tokencred = {NULL, 0}; 67599ebb4caSwyllys uint16_t kubits = 0; 67699ebb4caSwyllys int altcrit = 0, kucrit = 0; 67799ebb4caSwyllys 67899ebb4caSwyllys while ((opt = getopt_av(argc, argv, 67999ebb4caSwyllys "ik:(keystore)s:(subject)n:(nickname)A:(altname)" 68099ebb4caSwyllys "T:(token)d:(dir)p:(prefix)t:(keytype)y:(keylen)" 68199ebb4caSwyllys "r:(trust)L:(lifetime)l:(label)c:(outcert)" 68299ebb4caSwyllys "K:(outkey)S:(serial)F:(format)u:(keyusage)")) != EOF) { 68399ebb4caSwyllys 68499ebb4caSwyllys if (opt != 'i' && EMPTYSTRING(optarg_av)) 68599ebb4caSwyllys return (PK_ERR_USAGE); 68699ebb4caSwyllys 68799ebb4caSwyllys switch (opt) { 68899ebb4caSwyllys case 'A': 68999ebb4caSwyllys altname = optarg_av; 69099ebb4caSwyllys break; 69199ebb4caSwyllys case 'i': 69299ebb4caSwyllys if (interactive || subject) 69399ebb4caSwyllys return (PK_ERR_USAGE); 69499ebb4caSwyllys else 69599ebb4caSwyllys interactive = B_TRUE; 69699ebb4caSwyllys break; 69799ebb4caSwyllys case 'k': 69899ebb4caSwyllys kstype = KS2Int(optarg_av); 69999ebb4caSwyllys if (kstype == 0) 70099ebb4caSwyllys return (PK_ERR_USAGE); 70199ebb4caSwyllys break; 70299ebb4caSwyllys case 's': 70399ebb4caSwyllys if (interactive || subject) 70499ebb4caSwyllys return (PK_ERR_USAGE); 70599ebb4caSwyllys else 70699ebb4caSwyllys subject = optarg_av; 70799ebb4caSwyllys break; 70899ebb4caSwyllys case 'l': 70999ebb4caSwyllys case 'n': 71099ebb4caSwyllys if (certlabel) 71199ebb4caSwyllys return (PK_ERR_USAGE); 71299ebb4caSwyllys certlabel = optarg_av; 71399ebb4caSwyllys break; 71499ebb4caSwyllys case 'T': 71599ebb4caSwyllys if (tokenname) 71699ebb4caSwyllys return (PK_ERR_USAGE); 71799ebb4caSwyllys tokenname = optarg_av; 71899ebb4caSwyllys break; 71999ebb4caSwyllys case 'd': 72099ebb4caSwyllys if (dir) 72199ebb4caSwyllys return (PK_ERR_USAGE); 72299ebb4caSwyllys dir = optarg_av; 72399ebb4caSwyllys break; 72499ebb4caSwyllys case 'p': 72599ebb4caSwyllys if (prefix) 72699ebb4caSwyllys return (PK_ERR_USAGE); 72799ebb4caSwyllys prefix = optarg_av; 72899ebb4caSwyllys break; 72999ebb4caSwyllys case 't': 73099ebb4caSwyllys keytype = optarg_av; 73199ebb4caSwyllys break; 73299ebb4caSwyllys case 'u': 73399ebb4caSwyllys keyusagestr = optarg_av; 73499ebb4caSwyllys break; 73599ebb4caSwyllys case 'y': 73699ebb4caSwyllys if (sscanf(optarg_av, "%d", 73799ebb4caSwyllys &keylen) != 1) { 73899ebb4caSwyllys cryptoerror(LOG_STDERR, 73999ebb4caSwyllys gettext("key length must be" 74099ebb4caSwyllys "a numeric value (%s)\n"), 74199ebb4caSwyllys optarg_av); 74299ebb4caSwyllys return (PK_ERR_USAGE); 74399ebb4caSwyllys } 74499ebb4caSwyllys break; 74599ebb4caSwyllys case 'r': 74699ebb4caSwyllys if (trust) 74799ebb4caSwyllys return (PK_ERR_USAGE); 74899ebb4caSwyllys trust = optarg_av; 74999ebb4caSwyllys break; 75099ebb4caSwyllys case 'L': 75199ebb4caSwyllys if (lifetime) 75299ebb4caSwyllys return (PK_ERR_USAGE); 75399ebb4caSwyllys lifetime = optarg_av; 75499ebb4caSwyllys break; 75599ebb4caSwyllys case 'c': 75699ebb4caSwyllys if (outcert) 75799ebb4caSwyllys return (PK_ERR_USAGE); 75899ebb4caSwyllys outcert = optarg_av; 75999ebb4caSwyllys break; 76099ebb4caSwyllys case 'K': 76199ebb4caSwyllys if (outkey) 76299ebb4caSwyllys return (PK_ERR_USAGE); 76399ebb4caSwyllys outkey = optarg_av; 76499ebb4caSwyllys break; 76599ebb4caSwyllys case 'S': 76699ebb4caSwyllys serstr = optarg_av; 76799ebb4caSwyllys break; 76899ebb4caSwyllys case 'F': 76999ebb4caSwyllys if (format) 77099ebb4caSwyllys return (PK_ERR_USAGE); 77199ebb4caSwyllys format = optarg_av; 77299ebb4caSwyllys break; 77399ebb4caSwyllys default: 77499ebb4caSwyllys return (PK_ERR_USAGE); 77599ebb4caSwyllys } 77699ebb4caSwyllys } 77799ebb4caSwyllys 77899ebb4caSwyllys /* No additional args allowed. */ 77999ebb4caSwyllys argc -= optind_av; 78099ebb4caSwyllys argv += optind_av; 78199ebb4caSwyllys if (argc) { 78299ebb4caSwyllys return (PK_ERR_USAGE); 78399ebb4caSwyllys } 78499ebb4caSwyllys 785*30a5e8faSwyllys if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 78699ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n")); 78799ebb4caSwyllys return (PK_ERR_USAGE); 78899ebb4caSwyllys } 78999ebb4caSwyllys 79099ebb4caSwyllys /* Assume keystore = PKCS#11 if not specified. */ 79199ebb4caSwyllys if (kstype == 0) 79299ebb4caSwyllys kstype = KMF_KEYSTORE_PK11TOKEN; 79399ebb4caSwyllys 79499ebb4caSwyllys if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) && 79599ebb4caSwyllys EMPTYSTRING(certlabel)) { 79699ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("A label must be specified " 79799ebb4caSwyllys "to create a self-signed certificate.\n")); 79899ebb4caSwyllys return (PK_ERR_USAGE); 79999ebb4caSwyllys } else if (kstype == KMF_KEYSTORE_OPENSSL && EMPTYSTRING(outcert)) { 80099ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("A certificate filename must " 80199ebb4caSwyllys "be specified to create a self-signed certificate.\n")); 80299ebb4caSwyllys return (PK_ERR_USAGE); 80399ebb4caSwyllys } 80499ebb4caSwyllys 80599ebb4caSwyllys if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) { 80699ebb4caSwyllys cryptoerror(LOG_STDERR, 80799ebb4caSwyllys gettext("Error parsing format string (%s).\n"), 80899ebb4caSwyllys format); 80999ebb4caSwyllys return (PK_ERR_USAGE); 81099ebb4caSwyllys } 81199ebb4caSwyllys 81299ebb4caSwyllys if (Str2Lifetime(lifetime, <ime) != 0) { 81399ebb4caSwyllys cryptoerror(LOG_STDERR, 81499ebb4caSwyllys gettext("Error parsing lifetime string\n")); 81599ebb4caSwyllys return (PK_ERR_USAGE); 81699ebb4caSwyllys } 81799ebb4caSwyllys 81899ebb4caSwyllys if (Str2KeyType(keytype, &keyAlg, &sigAlg) != 0) { 81999ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("Unrecognized keytype (%s).\n"), 82099ebb4caSwyllys keytype); 82199ebb4caSwyllys return (PK_ERR_USAGE); 82299ebb4caSwyllys } 82399ebb4caSwyllys 82499ebb4caSwyllys 82599ebb4caSwyllys /* 82699ebb4caSwyllys * Check the subject name. 82799ebb4caSwyllys * If interactive is true, get it now interactively. 82899ebb4caSwyllys */ 82999ebb4caSwyllys if (interactive) { 83099ebb4caSwyllys if (get_subname(&subname) != KMF_OK) { 83199ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("Failed to get the " 83299ebb4caSwyllys "subject name interactively.\n")); 83399ebb4caSwyllys return (PK_ERR_USAGE); 83499ebb4caSwyllys } 83599ebb4caSwyllys } else { 83699ebb4caSwyllys if (EMPTYSTRING(subject)) { 83799ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("A subject name or " 83899ebb4caSwyllys "-i must be specified to create a self-signed " 83999ebb4caSwyllys "certificate.\n")); 84099ebb4caSwyllys return (PK_ERR_USAGE); 84199ebb4caSwyllys } else { 84299ebb4caSwyllys subname = strdup(subject); 84399ebb4caSwyllys if (subname == NULL) { 84499ebb4caSwyllys cryptoerror(LOG_STDERR, 84599ebb4caSwyllys gettext("Out of memory.\n")); 84699ebb4caSwyllys return (PK_ERR_SYSTEM); 84799ebb4caSwyllys } 84899ebb4caSwyllys } 84999ebb4caSwyllys } 85099ebb4caSwyllys 85199ebb4caSwyllys if (serstr == NULL) { 85299ebb4caSwyllys (void) fprintf(stderr, gettext("A serial number " 85399ebb4caSwyllys "must be specified as a hex number when creating" 85499ebb4caSwyllys " a self-signed certificate " 855985be8f1Swyllys "(ex: serial=0x0102030405feedface)\n")); 85699ebb4caSwyllys rv = PK_ERR_USAGE; 85799ebb4caSwyllys goto end; 85899ebb4caSwyllys } else { 85999ebb4caSwyllys uchar_t *bytes = NULL; 86099ebb4caSwyllys size_t bytelen; 86199ebb4caSwyllys 862*30a5e8faSwyllys rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen); 86399ebb4caSwyllys if (rv != KMF_OK || bytes == NULL) { 86499ebb4caSwyllys (void) fprintf(stderr, gettext("serial number " 86599ebb4caSwyllys "must be specified as a hex number " 86699ebb4caSwyllys "(ex: 0x0102030405ffeeddee)\n")); 86799ebb4caSwyllys rv = PK_ERR_USAGE; 86899ebb4caSwyllys goto end; 86999ebb4caSwyllys } 87099ebb4caSwyllys serial.val = bytes; 87199ebb4caSwyllys serial.len = bytelen; 87299ebb4caSwyllys } 87399ebb4caSwyllys 87499ebb4caSwyllys if (altname != NULL) { 87599ebb4caSwyllys rv = verify_altname(altname, &alttype, &altcrit); 87699ebb4caSwyllys if (rv != KMF_OK) { 87799ebb4caSwyllys (void) fprintf(stderr, gettext("Subject AltName " 87899ebb4caSwyllys "must be specified as a name=value pair. " 87999ebb4caSwyllys "See the man page for details.\n")); 88099ebb4caSwyllys rv = PK_ERR_USAGE; 88199ebb4caSwyllys goto end; 88299ebb4caSwyllys } else { 88399ebb4caSwyllys /* advance the altname past the '=' sign */ 88499ebb4caSwyllys char *p = strchr(altname, '='); 88599ebb4caSwyllys if (p != NULL) 88699ebb4caSwyllys altname = p + 1; 88799ebb4caSwyllys } 88899ebb4caSwyllys } 88999ebb4caSwyllys 89099ebb4caSwyllys if (keyusagestr != NULL) { 89199ebb4caSwyllys rv = verify_keyusage(keyusagestr, &kubits, &kucrit); 89299ebb4caSwyllys if (rv != KMF_OK) { 89399ebb4caSwyllys (void) fprintf(stderr, gettext("KeyUsage " 89499ebb4caSwyllys "must be specified as a comma-separated list. " 89599ebb4caSwyllys "See the man page for details.\n")); 89699ebb4caSwyllys rv = PK_ERR_USAGE; 89799ebb4caSwyllys goto end; 89899ebb4caSwyllys } 89999ebb4caSwyllys } 90099ebb4caSwyllys 90199ebb4caSwyllys if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) { 90299ebb4caSwyllys if (tokenname == NULL || !strlen(tokenname)) { 90399ebb4caSwyllys if (kstype == KMF_KEYSTORE_NSS) { 90499ebb4caSwyllys tokenname = "internal"; 90599ebb4caSwyllys } else { 90699ebb4caSwyllys tokenname = PK_DEFAULT_PK11TOKEN; 90799ebb4caSwyllys } 90899ebb4caSwyllys } 90999ebb4caSwyllys 91099ebb4caSwyllys (void) get_token_password(kstype, tokenname, &tokencred); 91199ebb4caSwyllys } 91299ebb4caSwyllys 91399ebb4caSwyllys if (kstype == KMF_KEYSTORE_NSS) { 91499ebb4caSwyllys if (dir == NULL) 91599ebb4caSwyllys dir = PK_DEFAULT_DIRECTORY; 91699ebb4caSwyllys 91799ebb4caSwyllys rv = gencert_nss(kmfhandle, 91899ebb4caSwyllys tokenname, subname, altname, alttype, altcrit, 91999ebb4caSwyllys certlabel, dir, prefix, keyAlg, sigAlg, keylen, 92099ebb4caSwyllys trust, ltime, &serial, kubits, kucrit, &tokencred); 92199ebb4caSwyllys 92299ebb4caSwyllys } else if (kstype == KMF_KEYSTORE_PK11TOKEN) { 92399ebb4caSwyllys rv = gencert_pkcs11(kmfhandle, 92499ebb4caSwyllys tokenname, subname, altname, alttype, altcrit, 92599ebb4caSwyllys certlabel, keyAlg, sigAlg, keylen, ltime, 92699ebb4caSwyllys &serial, kubits, kucrit, &tokencred); 92799ebb4caSwyllys 92899ebb4caSwyllys } else if (kstype == KMF_KEYSTORE_OPENSSL) { 92999ebb4caSwyllys rv = gencert_file(kmfhandle, 93099ebb4caSwyllys keyAlg, sigAlg, keylen, fmt, 93199ebb4caSwyllys ltime, subname, altname, alttype, altcrit, 93299ebb4caSwyllys &serial, kubits, kucrit, dir, outcert, outkey); 93399ebb4caSwyllys } 93499ebb4caSwyllys 93599ebb4caSwyllys if (rv != KMF_OK) 93699ebb4caSwyllys display_error(kmfhandle, rv, 93799ebb4caSwyllys gettext("Error creating certificate and keypair")); 93899ebb4caSwyllys end: 93999ebb4caSwyllys if (subname) 94099ebb4caSwyllys free(subname); 94199ebb4caSwyllys if (tokencred.cred != NULL) 94299ebb4caSwyllys free(tokencred.cred); 94399ebb4caSwyllys 94499ebb4caSwyllys if (serial.val != NULL) 94599ebb4caSwyllys free(serial.val); 94699ebb4caSwyllys 947*30a5e8faSwyllys (void) kmf_finalize(kmfhandle); 94899ebb4caSwyllys return (rv); 94999ebb4caSwyllys } 950