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
20*12234Swyllys.ingersoll@sun.com *
21*12234Swyllys.ingersoll@sun.com * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
223089Swyllys */
233089Swyllys
243089Swyllys #include <stdio.h>
253089Swyllys #include <string.h>
263089Swyllys #include <ctype.h>
273089Swyllys #include <malloc.h>
283089Swyllys #include <libgen.h>
293089Swyllys #include <errno.h>
303089Swyllys #include <cryptoutil.h>
313089Swyllys #include <security/cryptoki.h>
323089Swyllys #include "common.h"
333089Swyllys
343089Swyllys #include <kmfapi.h>
353089Swyllys
363089Swyllys #define SET_VALUE(f, s) \
373089Swyllys kmfrv = f; \
383089Swyllys if (kmfrv != KMF_OK) { \
393089Swyllys cryptoerror(LOG_STDERR, \
403089Swyllys gettext("Failed to set %s: 0x%02x\n"), \
413089Swyllys s, kmfrv); \
423089Swyllys goto cleanup; \
433089Swyllys }
443089Swyllys
453089Swyllys static int
gencert_pkcs11(KMF_HANDLE_T kmfhandle,char * token,char * subject,char * altname,KMF_GENERALNAMECHOICES alttype,int altcrit,char * certlabel,KMF_KEY_ALG keyAlg,KMF_ALGORITHM_INDEX sigAlg,int keylen,uint32_t ltime,KMF_BIGINT * serial,uint16_t kubits,int kucrit,KMF_CREDENTIAL * tokencred,EKU_LIST * ekulist,KMF_OID * curveoid)463089Swyllys gencert_pkcs11(KMF_HANDLE_T kmfhandle,
473089Swyllys char *token, char *subject, char *altname,
483089Swyllys KMF_GENERALNAMECHOICES alttype, int altcrit,
493089Swyllys char *certlabel, KMF_KEY_ALG keyAlg,
503089Swyllys KMF_ALGORITHM_INDEX sigAlg,
513089Swyllys int keylen, uint32_t ltime, KMF_BIGINT *serial,
526051Swyllys uint16_t kubits, int kucrit, KMF_CREDENTIAL *tokencred,
5311973Swyllys.ingersoll@sun.com EKU_LIST *ekulist, KMF_OID *curveoid)
543089Swyllys {
553089Swyllys KMF_RETURN kmfrv = KMF_OK;
563089Swyllys KMF_KEY_HANDLE pubk, prik;
573089Swyllys KMF_X509_CERTIFICATE signedCert;
583089Swyllys KMF_X509_NAME certSubject;
593089Swyllys KMF_X509_NAME certIssuer;
603089Swyllys KMF_DATA x509DER;
615051Swyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
625051Swyllys KMF_ATTRIBUTE attrlist[16];
635051Swyllys int numattr = 0;
645051Swyllys KMF_KEY_ALG keytype;
655051Swyllys uint32_t keylength;
663089Swyllys
673089Swyllys (void) memset(&signedCert, 0, sizeof (signedCert));
683089Swyllys (void) memset(&certSubject, 0, sizeof (certSubject));
693089Swyllys (void) memset(&certIssuer, 0, sizeof (certIssuer));
703089Swyllys (void) memset(&x509DER, 0, sizeof (x509DER));
713089Swyllys
723089Swyllys /* If the subject name cannot be parsed, flag it now and exit */
735051Swyllys if (kmf_dn_parser(subject, &certSubject) != KMF_OK) {
743089Swyllys cryptoerror(LOG_STDERR,
755051Swyllys gettext("Subject name cannot be parsed.\n"));
763089Swyllys return (PK_ERR_USAGE);
773089Swyllys }
783089Swyllys
793089Swyllys /* For a self-signed cert, the issuser and subject are the same */
805051Swyllys if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) {
813089Swyllys cryptoerror(LOG_STDERR,
825051Swyllys gettext("Subject name cannot be parsed.\n"));
833089Swyllys return (PK_ERR_USAGE);
843089Swyllys }
853089Swyllys
865051Swyllys keylength = keylen; /* bits */
875051Swyllys keytype = keyAlg;
883089Swyllys
893089Swyllys /* Select a PKCS11 token */
903089Swyllys kmfrv = select_token(kmfhandle, token, FALSE);
913089Swyllys if (kmfrv != KMF_OK) {
923089Swyllys return (kmfrv);
933089Swyllys }
943089Swyllys
9511973Swyllys.ingersoll@sun.com /*
9611973Swyllys.ingersoll@sun.com * Share the "genkeypair" routine for creating the keypair.
9711973Swyllys.ingersoll@sun.com */
9811973Swyllys.ingersoll@sun.com kmfrv = genkeypair_pkcs11(kmfhandle, token, certlabel,
9911973Swyllys.ingersoll@sun.com keytype, keylength, tokencred, curveoid, &prik, &pubk);
10011973Swyllys.ingersoll@sun.com if (kmfrv != KMF_OK)
1013089Swyllys return (kmfrv);
1023089Swyllys
1035051Swyllys SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert),
1045051Swyllys "keypair");
1053089Swyllys
1065051Swyllys SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number");
1073089Swyllys
1085051Swyllys SET_VALUE(kmf_set_cert_serial(&signedCert, serial),
1095051Swyllys "serial number");
1103089Swyllys
1115051Swyllys SET_VALUE(kmf_set_cert_validity(&signedCert, NULL, ltime),
1125051Swyllys "validity time");
1133089Swyllys
1145051Swyllys SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg),
1155051Swyllys "signature algorithm");
1163089Swyllys
1175051Swyllys SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject),
1185051Swyllys "subject name");
1193089Swyllys
1205051Swyllys SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer),
1215051Swyllys "issuer name");
1223089Swyllys
1233089Swyllys if (altname != NULL)
1245051Swyllys SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit,
1255051Swyllys alttype, altname), "subjectAltName");
1263089Swyllys
1273089Swyllys if (kubits != 0)
1285051Swyllys SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits),
1295051Swyllys "KeyUsage");
1305051Swyllys
1316051Swyllys if (ekulist != NULL) {
1326051Swyllys int i;
1336051Swyllys for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
1346051Swyllys SET_VALUE(kmf_add_cert_eku(&signedCert,
1356051Swyllys &ekulist->ekulist[i], ekulist->critlist[i]),
1366051Swyllys "Extended Key Usage");
1376051Swyllys }
1386051Swyllys }
1396051Swyllys
1405051Swyllys /*
1415051Swyllys * Construct attributes for the kmf_sign_cert operation.
1425051Swyllys */
1435051Swyllys numattr = 0;
1445051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
1455051Swyllys &kstype, sizeof (kstype));
1465051Swyllys numattr++;
1473089Swyllys
1485051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
1495051Swyllys &prik, sizeof (KMF_KEY_HANDLE_ATTR));
1505051Swyllys numattr++;
1515051Swyllys
1525051Swyllys /* cert data that is to be signed */
1535051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR,
1545051Swyllys &signedCert, sizeof (KMF_X509_CERTIFICATE));
1555051Swyllys numattr++;
1565051Swyllys
1575051Swyllys /* output buffer for the signed cert */
1585051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
1595051Swyllys &x509DER, sizeof (KMF_DATA));
1605051Swyllys numattr++;
1615051Swyllys
162*12234Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr, KMF_ALGORITHM_INDEX_ATTR,
163*12234Swyllys.ingersoll@sun.com &sigAlg, sizeof (sigAlg));
164*12234Swyllys.ingersoll@sun.com numattr++;
165*12234Swyllys.ingersoll@sun.com
1665051Swyllys if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) !=
1675051Swyllys KMF_OK) {
1683089Swyllys goto cleanup;
1693089Swyllys }
1703089Swyllys
1713089Swyllys /*
1723089Swyllys * Store the cert in the DB.
1733089Swyllys */
1745051Swyllys numattr = 0;
1755051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
1765051Swyllys &kstype, sizeof (kstype));
1775051Swyllys numattr++;
1785051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
1795051Swyllys &x509DER, sizeof (KMF_DATA));
1805051Swyllys numattr++;
1815051Swyllys
1825051Swyllys if (certlabel != NULL) {
1835051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR,
1845051Swyllys certlabel, strlen(certlabel));
1855051Swyllys numattr++;
1865051Swyllys }
1875051Swyllys
1885051Swyllys kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist);
1895051Swyllys
1903089Swyllys cleanup:
1915051Swyllys kmf_free_data(&x509DER);
1925051Swyllys kmf_free_dn(&certSubject);
1935051Swyllys kmf_free_dn(&certIssuer);
1949145SHuie-Ying.Lee@Sun.COM
1959145SHuie-Ying.Lee@Sun.COM /*
1969145SHuie-Ying.Lee@Sun.COM * If kmf_sign_cert or kmf_store_cert failed, then we need to clean up
1979145SHuie-Ying.Lee@Sun.COM * the key pair from the token.
1989145SHuie-Ying.Lee@Sun.COM */
1999145SHuie-Ying.Lee@Sun.COM if (kmfrv != KMF_OK) {
2009145SHuie-Ying.Lee@Sun.COM /* delete the public key */
2019145SHuie-Ying.Lee@Sun.COM numattr = 0;
2029145SHuie-Ying.Lee@Sun.COM kmf_set_attr_at_index(attrlist, numattr,
2039145SHuie-Ying.Lee@Sun.COM KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
2049145SHuie-Ying.Lee@Sun.COM numattr++;
2059145SHuie-Ying.Lee@Sun.COM
2069145SHuie-Ying.Lee@Sun.COM kmf_set_attr_at_index(attrlist, numattr,
2079145SHuie-Ying.Lee@Sun.COM KMF_KEY_HANDLE_ATTR, &pubk, sizeof (KMF_KEY_HANDLE));
2089145SHuie-Ying.Lee@Sun.COM numattr++;
2099145SHuie-Ying.Lee@Sun.COM
2109145SHuie-Ying.Lee@Sun.COM if (tokencred != NULL && tokencred->cred != NULL) {
2119145SHuie-Ying.Lee@Sun.COM kmf_set_attr_at_index(attrlist, numattr,
2129145SHuie-Ying.Lee@Sun.COM KMF_CREDENTIAL_ATTR, tokencred,
2139145SHuie-Ying.Lee@Sun.COM sizeof (KMF_CREDENTIAL));
2149145SHuie-Ying.Lee@Sun.COM numattr++;
2159145SHuie-Ying.Lee@Sun.COM }
2169145SHuie-Ying.Lee@Sun.COM
2179145SHuie-Ying.Lee@Sun.COM (void) kmf_delete_key_from_keystore(kmfhandle, numattr,
2189145SHuie-Ying.Lee@Sun.COM attrlist);
2199145SHuie-Ying.Lee@Sun.COM
2209145SHuie-Ying.Lee@Sun.COM /* delete the private key */
2219145SHuie-Ying.Lee@Sun.COM numattr = 0;
2229145SHuie-Ying.Lee@Sun.COM kmf_set_attr_at_index(attrlist, numattr,
2239145SHuie-Ying.Lee@Sun.COM KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
2249145SHuie-Ying.Lee@Sun.COM numattr++;
2259145SHuie-Ying.Lee@Sun.COM
2269145SHuie-Ying.Lee@Sun.COM kmf_set_attr_at_index(attrlist, numattr,
2279145SHuie-Ying.Lee@Sun.COM KMF_KEY_HANDLE_ATTR, &prik, sizeof (KMF_KEY_HANDLE));
2289145SHuie-Ying.Lee@Sun.COM numattr++;
2299145SHuie-Ying.Lee@Sun.COM
2309145SHuie-Ying.Lee@Sun.COM if (tokencred != NULL && tokencred->cred != NULL) {
2319145SHuie-Ying.Lee@Sun.COM kmf_set_attr_at_index(attrlist, numattr,
2329145SHuie-Ying.Lee@Sun.COM KMF_CREDENTIAL_ATTR, tokencred,
2339145SHuie-Ying.Lee@Sun.COM sizeof (KMF_CREDENTIAL));
2349145SHuie-Ying.Lee@Sun.COM numattr++;
2359145SHuie-Ying.Lee@Sun.COM }
2369145SHuie-Ying.Lee@Sun.COM
2379145SHuie-Ying.Lee@Sun.COM (void) kmf_delete_key_from_keystore(kmfhandle, numattr,
2389145SHuie-Ying.Lee@Sun.COM attrlist);
2399145SHuie-Ying.Lee@Sun.COM }
2409145SHuie-Ying.Lee@Sun.COM
2413089Swyllys return (kmfrv);
2423089Swyllys }
2433089Swyllys
2443089Swyllys static int
gencert_file(KMF_HANDLE_T kmfhandle,KMF_KEY_ALG keyAlg,KMF_ALGORITHM_INDEX sigAlg,int keylen,KMF_ENCODE_FORMAT fmt,uint32_t ltime,char * subject,char * altname,KMF_GENERALNAMECHOICES alttype,int altcrit,KMF_BIGINT * serial,uint16_t kubits,int kucrit,char * outcert,char * outkey,EKU_LIST * ekulist)2453089Swyllys gencert_file(KMF_HANDLE_T kmfhandle,
2463089Swyllys KMF_KEY_ALG keyAlg, KMF_ALGORITHM_INDEX sigAlg,
2473089Swyllys int keylen, KMF_ENCODE_FORMAT fmt,
2483089Swyllys uint32_t ltime, char *subject, char *altname,
2493089Swyllys KMF_GENERALNAMECHOICES alttype, int altcrit,
2503089Swyllys KMF_BIGINT *serial, uint16_t kubits, int kucrit,
2516669Swyllys char *outcert, char *outkey,
2526051Swyllys EKU_LIST *ekulist)
2533089Swyllys {
2543089Swyllys KMF_RETURN kmfrv;
2553089Swyllys KMF_KEY_HANDLE pubk, prik;
2563089Swyllys KMF_X509_CERTIFICATE signedCert;
2573089Swyllys KMF_X509_NAME certSubject;
2583089Swyllys KMF_X509_NAME certIssuer;
2593089Swyllys KMF_DATA x509DER;
2603089Swyllys char *fullcertpath = NULL;
2613089Swyllys char *fullkeypath = NULL;
2625051Swyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
2635051Swyllys KMF_ATTRIBUTE attrlist[10];
2645051Swyllys int numattr = 0;
2653089Swyllys
2663089Swyllys (void) memset(&signedCert, 0, sizeof (signedCert));
2673089Swyllys (void) memset(&certSubject, 0, sizeof (certSubject));
2683089Swyllys (void) memset(&certIssuer, 0, sizeof (certIssuer));
2693089Swyllys (void) memset(&x509DER, 0, sizeof (x509DER));
2703089Swyllys
2713089Swyllys if (EMPTYSTRING(outcert) || EMPTYSTRING(outkey)) {
2723089Swyllys cryptoerror(LOG_STDERR,
2735051Swyllys gettext("No output file was specified for "
2745051Swyllys "the cert or key\n"));
2753089Swyllys return (PK_ERR_USAGE);
2763089Swyllys }
2776669Swyllys fullcertpath = strdup(outcert);
2783089Swyllys if (verify_file(fullcertpath)) {
2793089Swyllys cryptoerror(LOG_STDERR,
2805051Swyllys gettext("Cannot write the indicated output "
2815051Swyllys "certificate file (%s).\n"), fullcertpath);
2823089Swyllys free(fullcertpath);
2833089Swyllys return (PK_ERR_USAGE);
2843089Swyllys }
2856669Swyllys
2863089Swyllys /* If the subject name cannot be parsed, flag it now and exit */
2875051Swyllys if (kmf_dn_parser(subject, &certSubject) != KMF_OK) {
2883089Swyllys cryptoerror(LOG_STDERR,
2895051Swyllys gettext("Subject name cannot be parsed (%s)\n"), subject);
2903089Swyllys return (PK_ERR_USAGE);
2913089Swyllys }
2923089Swyllys
2933089Swyllys /* For a self-signed cert, the issuser and subject are the same */
2945051Swyllys if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) {
2953089Swyllys cryptoerror(LOG_STDERR,
2965051Swyllys gettext("Subject name cannot be parsed (%s)\n"), subject);
2975051Swyllys kmf_free_dn(&certSubject);
2983089Swyllys return (PK_ERR_USAGE);
2993089Swyllys }
3003089Swyllys
30111973Swyllys.ingersoll@sun.com /*
30211973Swyllys.ingersoll@sun.com * Share the "genkeypair" routine for creating the keypair.
30311973Swyllys.ingersoll@sun.com */
30411973Swyllys.ingersoll@sun.com kmfrv = genkeypair_file(kmfhandle, keyAlg, keylen,
30511973Swyllys.ingersoll@sun.com fmt, outkey, &prik, &pubk);
30611973Swyllys.ingersoll@sun.com if (kmfrv != KMF_OK)
30711973Swyllys.ingersoll@sun.com return (kmfrv);
3085051Swyllys
3095051Swyllys SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert),
3105051Swyllys "keypair");
3113089Swyllys
3125051Swyllys SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number");
3133089Swyllys
3145051Swyllys SET_VALUE(kmf_set_cert_serial(&signedCert, serial),
3155051Swyllys "serial number");
3163089Swyllys
3175051Swyllys SET_VALUE(kmf_set_cert_validity(&signedCert, NULL, ltime),
3185051Swyllys "validity time");
3193089Swyllys
3205051Swyllys SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg),
3215051Swyllys "signature algorithm");
3223089Swyllys
3235051Swyllys SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject),
3245051Swyllys "subject name");
3253089Swyllys
3265051Swyllys SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer),
3275051Swyllys "issuer name");
3283089Swyllys
3293089Swyllys if (altname != NULL)
3305051Swyllys SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit,
3315051Swyllys alttype, altname), "subjectAltName");
3323089Swyllys
3333089Swyllys if (kubits != 0)
3345051Swyllys SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits),
3355051Swyllys "KeyUsage");
3366051Swyllys
3376051Swyllys if (ekulist != NULL) {
3386051Swyllys int i;
3396051Swyllys for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
3406051Swyllys SET_VALUE(kmf_add_cert_eku(&signedCert,
3416051Swyllys &ekulist->ekulist[i],
3426051Swyllys ekulist->critlist[i]), "Extended Key Usage");
3436051Swyllys }
3446051Swyllys }
3455051Swyllys /*
3465051Swyllys * Construct attributes for the kmf_sign_cert operation.
3475051Swyllys */
3485051Swyllys numattr = 0;
3495051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
3505051Swyllys &kstype, sizeof (kstype));
3515051Swyllys numattr++;
3523089Swyllys
3535051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
3545051Swyllys &prik, sizeof (KMF_KEY_HANDLE_ATTR));
3555051Swyllys numattr++;
3565051Swyllys
3575051Swyllys /* cert data that is to be signed */
3585051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR,
3595051Swyllys &signedCert, sizeof (KMF_X509_CERTIFICATE));
3605051Swyllys numattr++;
3615051Swyllys
3625051Swyllys /* output buffer for the signed cert */
3635051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
3645051Swyllys &x509DER, sizeof (KMF_DATA));
3655051Swyllys numattr++;
3665051Swyllys
367*12234Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr, KMF_ALGORITHM_INDEX_ATTR,
368*12234Swyllys.ingersoll@sun.com &sigAlg, sizeof (sigAlg));
369*12234Swyllys.ingersoll@sun.com numattr++;
370*12234Swyllys.ingersoll@sun.com
3715051Swyllys if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) !=
3725051Swyllys KMF_OK) {
3733089Swyllys goto cleanup;
3743089Swyllys }
3753089Swyllys
3763089Swyllys /*
3773089Swyllys * Store the cert in the DB.
3783089Swyllys */
3795051Swyllys numattr = 0;
3805051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
3815051Swyllys &kstype, sizeof (kstype));
3825051Swyllys numattr++;
3835051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
3845051Swyllys &x509DER, sizeof (KMF_DATA));
3855051Swyllys numattr++;
3865051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_FILENAME_ATTR,
3875051Swyllys fullcertpath, strlen(fullcertpath));
3885051Swyllys numattr++;
3895051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR,
3905051Swyllys &fmt, sizeof (fmt));
3915051Swyllys numattr++;
3925051Swyllys
3935051Swyllys kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist);
3943089Swyllys
3953089Swyllys cleanup:
3963089Swyllys if (fullkeypath != NULL)
3973089Swyllys free(fullkeypath);
3983089Swyllys if (fullcertpath != NULL)
3993089Swyllys free(fullcertpath);
4003089Swyllys
4015051Swyllys kmf_free_data(&x509DER);
4025051Swyllys kmf_free_dn(&certSubject);
4035051Swyllys kmf_free_dn(&certIssuer);
4043089Swyllys return (kmfrv);
4053089Swyllys }
4063089Swyllys
4073089Swyllys static KMF_RETURN
gencert_nss(KMF_HANDLE_T kmfhandle,char * token,char * subject,char * altname,KMF_GENERALNAMECHOICES alttype,int altcrit,char * nickname,char * dir,char * prefix,KMF_KEY_ALG keyAlg,KMF_ALGORITHM_INDEX sigAlg,int keylen,char * trust,uint32_t ltime,KMF_BIGINT * serial,uint16_t kubits,int kucrit,KMF_CREDENTIAL * tokencred,EKU_LIST * ekulist,KMF_OID * curveoid)4083089Swyllys gencert_nss(KMF_HANDLE_T kmfhandle,
4093089Swyllys char *token, char *subject, char *altname,
4103089Swyllys KMF_GENERALNAMECHOICES alttype, int altcrit,
4113089Swyllys char *nickname, char *dir, char *prefix,
4123089Swyllys KMF_KEY_ALG keyAlg,
4133089Swyllys KMF_ALGORITHM_INDEX sigAlg,
4143089Swyllys int keylen, char *trust,
4153089Swyllys uint32_t ltime, KMF_BIGINT *serial, uint16_t kubits,
4166051Swyllys int kucrit, KMF_CREDENTIAL *tokencred,
41711973Swyllys.ingersoll@sun.com EKU_LIST *ekulist, KMF_OID *curveoid)
4183089Swyllys {
4193089Swyllys KMF_RETURN kmfrv;
4203089Swyllys KMF_KEY_HANDLE pubk, prik;
4213089Swyllys KMF_X509_CERTIFICATE signedCert;
4223089Swyllys KMF_X509_NAME certSubject;
4233089Swyllys KMF_X509_NAME certIssuer;
4243089Swyllys KMF_DATA x509DER;
4255051Swyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
4265051Swyllys KMF_ATTRIBUTE attrlist[16];
4275051Swyllys int numattr = 0;
4283089Swyllys
4293089Swyllys if (token == NULL)
4303089Swyllys token = DEFAULT_NSS_TOKEN;
4313089Swyllys
4323089Swyllys kmfrv = configure_nss(kmfhandle, dir, prefix);
4333089Swyllys if (kmfrv != KMF_OK)
4343089Swyllys return (kmfrv);
4353089Swyllys
4363089Swyllys (void) memset(&signedCert, 0, sizeof (signedCert));
4373089Swyllys (void) memset(&certSubject, 0, sizeof (certSubject));
4383089Swyllys (void) memset(&certIssuer, 0, sizeof (certIssuer));
4393089Swyllys (void) memset(&x509DER, 0, sizeof (x509DER));
4403089Swyllys
4413089Swyllys /* If the subject name cannot be parsed, flag it now and exit */
4425051Swyllys if (kmf_dn_parser(subject, &certSubject) != KMF_OK) {
4433089Swyllys cryptoerror(LOG_STDERR,
4445051Swyllys gettext("Subject name cannot be parsed.\n"));
4453089Swyllys return (PK_ERR_USAGE);
4463089Swyllys }
4473089Swyllys
4483089Swyllys /* For a self-signed cert, the issuser and subject are the same */
4495051Swyllys if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) {
4503089Swyllys cryptoerror(LOG_STDERR,
4515051Swyllys gettext("Subject name cannot be parsed.\n"));
4523089Swyllys return (PK_ERR_USAGE);
4533089Swyllys }
4543089Swyllys
45511973Swyllys.ingersoll@sun.com kmfrv = genkeypair_nss(kmfhandle, token, nickname, dir,
45611973Swyllys.ingersoll@sun.com prefix, keyAlg, keylen, tokencred, curveoid,
45711973Swyllys.ingersoll@sun.com &prik, &pubk);
45811973Swyllys.ingersoll@sun.com if (kmfrv != KMF_OK)
4593089Swyllys return (kmfrv);
4603089Swyllys
4615051Swyllys SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert),
4625051Swyllys "keypair");
4633089Swyllys
4645051Swyllys SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number");
4653089Swyllys
4665051Swyllys SET_VALUE(kmf_set_cert_serial(&signedCert, serial),
4675051Swyllys "serial number");
4683089Swyllys
4695051Swyllys SET_VALUE(kmf_set_cert_validity(&signedCert, NULL, ltime),
4705051Swyllys "validity time");
4713089Swyllys
4725051Swyllys SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg),
4735051Swyllys "signature algorithm");
4743089Swyllys
4755051Swyllys SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject),
4765051Swyllys "subject name");
4773089Swyllys
4785051Swyllys SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer),
4795051Swyllys "issuer name");
4803089Swyllys
4813089Swyllys if (altname != NULL)
4825051Swyllys SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit,
4835051Swyllys alttype, altname), "subjectAltName");
4843089Swyllys
4853089Swyllys if (kubits)
4865051Swyllys SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits),
4875051Swyllys "subjectAltName");
4885051Swyllys
4896051Swyllys if (ekulist != NULL) {
4906051Swyllys int i;
4916051Swyllys for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
4926051Swyllys SET_VALUE(kmf_add_cert_eku(&signedCert,
4936051Swyllys &ekulist->ekulist[i],
4946051Swyllys ekulist->critlist[i]), "Extended Key Usage");
4956051Swyllys }
4966051Swyllys }
4975051Swyllys /*
4985051Swyllys * Construct attributes for the kmf_sign_cert operation.
4995051Swyllys */
5005051Swyllys numattr = 0;
5015051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
5025051Swyllys &kstype, sizeof (kstype));
5035051Swyllys numattr++;
5043089Swyllys
5055051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
5065051Swyllys &prik, sizeof (KMF_KEY_HANDLE_ATTR));
5075051Swyllys numattr++;
5085051Swyllys
5095051Swyllys /* cert data that is to be signed */
5105051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR,
5115051Swyllys &signedCert, sizeof (KMF_X509_CERTIFICATE));
5125051Swyllys numattr++;
5135051Swyllys
5145051Swyllys /* output buffer for the signed cert */
5155051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
5165051Swyllys &x509DER, sizeof (KMF_DATA));
5175051Swyllys numattr++;
5185051Swyllys
519*12234Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr, KMF_ALGORITHM_INDEX_ATTR,
520*12234Swyllys.ingersoll@sun.com &sigAlg, sizeof (sigAlg));
521*12234Swyllys.ingersoll@sun.com numattr++;
522*12234Swyllys.ingersoll@sun.com
5235051Swyllys if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) !=
5245051Swyllys KMF_OK) {
5253089Swyllys goto cleanup;
5263089Swyllys }
5273089Swyllys
5283089Swyllys /*
5293089Swyllys * Store the cert in the DB.
5303089Swyllys */
5315051Swyllys numattr = 0;
5325051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
5335051Swyllys &kstype, sizeof (kstype));
5345051Swyllys numattr++;
5355051Swyllys
5365051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
5375051Swyllys &x509DER, sizeof (KMF_DATA));
5385051Swyllys numattr++;
5395051Swyllys
5405051Swyllys if (nickname != NULL) {
5415051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR,
5425051Swyllys nickname, strlen(nickname));
5435051Swyllys numattr++;
5445051Swyllys }
5455051Swyllys
5465051Swyllys if (trust != NULL) {
5475051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_TRUSTFLAG_ATTR,
5485051Swyllys trust, strlen(trust));
5495051Swyllys numattr++;
5505051Swyllys }
5515051Swyllys
5525051Swyllys if (token != NULL) {
5535051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
5545051Swyllys token, strlen(token));
5555051Swyllys numattr++;
5565051Swyllys }
5575051Swyllys
5585051Swyllys kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist);
5593089Swyllys
5603089Swyllys cleanup:
5615051Swyllys kmf_free_data(&x509DER);
5625051Swyllys kmf_free_dn(&certSubject);
5635051Swyllys kmf_free_dn(&certIssuer);
5643089Swyllys return (kmfrv);
5653089Swyllys }
5663089Swyllys
5673089Swyllys int
pk_gencert(int argc,char * argv[])5683089Swyllys pk_gencert(int argc, char *argv[])
5693089Swyllys {
5703089Swyllys int rv;
5713089Swyllys int opt;
5723089Swyllys extern int optind_av;
5733089Swyllys extern char *optarg_av;
5743089Swyllys KMF_KEYSTORE_TYPE kstype = 0;
5753089Swyllys char *subject = NULL;
5763089Swyllys char *tokenname = NULL;
5773089Swyllys char *dir = NULL;
5783089Swyllys char *prefix = NULL;
5793089Swyllys char *keytype = PK_DEFAULT_KEYTYPE;
5803089Swyllys int keylen = PK_DEFAULT_KEYLENGTH;
5813089Swyllys char *trust = NULL;
5823089Swyllys char *lifetime = NULL;
5833089Swyllys char *certlabel = NULL;
5843089Swyllys char *outcert = NULL;
5853089Swyllys char *outkey = NULL;
5863089Swyllys char *format = NULL;
5873089Swyllys char *serstr = NULL;
5883089Swyllys char *altname = NULL;
5893089Swyllys char *keyusagestr = NULL;
5906051Swyllys char *ekustr = NULL;
59111973Swyllys.ingersoll@sun.com char *hashname = NULL;
5923089Swyllys KMF_GENERALNAMECHOICES alttype = 0;
5933089Swyllys KMF_BIGINT serial = { NULL, 0 };
5943089Swyllys uint32_t ltime;
5953089Swyllys KMF_HANDLE_T kmfhandle = NULL;
5963089Swyllys KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1;
5973089Swyllys KMF_KEY_ALG keyAlg = KMF_RSA;
59810744Swyllys.ingersoll@sun.com KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_SHA1WithRSA;
5993089Swyllys boolean_t interactive = B_FALSE;
6003089Swyllys char *subname = NULL;
6013089Swyllys KMF_CREDENTIAL tokencred = {NULL, 0};
6023089Swyllys uint16_t kubits = 0;
6033089Swyllys int altcrit = 0, kucrit = 0;
6046051Swyllys EKU_LIST *ekulist = NULL;
60511973Swyllys.ingersoll@sun.com KMF_OID *curveoid = NULL; /* ECC */
60611973Swyllys.ingersoll@sun.com KMF_OID *hashoid = NULL;
60711973Swyllys.ingersoll@sun.com int y_flag = 0;
6083089Swyllys
6093089Swyllys while ((opt = getopt_av(argc, argv,
6105051Swyllys "ik:(keystore)s:(subject)n:(nickname)A:(altname)"
6115051Swyllys "T:(token)d:(dir)p:(prefix)t:(keytype)y:(keylen)"
6126051Swyllys "r:(trust)L:(lifetime)l:(label)c:(outcert)e:(eku)"
61311973Swyllys.ingersoll@sun.com "K:(outkey)S:(serial)F:(format)u:(keyusage)C:(curve)"
61411973Swyllys.ingersoll@sun.com "E(listcurves)h:(hash)")) != EOF) {
6153089Swyllys
61611973Swyllys.ingersoll@sun.com if (opt != 'i' && opt != 'E' && EMPTYSTRING(optarg_av))
6173089Swyllys return (PK_ERR_USAGE);
6183089Swyllys
6193089Swyllys switch (opt) {
6203089Swyllys case 'A':
6213089Swyllys altname = optarg_av;
6223089Swyllys break;
6233089Swyllys case 'i':
6243089Swyllys if (interactive || subject)
6253089Swyllys return (PK_ERR_USAGE);
6263089Swyllys else
6273089Swyllys interactive = B_TRUE;
6283089Swyllys break;
6293089Swyllys case 'k':
6303089Swyllys kstype = KS2Int(optarg_av);
6313089Swyllys if (kstype == 0)
6323089Swyllys return (PK_ERR_USAGE);
6333089Swyllys break;
6343089Swyllys case 's':
6353089Swyllys if (interactive || subject)
6363089Swyllys return (PK_ERR_USAGE);
6373089Swyllys else
6383089Swyllys subject = optarg_av;
6393089Swyllys break;
6403089Swyllys case 'l':
6413089Swyllys case 'n':
6423089Swyllys if (certlabel)
6433089Swyllys return (PK_ERR_USAGE);
6443089Swyllys certlabel = optarg_av;
6453089Swyllys break;
6463089Swyllys case 'T':
6473089Swyllys if (tokenname)
6483089Swyllys return (PK_ERR_USAGE);
6493089Swyllys tokenname = optarg_av;
6503089Swyllys break;
6513089Swyllys case 'd':
6523089Swyllys if (dir)
6533089Swyllys return (PK_ERR_USAGE);
6543089Swyllys dir = optarg_av;
6553089Swyllys break;
6563089Swyllys case 'p':
6573089Swyllys if (prefix)
6583089Swyllys return (PK_ERR_USAGE);
6593089Swyllys prefix = optarg_av;
6603089Swyllys break;
6613089Swyllys case 't':
6623089Swyllys keytype = optarg_av;
6633089Swyllys break;
6643089Swyllys case 'u':
6653089Swyllys keyusagestr = optarg_av;
6663089Swyllys break;
6673089Swyllys case 'y':
6683089Swyllys if (sscanf(optarg_av, "%d",
6695051Swyllys &keylen) != 1) {
6703089Swyllys cryptoerror(LOG_STDERR,
6715051Swyllys gettext("key length must be"
6725051Swyllys "a numeric value (%s)\n"),
6735051Swyllys optarg_av);
6743089Swyllys return (PK_ERR_USAGE);
6753089Swyllys }
67611973Swyllys.ingersoll@sun.com y_flag++;
6773089Swyllys break;
6783089Swyllys case 'r':
6793089Swyllys if (trust)
6803089Swyllys return (PK_ERR_USAGE);
6813089Swyllys trust = optarg_av;
6823089Swyllys break;
6833089Swyllys case 'L':
6843089Swyllys if (lifetime)
6853089Swyllys return (PK_ERR_USAGE);
6863089Swyllys lifetime = optarg_av;
6873089Swyllys break;
6883089Swyllys case 'c':
6893089Swyllys if (outcert)
6903089Swyllys return (PK_ERR_USAGE);
6913089Swyllys outcert = optarg_av;
6923089Swyllys break;
6933089Swyllys case 'K':
6943089Swyllys if (outkey)
6953089Swyllys return (PK_ERR_USAGE);
6963089Swyllys outkey = optarg_av;
6973089Swyllys break;
6983089Swyllys case 'S':
6993089Swyllys serstr = optarg_av;
7003089Swyllys break;
7013089Swyllys case 'F':
7023089Swyllys if (format)
7033089Swyllys return (PK_ERR_USAGE);
7043089Swyllys format = optarg_av;
7053089Swyllys break;
7066051Swyllys case 'e':
7076051Swyllys ekustr = optarg_av;
7086051Swyllys break;
70911973Swyllys.ingersoll@sun.com case 'C':
71011973Swyllys.ingersoll@sun.com curveoid = ecc_name_to_oid(optarg_av);
71111973Swyllys.ingersoll@sun.com if (curveoid == NULL) {
71211973Swyllys.ingersoll@sun.com cryptoerror(LOG_STDERR,
71311973Swyllys.ingersoll@sun.com gettext("Unrecognized ECC "
71411973Swyllys.ingersoll@sun.com "curve.\n"));
71511973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE);
71611973Swyllys.ingersoll@sun.com }
71711973Swyllys.ingersoll@sun.com break;
71811973Swyllys.ingersoll@sun.com case 'E':
71911973Swyllys.ingersoll@sun.com /*
72011973Swyllys.ingersoll@sun.com * This argument is only to be used
72111973Swyllys.ingersoll@sun.com * by itself, no other options should
72211973Swyllys.ingersoll@sun.com * be present.
72311973Swyllys.ingersoll@sun.com */
72411973Swyllys.ingersoll@sun.com if (argc != 2) {
72511973Swyllys.ingersoll@sun.com cryptoerror(LOG_STDERR,
72611973Swyllys.ingersoll@sun.com gettext("listcurves has no other "
72711973Swyllys.ingersoll@sun.com "options.\n"));
72811973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE);
72911973Swyllys.ingersoll@sun.com }
73011973Swyllys.ingersoll@sun.com show_ecc_curves();
73111973Swyllys.ingersoll@sun.com return (0);
73211973Swyllys.ingersoll@sun.com case 'h':
73311973Swyllys.ingersoll@sun.com hashname = optarg_av;
73411973Swyllys.ingersoll@sun.com hashoid = ecc_name_to_oid(optarg_av);
73511973Swyllys.ingersoll@sun.com if (hashoid == NULL) {
73611973Swyllys.ingersoll@sun.com cryptoerror(LOG_STDERR,
73711973Swyllys.ingersoll@sun.com gettext("Unrecognized hash.\n"));
73811973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE);
73911973Swyllys.ingersoll@sun.com }
74011973Swyllys.ingersoll@sun.com break;
7413089Swyllys default:
7423089Swyllys return (PK_ERR_USAGE);
7433089Swyllys }
7443089Swyllys }
7453089Swyllys
7463089Swyllys /* No additional args allowed. */
7473089Swyllys argc -= optind_av;
7483089Swyllys argv += optind_av;
7493089Swyllys if (argc) {
7503089Swyllys return (PK_ERR_USAGE);
7513089Swyllys }
7523089Swyllys
7535051Swyllys if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
7543089Swyllys cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n"));
7553089Swyllys return (PK_ERR_USAGE);
7563089Swyllys }
7573089Swyllys
7583089Swyllys /* Assume keystore = PKCS#11 if not specified. */
7593089Swyllys if (kstype == 0)
7603089Swyllys kstype = KMF_KEYSTORE_PK11TOKEN;
7613089Swyllys
7625221Swyllys if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN)) {
7635221Swyllys if (interactive && EMPTYSTRING(certlabel)) {
7645221Swyllys (void) get_certlabel(&certlabel);
7655221Swyllys }
7665221Swyllys /* It better not be empty now */
7675221Swyllys if (EMPTYSTRING(certlabel)) {
7685221Swyllys cryptoerror(LOG_STDERR, gettext("A label must be "
7695221Swyllys "specified to create a self-signed certificate."
7705221Swyllys "\n"));
7715221Swyllys return (PK_ERR_USAGE);
7725221Swyllys }
7733089Swyllys } else if (kstype == KMF_KEYSTORE_OPENSSL && EMPTYSTRING(outcert)) {
7743089Swyllys cryptoerror(LOG_STDERR, gettext("A certificate filename must "
7753089Swyllys "be specified to create a self-signed certificate.\n"));
7763089Swyllys return (PK_ERR_USAGE);
7773089Swyllys }
7783089Swyllys
7796884Swyllys DIR_OPTION_CHECK(kstype, dir);
7806884Swyllys
7813089Swyllys if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) {
7823089Swyllys cryptoerror(LOG_STDERR,
7833089Swyllys gettext("Error parsing format string (%s).\n"),
7843089Swyllys format);
7853089Swyllys return (PK_ERR_USAGE);
7863089Swyllys }
7873089Swyllys
7883089Swyllys if (Str2Lifetime(lifetime, <ime) != 0) {
7893089Swyllys cryptoerror(LOG_STDERR,
7905051Swyllys gettext("Error parsing lifetime string\n"));
7913089Swyllys return (PK_ERR_USAGE);
7923089Swyllys }
7933089Swyllys
79411973Swyllys.ingersoll@sun.com if (Str2KeyType(keytype, hashoid, &keyAlg, &sigAlg) != 0) {
79511973Swyllys.ingersoll@sun.com cryptoerror(LOG_STDERR,
79611973Swyllys.ingersoll@sun.com gettext("Unsupported key/hash combination (%s/%s).\n"),
79711973Swyllys.ingersoll@sun.com keytype, (hashname ? hashname : "none"));
7983089Swyllys return (PK_ERR_USAGE);
7993089Swyllys }
80011973Swyllys.ingersoll@sun.com if (curveoid != NULL && keyAlg != KMF_ECDSA) {
80111973Swyllys.ingersoll@sun.com cryptoerror(LOG_STDERR, gettext("EC curves are only "
80211973Swyllys.ingersoll@sun.com "valid for EC keytypes.\n"));
80311973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE);
80411973Swyllys.ingersoll@sun.com }
80511973Swyllys.ingersoll@sun.com if (keyAlg == KMF_ECDSA && curveoid == NULL) {
80611973Swyllys.ingersoll@sun.com cryptoerror(LOG_STDERR, gettext("A curve must be "
80711973Swyllys.ingersoll@sun.com "specifed when using EC keys.\n"));
80811973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE);
80911973Swyllys.ingersoll@sun.com }
81011973Swyllys.ingersoll@sun.com /* Adjust default keylength for NSS and DSA */
81111973Swyllys.ingersoll@sun.com if (keyAlg == KMF_DSA && !y_flag && kstype == KMF_KEYSTORE_NSS)
81211973Swyllys.ingersoll@sun.com keylen = 1024;
8133089Swyllys
8143089Swyllys /*
8153089Swyllys * Check the subject name.
8163089Swyllys * If interactive is true, get it now interactively.
8173089Swyllys */
8183089Swyllys if (interactive) {
8195221Swyllys subname = NULL;
8205221Swyllys if (get_subname(&subname) != KMF_OK || subname == NULL) {
8213089Swyllys cryptoerror(LOG_STDERR, gettext("Failed to get the "
8223089Swyllys "subject name interactively.\n"));
8233089Swyllys return (PK_ERR_USAGE);
8243089Swyllys }
8255221Swyllys if (serstr == NULL) {
8265221Swyllys (void) get_serial(&serstr);
8275221Swyllys }
8283089Swyllys } else {
8293089Swyllys if (EMPTYSTRING(subject)) {
8303089Swyllys cryptoerror(LOG_STDERR, gettext("A subject name or "
8313089Swyllys "-i must be specified to create a self-signed "
8323089Swyllys "certificate.\n"));
8333089Swyllys return (PK_ERR_USAGE);
8343089Swyllys } else {
8353089Swyllys subname = strdup(subject);
8363089Swyllys if (subname == NULL) {
8373089Swyllys cryptoerror(LOG_STDERR,
8383089Swyllys gettext("Out of memory.\n"));
8393089Swyllys return (PK_ERR_SYSTEM);
8403089Swyllys }
8413089Swyllys }
8423089Swyllys }
8433089Swyllys
8443089Swyllys if (serstr == NULL) {
8453089Swyllys (void) fprintf(stderr, gettext("A serial number "
8465051Swyllys "must be specified as a hex number when creating"
8475051Swyllys " a self-signed certificate "
8485051Swyllys "(ex: serial=0x0102030405feedface)\n"));
8493089Swyllys rv = PK_ERR_USAGE;
8503089Swyllys goto end;
8513089Swyllys } else {
8523089Swyllys uchar_t *bytes = NULL;
8533089Swyllys size_t bytelen;
8543089Swyllys
8555051Swyllys rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen);
8563089Swyllys if (rv != KMF_OK || bytes == NULL) {
8573089Swyllys (void) fprintf(stderr, gettext("serial number "
8585051Swyllys "must be specified as a hex number "
8595051Swyllys "(ex: 0x0102030405ffeeddee)\n"));
8603089Swyllys rv = PK_ERR_USAGE;
8613089Swyllys goto end;
8623089Swyllys }
8633089Swyllys serial.val = bytes;
8643089Swyllys serial.len = bytelen;
8653089Swyllys }
8663089Swyllys
8673089Swyllys if (altname != NULL) {
8683089Swyllys rv = verify_altname(altname, &alttype, &altcrit);
8693089Swyllys if (rv != KMF_OK) {
8703089Swyllys (void) fprintf(stderr, gettext("Subject AltName "
8715051Swyllys "must be specified as a name=value pair. "
8725051Swyllys "See the man page for details.\n"));
8733089Swyllys rv = PK_ERR_USAGE;
8743089Swyllys goto end;
8753089Swyllys } else {
8763089Swyllys /* advance the altname past the '=' sign */
8773089Swyllys char *p = strchr(altname, '=');
8783089Swyllys if (p != NULL)
8793089Swyllys altname = p + 1;
8803089Swyllys }
8813089Swyllys }
8823089Swyllys
8833089Swyllys if (keyusagestr != NULL) {
8843089Swyllys rv = verify_keyusage(keyusagestr, &kubits, &kucrit);
8853089Swyllys if (rv != KMF_OK) {
8863089Swyllys (void) fprintf(stderr, gettext("KeyUsage "
8875051Swyllys "must be specified as a comma-separated list. "
8885051Swyllys "See the man page for details.\n"));
8893089Swyllys rv = PK_ERR_USAGE;
8903089Swyllys goto end;
8913089Swyllys }
8923089Swyllys }
8936051Swyllys if (ekustr != NULL) {
8946051Swyllys rv = verify_ekunames(ekustr, &ekulist);
8956051Swyllys if (rv != KMF_OK) {
8966051Swyllys (void) fprintf(stderr, gettext("EKUs must "
8976051Swyllys "be specified as a comma-separated list. "
8986051Swyllys "See the man page for details.\n"));
8996051Swyllys rv = PK_ERR_USAGE;
9006051Swyllys goto end;
9016051Swyllys }
9026051Swyllys }
90311973Swyllys.ingersoll@sun.com if (keyAlg == KMF_ECDSA && kstype == KMF_KEYSTORE_OPENSSL) {
90411973Swyllys.ingersoll@sun.com (void) fprintf(stderr, gettext("ECC certificates are"
90511973Swyllys.ingersoll@sun.com "only supported with the pkcs11 and nss keystores\n"));
90611973Swyllys.ingersoll@sun.com rv = PK_ERR_USAGE;
90711973Swyllys.ingersoll@sun.com goto end;
90811973Swyllys.ingersoll@sun.com }
9093089Swyllys
9103089Swyllys if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) {
9113089Swyllys if (tokenname == NULL || !strlen(tokenname)) {
9123089Swyllys if (kstype == KMF_KEYSTORE_NSS) {
9133089Swyllys tokenname = "internal";
9143089Swyllys } else {
9153089Swyllys tokenname = PK_DEFAULT_PK11TOKEN;
9163089Swyllys }
9173089Swyllys }
9183089Swyllys
9193089Swyllys (void) get_token_password(kstype, tokenname, &tokencred);
9203089Swyllys }
9213089Swyllys
9223089Swyllys if (kstype == KMF_KEYSTORE_NSS) {
9233089Swyllys if (dir == NULL)
9243089Swyllys dir = PK_DEFAULT_DIRECTORY;
9253089Swyllys
9263089Swyllys rv = gencert_nss(kmfhandle,
9275051Swyllys tokenname, subname, altname, alttype, altcrit,
9285051Swyllys certlabel, dir, prefix, keyAlg, sigAlg, keylen,
9296051Swyllys trust, ltime, &serial, kubits, kucrit, &tokencred,
93011973Swyllys.ingersoll@sun.com ekulist, curveoid);
9313089Swyllys
9323089Swyllys } else if (kstype == KMF_KEYSTORE_PK11TOKEN) {
9333089Swyllys rv = gencert_pkcs11(kmfhandle,
9345051Swyllys tokenname, subname, altname, alttype, altcrit,
9355051Swyllys certlabel, keyAlg, sigAlg, keylen, ltime,
93611973Swyllys.ingersoll@sun.com &serial, kubits, kucrit, &tokencred, ekulist,
93711973Swyllys.ingersoll@sun.com curveoid);
9383089Swyllys
9393089Swyllys } else if (kstype == KMF_KEYSTORE_OPENSSL) {
9403089Swyllys rv = gencert_file(kmfhandle,
9415051Swyllys keyAlg, sigAlg, keylen, fmt,
9425051Swyllys ltime, subname, altname, alttype, altcrit,
9436669Swyllys &serial, kubits, kucrit, outcert, outkey,
9446051Swyllys ekulist);
9453089Swyllys }
9463089Swyllys
9473089Swyllys if (rv != KMF_OK)
9483089Swyllys display_error(kmfhandle, rv,
9495051Swyllys gettext("Error creating certificate and keypair"));
9503089Swyllys end:
9516051Swyllys if (ekulist != NULL)
9526051Swyllys free_eku_list(ekulist);
9533089Swyllys if (subname)
9543089Swyllys free(subname);
9553089Swyllys if (tokencred.cred != NULL)
9563089Swyllys free(tokencred.cred);
9573089Swyllys
9583089Swyllys if (serial.val != NULL)
9593089Swyllys free(serial.val);
9603089Swyllys
9615051Swyllys (void) kmf_finalize(kmfhandle);
9623089Swyllys return (rv);
9633089Swyllys }
964