13089Swyllys /* 23089Swyllys * CDDL HEADER START 33089Swyllys * 43089Swyllys * The contents of this file are subject to the terms of the 53089Swyllys * Common Development and Distribution License (the "License"). 63089Swyllys * You may not use this file except in compliance with the License. 73089Swyllys * 83089Swyllys * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 93089Swyllys * or http://www.opensolaris.org/os/licensing. 103089Swyllys * See the License for the specific language governing permissions 113089Swyllys * and limitations under the License. 123089Swyllys * 133089Swyllys * When distributing Covered Code, include this CDDL HEADER in each 143089Swyllys * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 153089Swyllys * If applicable, add the following below this CDDL HEADER, with the 163089Swyllys * fields enclosed by brackets "[]" replaced with your own identifying 173089Swyllys * information: Portions Copyright [yyyy] [name of copyright owner] 183089Swyllys * 193089Swyllys * CDDL HEADER END 203089Swyllys */ 213089Swyllys /* 22*11973Swyllys.ingersoll@sun.com * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 233089Swyllys * Use is subject to license terms. 243089Swyllys */ 253089Swyllys 263089Swyllys #include <stdio.h> 273089Swyllys #include <string.h> 283089Swyllys #include <ctype.h> 293089Swyllys #include <malloc.h> 303089Swyllys #include <libgen.h> 313089Swyllys #include <errno.h> 323089Swyllys #include <cryptoutil.h> 333089Swyllys #include <security/cryptoki.h> 343089Swyllys #include "common.h" 353089Swyllys 363089Swyllys #include <kmfapi.h> 373089Swyllys 383089Swyllys #define SET_VALUE(f, s) \ 393089Swyllys kmfrv = f; \ 403089Swyllys if (kmfrv != KMF_OK) { \ 413089Swyllys cryptoerror(LOG_STDERR, \ 423089Swyllys gettext("Failed to set %s: 0x%02x\n"), \ 433089Swyllys s, kmfrv); \ 443089Swyllys goto cleanup; \ 453089Swyllys } 463089Swyllys 473089Swyllys static int 483089Swyllys gencert_pkcs11(KMF_HANDLE_T kmfhandle, 493089Swyllys char *token, char *subject, char *altname, 503089Swyllys KMF_GENERALNAMECHOICES alttype, int altcrit, 513089Swyllys char *certlabel, KMF_KEY_ALG keyAlg, 523089Swyllys KMF_ALGORITHM_INDEX sigAlg, 533089Swyllys int keylen, uint32_t ltime, KMF_BIGINT *serial, 546051Swyllys uint16_t kubits, int kucrit, KMF_CREDENTIAL *tokencred, 55*11973Swyllys.ingersoll@sun.com EKU_LIST *ekulist, KMF_OID *curveoid) 563089Swyllys { 573089Swyllys KMF_RETURN kmfrv = KMF_OK; 583089Swyllys KMF_KEY_HANDLE pubk, prik; 593089Swyllys KMF_X509_CERTIFICATE signedCert; 603089Swyllys KMF_X509_NAME certSubject; 613089Swyllys KMF_X509_NAME certIssuer; 623089Swyllys KMF_DATA x509DER; 635051Swyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 645051Swyllys KMF_ATTRIBUTE attrlist[16]; 655051Swyllys int numattr = 0; 665051Swyllys KMF_KEY_ALG keytype; 675051Swyllys uint32_t keylength; 683089Swyllys 693089Swyllys (void) memset(&signedCert, 0, sizeof (signedCert)); 703089Swyllys (void) memset(&certSubject, 0, sizeof (certSubject)); 713089Swyllys (void) memset(&certIssuer, 0, sizeof (certIssuer)); 723089Swyllys (void) memset(&x509DER, 0, sizeof (x509DER)); 733089Swyllys 743089Swyllys /* If the subject name cannot be parsed, flag it now and exit */ 755051Swyllys if (kmf_dn_parser(subject, &certSubject) != KMF_OK) { 763089Swyllys cryptoerror(LOG_STDERR, 775051Swyllys gettext("Subject name cannot be parsed.\n")); 783089Swyllys return (PK_ERR_USAGE); 793089Swyllys } 803089Swyllys 813089Swyllys /* For a self-signed cert, the issuser and subject are the same */ 825051Swyllys if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) { 833089Swyllys cryptoerror(LOG_STDERR, 845051Swyllys gettext("Subject name cannot be parsed.\n")); 853089Swyllys return (PK_ERR_USAGE); 863089Swyllys } 873089Swyllys 885051Swyllys keylength = keylen; /* bits */ 895051Swyllys keytype = keyAlg; 903089Swyllys 913089Swyllys /* Select a PKCS11 token */ 923089Swyllys kmfrv = select_token(kmfhandle, token, FALSE); 933089Swyllys if (kmfrv != KMF_OK) { 943089Swyllys return (kmfrv); 953089Swyllys } 963089Swyllys 97*11973Swyllys.ingersoll@sun.com /* 98*11973Swyllys.ingersoll@sun.com * Share the "genkeypair" routine for creating the keypair. 99*11973Swyllys.ingersoll@sun.com */ 100*11973Swyllys.ingersoll@sun.com kmfrv = genkeypair_pkcs11(kmfhandle, token, certlabel, 101*11973Swyllys.ingersoll@sun.com keytype, keylength, tokencred, curveoid, &prik, &pubk); 102*11973Swyllys.ingersoll@sun.com if (kmfrv != KMF_OK) 1033089Swyllys return (kmfrv); 1043089Swyllys 1055051Swyllys SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert), 1065051Swyllys "keypair"); 1073089Swyllys 1085051Swyllys SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number"); 1093089Swyllys 1105051Swyllys SET_VALUE(kmf_set_cert_serial(&signedCert, serial), 1115051Swyllys "serial number"); 1123089Swyllys 1135051Swyllys SET_VALUE(kmf_set_cert_validity(&signedCert, NULL, ltime), 1145051Swyllys "validity time"); 1153089Swyllys 1165051Swyllys SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg), 1175051Swyllys "signature algorithm"); 1183089Swyllys 1195051Swyllys SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject), 1205051Swyllys "subject name"); 1213089Swyllys 1225051Swyllys SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer), 1235051Swyllys "issuer name"); 1243089Swyllys 1253089Swyllys if (altname != NULL) 1265051Swyllys SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit, 1275051Swyllys alttype, altname), "subjectAltName"); 1283089Swyllys 1293089Swyllys if (kubits != 0) 1305051Swyllys SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits), 1315051Swyllys "KeyUsage"); 1325051Swyllys 1336051Swyllys if (ekulist != NULL) { 1346051Swyllys int i; 1356051Swyllys for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) { 1366051Swyllys SET_VALUE(kmf_add_cert_eku(&signedCert, 1376051Swyllys &ekulist->ekulist[i], ekulist->critlist[i]), 1386051Swyllys "Extended Key Usage"); 1396051Swyllys } 1406051Swyllys } 1416051Swyllys 1425051Swyllys /* 1435051Swyllys * Construct attributes for the kmf_sign_cert operation. 1445051Swyllys */ 1455051Swyllys numattr = 0; 1465051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 1475051Swyllys &kstype, sizeof (kstype)); 1485051Swyllys numattr++; 1493089Swyllys 1505051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 1515051Swyllys &prik, sizeof (KMF_KEY_HANDLE_ATTR)); 1525051Swyllys numattr++; 1535051Swyllys 1545051Swyllys /* cert data that is to be signed */ 1555051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR, 1565051Swyllys &signedCert, sizeof (KMF_X509_CERTIFICATE)); 1575051Swyllys numattr++; 1585051Swyllys 1595051Swyllys /* output buffer for the signed cert */ 1605051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 1615051Swyllys &x509DER, sizeof (KMF_DATA)); 1625051Swyllys numattr++; 1635051Swyllys 1645051Swyllys if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) != 1655051Swyllys KMF_OK) { 1663089Swyllys goto cleanup; 1673089Swyllys } 1683089Swyllys 1693089Swyllys /* 1703089Swyllys * Store the cert in the DB. 1713089Swyllys */ 1725051Swyllys numattr = 0; 1735051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 1745051Swyllys &kstype, sizeof (kstype)); 1755051Swyllys numattr++; 1765051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 1775051Swyllys &x509DER, sizeof (KMF_DATA)); 1785051Swyllys numattr++; 1795051Swyllys 1805051Swyllys if (certlabel != NULL) { 1815051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR, 1825051Swyllys certlabel, strlen(certlabel)); 1835051Swyllys numattr++; 1845051Swyllys } 1855051Swyllys 1865051Swyllys kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist); 1875051Swyllys 1883089Swyllys cleanup: 1895051Swyllys kmf_free_data(&x509DER); 1905051Swyllys kmf_free_dn(&certSubject); 1915051Swyllys kmf_free_dn(&certIssuer); 1929145SHuie-Ying.Lee@Sun.COM 1939145SHuie-Ying.Lee@Sun.COM /* 1949145SHuie-Ying.Lee@Sun.COM * If kmf_sign_cert or kmf_store_cert failed, then we need to clean up 1959145SHuie-Ying.Lee@Sun.COM * the key pair from the token. 1969145SHuie-Ying.Lee@Sun.COM */ 1979145SHuie-Ying.Lee@Sun.COM if (kmfrv != KMF_OK) { 1989145SHuie-Ying.Lee@Sun.COM /* delete the public key */ 1999145SHuie-Ying.Lee@Sun.COM numattr = 0; 2009145SHuie-Ying.Lee@Sun.COM kmf_set_attr_at_index(attrlist, numattr, 2019145SHuie-Ying.Lee@Sun.COM KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 2029145SHuie-Ying.Lee@Sun.COM numattr++; 2039145SHuie-Ying.Lee@Sun.COM 2049145SHuie-Ying.Lee@Sun.COM kmf_set_attr_at_index(attrlist, numattr, 2059145SHuie-Ying.Lee@Sun.COM KMF_KEY_HANDLE_ATTR, &pubk, sizeof (KMF_KEY_HANDLE)); 2069145SHuie-Ying.Lee@Sun.COM numattr++; 2079145SHuie-Ying.Lee@Sun.COM 2089145SHuie-Ying.Lee@Sun.COM if (tokencred != NULL && tokencred->cred != NULL) { 2099145SHuie-Ying.Lee@Sun.COM kmf_set_attr_at_index(attrlist, numattr, 2109145SHuie-Ying.Lee@Sun.COM KMF_CREDENTIAL_ATTR, tokencred, 2119145SHuie-Ying.Lee@Sun.COM sizeof (KMF_CREDENTIAL)); 2129145SHuie-Ying.Lee@Sun.COM numattr++; 2139145SHuie-Ying.Lee@Sun.COM } 2149145SHuie-Ying.Lee@Sun.COM 2159145SHuie-Ying.Lee@Sun.COM (void) kmf_delete_key_from_keystore(kmfhandle, numattr, 2169145SHuie-Ying.Lee@Sun.COM attrlist); 2179145SHuie-Ying.Lee@Sun.COM 2189145SHuie-Ying.Lee@Sun.COM /* delete the private key */ 2199145SHuie-Ying.Lee@Sun.COM numattr = 0; 2209145SHuie-Ying.Lee@Sun.COM kmf_set_attr_at_index(attrlist, numattr, 2219145SHuie-Ying.Lee@Sun.COM KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 2229145SHuie-Ying.Lee@Sun.COM numattr++; 2239145SHuie-Ying.Lee@Sun.COM 2249145SHuie-Ying.Lee@Sun.COM kmf_set_attr_at_index(attrlist, numattr, 2259145SHuie-Ying.Lee@Sun.COM KMF_KEY_HANDLE_ATTR, &prik, sizeof (KMF_KEY_HANDLE)); 2269145SHuie-Ying.Lee@Sun.COM numattr++; 2279145SHuie-Ying.Lee@Sun.COM 2289145SHuie-Ying.Lee@Sun.COM if (tokencred != NULL && tokencred->cred != NULL) { 2299145SHuie-Ying.Lee@Sun.COM kmf_set_attr_at_index(attrlist, numattr, 2309145SHuie-Ying.Lee@Sun.COM KMF_CREDENTIAL_ATTR, tokencred, 2319145SHuie-Ying.Lee@Sun.COM sizeof (KMF_CREDENTIAL)); 2329145SHuie-Ying.Lee@Sun.COM numattr++; 2339145SHuie-Ying.Lee@Sun.COM } 2349145SHuie-Ying.Lee@Sun.COM 2359145SHuie-Ying.Lee@Sun.COM (void) kmf_delete_key_from_keystore(kmfhandle, numattr, 2369145SHuie-Ying.Lee@Sun.COM attrlist); 2379145SHuie-Ying.Lee@Sun.COM } 2389145SHuie-Ying.Lee@Sun.COM 2393089Swyllys return (kmfrv); 2403089Swyllys } 2413089Swyllys 2423089Swyllys static int 2433089Swyllys gencert_file(KMF_HANDLE_T kmfhandle, 2443089Swyllys KMF_KEY_ALG keyAlg, KMF_ALGORITHM_INDEX sigAlg, 2453089Swyllys int keylen, KMF_ENCODE_FORMAT fmt, 2463089Swyllys uint32_t ltime, char *subject, char *altname, 2473089Swyllys KMF_GENERALNAMECHOICES alttype, int altcrit, 2483089Swyllys KMF_BIGINT *serial, uint16_t kubits, int kucrit, 2496669Swyllys char *outcert, char *outkey, 2506051Swyllys EKU_LIST *ekulist) 2513089Swyllys { 2523089Swyllys KMF_RETURN kmfrv; 2533089Swyllys KMF_KEY_HANDLE pubk, prik; 2543089Swyllys KMF_X509_CERTIFICATE signedCert; 2553089Swyllys KMF_X509_NAME certSubject; 2563089Swyllys KMF_X509_NAME certIssuer; 2573089Swyllys KMF_DATA x509DER; 2583089Swyllys char *fullcertpath = NULL; 2593089Swyllys char *fullkeypath = NULL; 2605051Swyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 2615051Swyllys KMF_ATTRIBUTE attrlist[10]; 2625051Swyllys int numattr = 0; 2633089Swyllys 2643089Swyllys (void) memset(&signedCert, 0, sizeof (signedCert)); 2653089Swyllys (void) memset(&certSubject, 0, sizeof (certSubject)); 2663089Swyllys (void) memset(&certIssuer, 0, sizeof (certIssuer)); 2673089Swyllys (void) memset(&x509DER, 0, sizeof (x509DER)); 2683089Swyllys 2693089Swyllys if (EMPTYSTRING(outcert) || EMPTYSTRING(outkey)) { 2703089Swyllys cryptoerror(LOG_STDERR, 2715051Swyllys gettext("No output file was specified for " 2725051Swyllys "the cert or key\n")); 2733089Swyllys return (PK_ERR_USAGE); 2743089Swyllys } 2756669Swyllys fullcertpath = strdup(outcert); 2763089Swyllys if (verify_file(fullcertpath)) { 2773089Swyllys cryptoerror(LOG_STDERR, 2785051Swyllys gettext("Cannot write the indicated output " 2795051Swyllys "certificate file (%s).\n"), fullcertpath); 2803089Swyllys free(fullcertpath); 2813089Swyllys return (PK_ERR_USAGE); 2823089Swyllys } 2836669Swyllys 2843089Swyllys /* If the subject name cannot be parsed, flag it now and exit */ 2855051Swyllys if (kmf_dn_parser(subject, &certSubject) != KMF_OK) { 2863089Swyllys cryptoerror(LOG_STDERR, 2875051Swyllys gettext("Subject name cannot be parsed (%s)\n"), subject); 2883089Swyllys return (PK_ERR_USAGE); 2893089Swyllys } 2903089Swyllys 2913089Swyllys /* For a self-signed cert, the issuser and subject are the same */ 2925051Swyllys if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) { 2933089Swyllys cryptoerror(LOG_STDERR, 2945051Swyllys gettext("Subject name cannot be parsed (%s)\n"), subject); 2955051Swyllys kmf_free_dn(&certSubject); 2963089Swyllys return (PK_ERR_USAGE); 2973089Swyllys } 2983089Swyllys 299*11973Swyllys.ingersoll@sun.com /* 300*11973Swyllys.ingersoll@sun.com * Share the "genkeypair" routine for creating the keypair. 301*11973Swyllys.ingersoll@sun.com */ 302*11973Swyllys.ingersoll@sun.com kmfrv = genkeypair_file(kmfhandle, keyAlg, keylen, 303*11973Swyllys.ingersoll@sun.com fmt, outkey, &prik, &pubk); 304*11973Swyllys.ingersoll@sun.com if (kmfrv != KMF_OK) 305*11973Swyllys.ingersoll@sun.com return (kmfrv); 3065051Swyllys 3075051Swyllys SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert), 3085051Swyllys "keypair"); 3093089Swyllys 3105051Swyllys SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number"); 3113089Swyllys 3125051Swyllys SET_VALUE(kmf_set_cert_serial(&signedCert, serial), 3135051Swyllys "serial number"); 3143089Swyllys 3155051Swyllys SET_VALUE(kmf_set_cert_validity(&signedCert, NULL, ltime), 3165051Swyllys "validity time"); 3173089Swyllys 3185051Swyllys SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg), 3195051Swyllys "signature algorithm"); 3203089Swyllys 3215051Swyllys SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject), 3225051Swyllys "subject name"); 3233089Swyllys 3245051Swyllys SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer), 3255051Swyllys "issuer name"); 3263089Swyllys 3273089Swyllys if (altname != NULL) 3285051Swyllys SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit, 3295051Swyllys alttype, altname), "subjectAltName"); 3303089Swyllys 3313089Swyllys if (kubits != 0) 3325051Swyllys SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits), 3335051Swyllys "KeyUsage"); 3346051Swyllys 3356051Swyllys if (ekulist != NULL) { 3366051Swyllys int i; 3376051Swyllys for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) { 3386051Swyllys SET_VALUE(kmf_add_cert_eku(&signedCert, 3396051Swyllys &ekulist->ekulist[i], 3406051Swyllys ekulist->critlist[i]), "Extended Key Usage"); 3416051Swyllys } 3426051Swyllys } 3435051Swyllys /* 3445051Swyllys * Construct attributes for the kmf_sign_cert operation. 3455051Swyllys */ 3465051Swyllys numattr = 0; 3475051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 3485051Swyllys &kstype, sizeof (kstype)); 3495051Swyllys numattr++; 3503089Swyllys 3515051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 3525051Swyllys &prik, sizeof (KMF_KEY_HANDLE_ATTR)); 3535051Swyllys numattr++; 3545051Swyllys 3555051Swyllys /* cert data that is to be signed */ 3565051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR, 3575051Swyllys &signedCert, sizeof (KMF_X509_CERTIFICATE)); 3585051Swyllys numattr++; 3595051Swyllys 3605051Swyllys /* output buffer for the signed cert */ 3615051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 3625051Swyllys &x509DER, sizeof (KMF_DATA)); 3635051Swyllys numattr++; 3645051Swyllys 3655051Swyllys if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) != 3665051Swyllys KMF_OK) { 3673089Swyllys goto cleanup; 3683089Swyllys } 3693089Swyllys 3703089Swyllys /* 3713089Swyllys * Store the cert in the DB. 3723089Swyllys */ 3735051Swyllys numattr = 0; 3745051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 3755051Swyllys &kstype, sizeof (kstype)); 3765051Swyllys numattr++; 3775051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 3785051Swyllys &x509DER, sizeof (KMF_DATA)); 3795051Swyllys numattr++; 3805051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_FILENAME_ATTR, 3815051Swyllys fullcertpath, strlen(fullcertpath)); 3825051Swyllys numattr++; 3835051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, 3845051Swyllys &fmt, sizeof (fmt)); 3855051Swyllys numattr++; 3865051Swyllys 3875051Swyllys kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist); 3883089Swyllys 3893089Swyllys cleanup: 3903089Swyllys if (fullkeypath != NULL) 3913089Swyllys free(fullkeypath); 3923089Swyllys if (fullcertpath != NULL) 3933089Swyllys free(fullcertpath); 3943089Swyllys 3955051Swyllys kmf_free_data(&x509DER); 3965051Swyllys kmf_free_dn(&certSubject); 3975051Swyllys kmf_free_dn(&certIssuer); 3983089Swyllys return (kmfrv); 3993089Swyllys } 4003089Swyllys 4013089Swyllys static KMF_RETURN 4023089Swyllys gencert_nss(KMF_HANDLE_T kmfhandle, 4033089Swyllys char *token, char *subject, char *altname, 4043089Swyllys KMF_GENERALNAMECHOICES alttype, int altcrit, 4053089Swyllys char *nickname, char *dir, char *prefix, 4063089Swyllys KMF_KEY_ALG keyAlg, 4073089Swyllys KMF_ALGORITHM_INDEX sigAlg, 4083089Swyllys int keylen, char *trust, 4093089Swyllys uint32_t ltime, KMF_BIGINT *serial, uint16_t kubits, 4106051Swyllys int kucrit, KMF_CREDENTIAL *tokencred, 411*11973Swyllys.ingersoll@sun.com EKU_LIST *ekulist, KMF_OID *curveoid) 4123089Swyllys { 4133089Swyllys KMF_RETURN kmfrv; 4143089Swyllys KMF_KEY_HANDLE pubk, prik; 4153089Swyllys KMF_X509_CERTIFICATE signedCert; 4163089Swyllys KMF_X509_NAME certSubject; 4173089Swyllys KMF_X509_NAME certIssuer; 4183089Swyllys KMF_DATA x509DER; 4195051Swyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; 4205051Swyllys KMF_ATTRIBUTE attrlist[16]; 4215051Swyllys int numattr = 0; 4223089Swyllys 4233089Swyllys if (token == NULL) 4243089Swyllys token = DEFAULT_NSS_TOKEN; 4253089Swyllys 4263089Swyllys kmfrv = configure_nss(kmfhandle, dir, prefix); 4273089Swyllys if (kmfrv != KMF_OK) 4283089Swyllys return (kmfrv); 4293089Swyllys 4303089Swyllys (void) memset(&signedCert, 0, sizeof (signedCert)); 4313089Swyllys (void) memset(&certSubject, 0, sizeof (certSubject)); 4323089Swyllys (void) memset(&certIssuer, 0, sizeof (certIssuer)); 4333089Swyllys (void) memset(&x509DER, 0, sizeof (x509DER)); 4343089Swyllys 4353089Swyllys /* If the subject name cannot be parsed, flag it now and exit */ 4365051Swyllys if (kmf_dn_parser(subject, &certSubject) != KMF_OK) { 4373089Swyllys cryptoerror(LOG_STDERR, 4385051Swyllys gettext("Subject name cannot be parsed.\n")); 4393089Swyllys return (PK_ERR_USAGE); 4403089Swyllys } 4413089Swyllys 4423089Swyllys /* For a self-signed cert, the issuser and subject are the same */ 4435051Swyllys if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) { 4443089Swyllys cryptoerror(LOG_STDERR, 4455051Swyllys gettext("Subject name cannot be parsed.\n")); 4463089Swyllys return (PK_ERR_USAGE); 4473089Swyllys } 4483089Swyllys 449*11973Swyllys.ingersoll@sun.com kmfrv = genkeypair_nss(kmfhandle, token, nickname, dir, 450*11973Swyllys.ingersoll@sun.com prefix, keyAlg, keylen, tokencred, curveoid, 451*11973Swyllys.ingersoll@sun.com &prik, &pubk); 452*11973Swyllys.ingersoll@sun.com if (kmfrv != KMF_OK) 4533089Swyllys return (kmfrv); 4543089Swyllys 4555051Swyllys SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert), 4565051Swyllys "keypair"); 4573089Swyllys 4585051Swyllys SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number"); 4593089Swyllys 4605051Swyllys SET_VALUE(kmf_set_cert_serial(&signedCert, serial), 4615051Swyllys "serial number"); 4623089Swyllys 4635051Swyllys SET_VALUE(kmf_set_cert_validity(&signedCert, NULL, ltime), 4645051Swyllys "validity time"); 4653089Swyllys 4665051Swyllys SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg), 4675051Swyllys "signature algorithm"); 4683089Swyllys 4695051Swyllys SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject), 4705051Swyllys "subject name"); 4713089Swyllys 4725051Swyllys SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer), 4735051Swyllys "issuer name"); 4743089Swyllys 4753089Swyllys if (altname != NULL) 4765051Swyllys SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit, 4775051Swyllys alttype, altname), "subjectAltName"); 4783089Swyllys 4793089Swyllys if (kubits) 4805051Swyllys SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits), 4815051Swyllys "subjectAltName"); 4825051Swyllys 4836051Swyllys if (ekulist != NULL) { 4846051Swyllys int i; 4856051Swyllys for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) { 4866051Swyllys SET_VALUE(kmf_add_cert_eku(&signedCert, 4876051Swyllys &ekulist->ekulist[i], 4886051Swyllys ekulist->critlist[i]), "Extended Key Usage"); 4896051Swyllys } 4906051Swyllys } 4915051Swyllys /* 4925051Swyllys * Construct attributes for the kmf_sign_cert operation. 4935051Swyllys */ 4945051Swyllys numattr = 0; 4955051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 4965051Swyllys &kstype, sizeof (kstype)); 4975051Swyllys numattr++; 4983089Swyllys 4995051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 5005051Swyllys &prik, sizeof (KMF_KEY_HANDLE_ATTR)); 5015051Swyllys numattr++; 5025051Swyllys 5035051Swyllys /* cert data that is to be signed */ 5045051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR, 5055051Swyllys &signedCert, sizeof (KMF_X509_CERTIFICATE)); 5065051Swyllys numattr++; 5075051Swyllys 5085051Swyllys /* output buffer for the signed cert */ 5095051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 5105051Swyllys &x509DER, sizeof (KMF_DATA)); 5115051Swyllys numattr++; 5125051Swyllys 5135051Swyllys if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) != 5145051Swyllys KMF_OK) { 5153089Swyllys goto cleanup; 5163089Swyllys } 5173089Swyllys 5183089Swyllys /* 5193089Swyllys * Store the cert in the DB. 5203089Swyllys */ 5215051Swyllys numattr = 0; 5225051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 5235051Swyllys &kstype, sizeof (kstype)); 5245051Swyllys numattr++; 5255051Swyllys 5265051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 5275051Swyllys &x509DER, sizeof (KMF_DATA)); 5285051Swyllys numattr++; 5295051Swyllys 5305051Swyllys if (nickname != NULL) { 5315051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR, 5325051Swyllys nickname, strlen(nickname)); 5335051Swyllys numattr++; 5345051Swyllys } 5355051Swyllys 5365051Swyllys if (trust != NULL) { 5375051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_TRUSTFLAG_ATTR, 5385051Swyllys trust, strlen(trust)); 5395051Swyllys numattr++; 5405051Swyllys } 5415051Swyllys 5425051Swyllys if (token != NULL) { 5435051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, 5445051Swyllys token, strlen(token)); 5455051Swyllys numattr++; 5465051Swyllys } 5475051Swyllys 5485051Swyllys kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist); 5493089Swyllys 5503089Swyllys cleanup: 5515051Swyllys kmf_free_data(&x509DER); 5525051Swyllys kmf_free_dn(&certSubject); 5535051Swyllys kmf_free_dn(&certIssuer); 5543089Swyllys return (kmfrv); 5553089Swyllys } 5563089Swyllys 5573089Swyllys int 5583089Swyllys pk_gencert(int argc, char *argv[]) 5593089Swyllys { 5603089Swyllys int rv; 5613089Swyllys int opt; 5623089Swyllys extern int optind_av; 5633089Swyllys extern char *optarg_av; 5643089Swyllys KMF_KEYSTORE_TYPE kstype = 0; 5653089Swyllys char *subject = NULL; 5663089Swyllys char *tokenname = NULL; 5673089Swyllys char *dir = NULL; 5683089Swyllys char *prefix = NULL; 5693089Swyllys char *keytype = PK_DEFAULT_KEYTYPE; 5703089Swyllys int keylen = PK_DEFAULT_KEYLENGTH; 5713089Swyllys char *trust = NULL; 5723089Swyllys char *lifetime = NULL; 5733089Swyllys char *certlabel = NULL; 5743089Swyllys char *outcert = NULL; 5753089Swyllys char *outkey = NULL; 5763089Swyllys char *format = NULL; 5773089Swyllys char *serstr = NULL; 5783089Swyllys char *altname = NULL; 5793089Swyllys char *keyusagestr = NULL; 5806051Swyllys char *ekustr = NULL; 581*11973Swyllys.ingersoll@sun.com char *hashname = NULL; 5823089Swyllys KMF_GENERALNAMECHOICES alttype = 0; 5833089Swyllys KMF_BIGINT serial = { NULL, 0 }; 5843089Swyllys uint32_t ltime; 5853089Swyllys KMF_HANDLE_T kmfhandle = NULL; 5863089Swyllys KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1; 5873089Swyllys KMF_KEY_ALG keyAlg = KMF_RSA; 58810744Swyllys.ingersoll@sun.com KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_SHA1WithRSA; 5893089Swyllys boolean_t interactive = B_FALSE; 5903089Swyllys char *subname = NULL; 5913089Swyllys KMF_CREDENTIAL tokencred = {NULL, 0}; 5923089Swyllys uint16_t kubits = 0; 5933089Swyllys int altcrit = 0, kucrit = 0; 5946051Swyllys EKU_LIST *ekulist = NULL; 595*11973Swyllys.ingersoll@sun.com KMF_OID *curveoid = NULL; /* ECC */ 596*11973Swyllys.ingersoll@sun.com KMF_OID *hashoid = NULL; 597*11973Swyllys.ingersoll@sun.com int y_flag = 0; 5983089Swyllys 5993089Swyllys while ((opt = getopt_av(argc, argv, 6005051Swyllys "ik:(keystore)s:(subject)n:(nickname)A:(altname)" 6015051Swyllys "T:(token)d:(dir)p:(prefix)t:(keytype)y:(keylen)" 6026051Swyllys "r:(trust)L:(lifetime)l:(label)c:(outcert)e:(eku)" 603*11973Swyllys.ingersoll@sun.com "K:(outkey)S:(serial)F:(format)u:(keyusage)C:(curve)" 604*11973Swyllys.ingersoll@sun.com "E(listcurves)h:(hash)")) != EOF) { 6053089Swyllys 606*11973Swyllys.ingersoll@sun.com if (opt != 'i' && opt != 'E' && EMPTYSTRING(optarg_av)) 6073089Swyllys return (PK_ERR_USAGE); 6083089Swyllys 6093089Swyllys switch (opt) { 6103089Swyllys case 'A': 6113089Swyllys altname = optarg_av; 6123089Swyllys break; 6133089Swyllys case 'i': 6143089Swyllys if (interactive || subject) 6153089Swyllys return (PK_ERR_USAGE); 6163089Swyllys else 6173089Swyllys interactive = B_TRUE; 6183089Swyllys break; 6193089Swyllys case 'k': 6203089Swyllys kstype = KS2Int(optarg_av); 6213089Swyllys if (kstype == 0) 6223089Swyllys return (PK_ERR_USAGE); 6233089Swyllys break; 6243089Swyllys case 's': 6253089Swyllys if (interactive || subject) 6263089Swyllys return (PK_ERR_USAGE); 6273089Swyllys else 6283089Swyllys subject = optarg_av; 6293089Swyllys break; 6303089Swyllys case 'l': 6313089Swyllys case 'n': 6323089Swyllys if (certlabel) 6333089Swyllys return (PK_ERR_USAGE); 6343089Swyllys certlabel = optarg_av; 6353089Swyllys break; 6363089Swyllys case 'T': 6373089Swyllys if (tokenname) 6383089Swyllys return (PK_ERR_USAGE); 6393089Swyllys tokenname = optarg_av; 6403089Swyllys break; 6413089Swyllys case 'd': 6423089Swyllys if (dir) 6433089Swyllys return (PK_ERR_USAGE); 6443089Swyllys dir = optarg_av; 6453089Swyllys break; 6463089Swyllys case 'p': 6473089Swyllys if (prefix) 6483089Swyllys return (PK_ERR_USAGE); 6493089Swyllys prefix = optarg_av; 6503089Swyllys break; 6513089Swyllys case 't': 6523089Swyllys keytype = optarg_av; 6533089Swyllys break; 6543089Swyllys case 'u': 6553089Swyllys keyusagestr = optarg_av; 6563089Swyllys break; 6573089Swyllys case 'y': 6583089Swyllys if (sscanf(optarg_av, "%d", 6595051Swyllys &keylen) != 1) { 6603089Swyllys cryptoerror(LOG_STDERR, 6615051Swyllys gettext("key length must be" 6625051Swyllys "a numeric value (%s)\n"), 6635051Swyllys optarg_av); 6643089Swyllys return (PK_ERR_USAGE); 6653089Swyllys } 666*11973Swyllys.ingersoll@sun.com y_flag++; 6673089Swyllys break; 6683089Swyllys case 'r': 6693089Swyllys if (trust) 6703089Swyllys return (PK_ERR_USAGE); 6713089Swyllys trust = optarg_av; 6723089Swyllys break; 6733089Swyllys case 'L': 6743089Swyllys if (lifetime) 6753089Swyllys return (PK_ERR_USAGE); 6763089Swyllys lifetime = optarg_av; 6773089Swyllys break; 6783089Swyllys case 'c': 6793089Swyllys if (outcert) 6803089Swyllys return (PK_ERR_USAGE); 6813089Swyllys outcert = optarg_av; 6823089Swyllys break; 6833089Swyllys case 'K': 6843089Swyllys if (outkey) 6853089Swyllys return (PK_ERR_USAGE); 6863089Swyllys outkey = optarg_av; 6873089Swyllys break; 6883089Swyllys case 'S': 6893089Swyllys serstr = optarg_av; 6903089Swyllys break; 6913089Swyllys case 'F': 6923089Swyllys if (format) 6933089Swyllys return (PK_ERR_USAGE); 6943089Swyllys format = optarg_av; 6953089Swyllys break; 6966051Swyllys case 'e': 6976051Swyllys ekustr = optarg_av; 6986051Swyllys break; 699*11973Swyllys.ingersoll@sun.com case 'C': 700*11973Swyllys.ingersoll@sun.com curveoid = ecc_name_to_oid(optarg_av); 701*11973Swyllys.ingersoll@sun.com if (curveoid == NULL) { 702*11973Swyllys.ingersoll@sun.com cryptoerror(LOG_STDERR, 703*11973Swyllys.ingersoll@sun.com gettext("Unrecognized ECC " 704*11973Swyllys.ingersoll@sun.com "curve.\n")); 705*11973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE); 706*11973Swyllys.ingersoll@sun.com } 707*11973Swyllys.ingersoll@sun.com break; 708*11973Swyllys.ingersoll@sun.com case 'E': 709*11973Swyllys.ingersoll@sun.com /* 710*11973Swyllys.ingersoll@sun.com * This argument is only to be used 711*11973Swyllys.ingersoll@sun.com * by itself, no other options should 712*11973Swyllys.ingersoll@sun.com * be present. 713*11973Swyllys.ingersoll@sun.com */ 714*11973Swyllys.ingersoll@sun.com if (argc != 2) { 715*11973Swyllys.ingersoll@sun.com cryptoerror(LOG_STDERR, 716*11973Swyllys.ingersoll@sun.com gettext("listcurves has no other " 717*11973Swyllys.ingersoll@sun.com "options.\n")); 718*11973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE); 719*11973Swyllys.ingersoll@sun.com } 720*11973Swyllys.ingersoll@sun.com show_ecc_curves(); 721*11973Swyllys.ingersoll@sun.com return (0); 722*11973Swyllys.ingersoll@sun.com case 'h': 723*11973Swyllys.ingersoll@sun.com hashname = optarg_av; 724*11973Swyllys.ingersoll@sun.com hashoid = ecc_name_to_oid(optarg_av); 725*11973Swyllys.ingersoll@sun.com if (hashoid == NULL) { 726*11973Swyllys.ingersoll@sun.com cryptoerror(LOG_STDERR, 727*11973Swyllys.ingersoll@sun.com gettext("Unrecognized hash.\n")); 728*11973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE); 729*11973Swyllys.ingersoll@sun.com } 730*11973Swyllys.ingersoll@sun.com break; 7313089Swyllys default: 7323089Swyllys return (PK_ERR_USAGE); 7333089Swyllys } 7343089Swyllys } 7353089Swyllys 7363089Swyllys /* No additional args allowed. */ 7373089Swyllys argc -= optind_av; 7383089Swyllys argv += optind_av; 7393089Swyllys if (argc) { 7403089Swyllys return (PK_ERR_USAGE); 7413089Swyllys } 7423089Swyllys 7435051Swyllys if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 7443089Swyllys cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n")); 7453089Swyllys return (PK_ERR_USAGE); 7463089Swyllys } 7473089Swyllys 7483089Swyllys /* Assume keystore = PKCS#11 if not specified. */ 7493089Swyllys if (kstype == 0) 7503089Swyllys kstype = KMF_KEYSTORE_PK11TOKEN; 7513089Swyllys 7525221Swyllys if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN)) { 7535221Swyllys if (interactive && EMPTYSTRING(certlabel)) { 7545221Swyllys (void) get_certlabel(&certlabel); 7555221Swyllys } 7565221Swyllys /* It better not be empty now */ 7575221Swyllys if (EMPTYSTRING(certlabel)) { 7585221Swyllys cryptoerror(LOG_STDERR, gettext("A label must be " 7595221Swyllys "specified to create a self-signed certificate." 7605221Swyllys "\n")); 7615221Swyllys return (PK_ERR_USAGE); 7625221Swyllys } 7633089Swyllys } else if (kstype == KMF_KEYSTORE_OPENSSL && EMPTYSTRING(outcert)) { 7643089Swyllys cryptoerror(LOG_STDERR, gettext("A certificate filename must " 7653089Swyllys "be specified to create a self-signed certificate.\n")); 7663089Swyllys return (PK_ERR_USAGE); 7673089Swyllys } 7683089Swyllys 7696884Swyllys DIR_OPTION_CHECK(kstype, dir); 7706884Swyllys 7713089Swyllys if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) { 7723089Swyllys cryptoerror(LOG_STDERR, 7733089Swyllys gettext("Error parsing format string (%s).\n"), 7743089Swyllys format); 7753089Swyllys return (PK_ERR_USAGE); 7763089Swyllys } 7773089Swyllys 7783089Swyllys if (Str2Lifetime(lifetime, <ime) != 0) { 7793089Swyllys cryptoerror(LOG_STDERR, 7805051Swyllys gettext("Error parsing lifetime string\n")); 7813089Swyllys return (PK_ERR_USAGE); 7823089Swyllys } 7833089Swyllys 784*11973Swyllys.ingersoll@sun.com if (Str2KeyType(keytype, hashoid, &keyAlg, &sigAlg) != 0) { 785*11973Swyllys.ingersoll@sun.com cryptoerror(LOG_STDERR, 786*11973Swyllys.ingersoll@sun.com gettext("Unsupported key/hash combination (%s/%s).\n"), 787*11973Swyllys.ingersoll@sun.com keytype, (hashname ? hashname : "none")); 7883089Swyllys return (PK_ERR_USAGE); 7893089Swyllys } 790*11973Swyllys.ingersoll@sun.com if (curveoid != NULL && keyAlg != KMF_ECDSA) { 791*11973Swyllys.ingersoll@sun.com cryptoerror(LOG_STDERR, gettext("EC curves are only " 792*11973Swyllys.ingersoll@sun.com "valid for EC keytypes.\n")); 793*11973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE); 794*11973Swyllys.ingersoll@sun.com } 795*11973Swyllys.ingersoll@sun.com if (keyAlg == KMF_ECDSA && curveoid == NULL) { 796*11973Swyllys.ingersoll@sun.com cryptoerror(LOG_STDERR, gettext("A curve must be " 797*11973Swyllys.ingersoll@sun.com "specifed when using EC keys.\n")); 798*11973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE); 799*11973Swyllys.ingersoll@sun.com } 800*11973Swyllys.ingersoll@sun.com /* Adjust default keylength for NSS and DSA */ 801*11973Swyllys.ingersoll@sun.com if (keyAlg == KMF_DSA && !y_flag && kstype == KMF_KEYSTORE_NSS) 802*11973Swyllys.ingersoll@sun.com keylen = 1024; 8033089Swyllys 8043089Swyllys /* 8053089Swyllys * Check the subject name. 8063089Swyllys * If interactive is true, get it now interactively. 8073089Swyllys */ 8083089Swyllys if (interactive) { 8095221Swyllys subname = NULL; 8105221Swyllys if (get_subname(&subname) != KMF_OK || subname == NULL) { 8113089Swyllys cryptoerror(LOG_STDERR, gettext("Failed to get the " 8123089Swyllys "subject name interactively.\n")); 8133089Swyllys return (PK_ERR_USAGE); 8143089Swyllys } 8155221Swyllys if (serstr == NULL) { 8165221Swyllys (void) get_serial(&serstr); 8175221Swyllys } 8183089Swyllys } else { 8193089Swyllys if (EMPTYSTRING(subject)) { 8203089Swyllys cryptoerror(LOG_STDERR, gettext("A subject name or " 8213089Swyllys "-i must be specified to create a self-signed " 8223089Swyllys "certificate.\n")); 8233089Swyllys return (PK_ERR_USAGE); 8243089Swyllys } else { 8253089Swyllys subname = strdup(subject); 8263089Swyllys if (subname == NULL) { 8273089Swyllys cryptoerror(LOG_STDERR, 8283089Swyllys gettext("Out of memory.\n")); 8293089Swyllys return (PK_ERR_SYSTEM); 8303089Swyllys } 8313089Swyllys } 8323089Swyllys } 8333089Swyllys 8343089Swyllys if (serstr == NULL) { 8353089Swyllys (void) fprintf(stderr, gettext("A serial number " 8365051Swyllys "must be specified as a hex number when creating" 8375051Swyllys " a self-signed certificate " 8385051Swyllys "(ex: serial=0x0102030405feedface)\n")); 8393089Swyllys rv = PK_ERR_USAGE; 8403089Swyllys goto end; 8413089Swyllys } else { 8423089Swyllys uchar_t *bytes = NULL; 8433089Swyllys size_t bytelen; 8443089Swyllys 8455051Swyllys rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen); 8463089Swyllys if (rv != KMF_OK || bytes == NULL) { 8473089Swyllys (void) fprintf(stderr, gettext("serial number " 8485051Swyllys "must be specified as a hex number " 8495051Swyllys "(ex: 0x0102030405ffeeddee)\n")); 8503089Swyllys rv = PK_ERR_USAGE; 8513089Swyllys goto end; 8523089Swyllys } 8533089Swyllys serial.val = bytes; 8543089Swyllys serial.len = bytelen; 8553089Swyllys } 8563089Swyllys 8573089Swyllys if (altname != NULL) { 8583089Swyllys rv = verify_altname(altname, &alttype, &altcrit); 8593089Swyllys if (rv != KMF_OK) { 8603089Swyllys (void) fprintf(stderr, gettext("Subject AltName " 8615051Swyllys "must be specified as a name=value pair. " 8625051Swyllys "See the man page for details.\n")); 8633089Swyllys rv = PK_ERR_USAGE; 8643089Swyllys goto end; 8653089Swyllys } else { 8663089Swyllys /* advance the altname past the '=' sign */ 8673089Swyllys char *p = strchr(altname, '='); 8683089Swyllys if (p != NULL) 8693089Swyllys altname = p + 1; 8703089Swyllys } 8713089Swyllys } 8723089Swyllys 8733089Swyllys if (keyusagestr != NULL) { 8743089Swyllys rv = verify_keyusage(keyusagestr, &kubits, &kucrit); 8753089Swyllys if (rv != KMF_OK) { 8763089Swyllys (void) fprintf(stderr, gettext("KeyUsage " 8775051Swyllys "must be specified as a comma-separated list. " 8785051Swyllys "See the man page for details.\n")); 8793089Swyllys rv = PK_ERR_USAGE; 8803089Swyllys goto end; 8813089Swyllys } 8823089Swyllys } 8836051Swyllys if (ekustr != NULL) { 8846051Swyllys rv = verify_ekunames(ekustr, &ekulist); 8856051Swyllys if (rv != KMF_OK) { 8866051Swyllys (void) fprintf(stderr, gettext("EKUs must " 8876051Swyllys "be specified as a comma-separated list. " 8886051Swyllys "See the man page for details.\n")); 8896051Swyllys rv = PK_ERR_USAGE; 8906051Swyllys goto end; 8916051Swyllys } 8926051Swyllys } 893*11973Swyllys.ingersoll@sun.com if (keyAlg == KMF_ECDSA && kstype == KMF_KEYSTORE_OPENSSL) { 894*11973Swyllys.ingersoll@sun.com (void) fprintf(stderr, gettext("ECC certificates are" 895*11973Swyllys.ingersoll@sun.com "only supported with the pkcs11 and nss keystores\n")); 896*11973Swyllys.ingersoll@sun.com rv = PK_ERR_USAGE; 897*11973Swyllys.ingersoll@sun.com goto end; 898*11973Swyllys.ingersoll@sun.com } 8993089Swyllys 9003089Swyllys if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) { 9013089Swyllys if (tokenname == NULL || !strlen(tokenname)) { 9023089Swyllys if (kstype == KMF_KEYSTORE_NSS) { 9033089Swyllys tokenname = "internal"; 9043089Swyllys } else { 9053089Swyllys tokenname = PK_DEFAULT_PK11TOKEN; 9063089Swyllys } 9073089Swyllys } 9083089Swyllys 9093089Swyllys (void) get_token_password(kstype, tokenname, &tokencred); 9103089Swyllys } 9113089Swyllys 9123089Swyllys if (kstype == KMF_KEYSTORE_NSS) { 9133089Swyllys if (dir == NULL) 9143089Swyllys dir = PK_DEFAULT_DIRECTORY; 9153089Swyllys 9163089Swyllys rv = gencert_nss(kmfhandle, 9175051Swyllys tokenname, subname, altname, alttype, altcrit, 9185051Swyllys certlabel, dir, prefix, keyAlg, sigAlg, keylen, 9196051Swyllys trust, ltime, &serial, kubits, kucrit, &tokencred, 920*11973Swyllys.ingersoll@sun.com ekulist, curveoid); 9213089Swyllys 9223089Swyllys } else if (kstype == KMF_KEYSTORE_PK11TOKEN) { 9233089Swyllys rv = gencert_pkcs11(kmfhandle, 9245051Swyllys tokenname, subname, altname, alttype, altcrit, 9255051Swyllys certlabel, keyAlg, sigAlg, keylen, ltime, 926*11973Swyllys.ingersoll@sun.com &serial, kubits, kucrit, &tokencred, ekulist, 927*11973Swyllys.ingersoll@sun.com curveoid); 9283089Swyllys 9293089Swyllys } else if (kstype == KMF_KEYSTORE_OPENSSL) { 9303089Swyllys rv = gencert_file(kmfhandle, 9315051Swyllys keyAlg, sigAlg, keylen, fmt, 9325051Swyllys ltime, subname, altname, alttype, altcrit, 9336669Swyllys &serial, kubits, kucrit, outcert, outkey, 9346051Swyllys ekulist); 9353089Swyllys } 9363089Swyllys 9373089Swyllys if (rv != KMF_OK) 9383089Swyllys display_error(kmfhandle, rv, 9395051Swyllys gettext("Error creating certificate and keypair")); 9403089Swyllys end: 9416051Swyllys if (ekulist != NULL) 9426051Swyllys free_eku_list(ekulist); 9433089Swyllys if (subname) 9443089Swyllys free(subname); 9453089Swyllys if (tokencred.cred != NULL) 9463089Swyllys free(tokencred.cred); 9473089Swyllys 9483089Swyllys if (serial.val != NULL) 9493089Swyllys free(serial.val); 9503089Swyllys 9515051Swyllys (void) kmf_finalize(kmfhandle); 9523089Swyllys return (rv); 9533089Swyllys } 954