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 *
212c9a247fSWyllys Ingersoll * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
2299ebb4caSwyllys */
2399ebb4caSwyllys
2499ebb4caSwyllys #include <stdio.h>
2599ebb4caSwyllys #include <string.h>
2699ebb4caSwyllys #include <ctype.h>
2799ebb4caSwyllys #include <malloc.h>
2899ebb4caSwyllys #include <libgen.h>
2999ebb4caSwyllys #include <errno.h>
3099ebb4caSwyllys #include <cryptoutil.h>
3199ebb4caSwyllys #include <security/cryptoki.h>
3299ebb4caSwyllys #include "common.h"
3399ebb4caSwyllys
3499ebb4caSwyllys #include <kmfapi.h>
3599ebb4caSwyllys
3699ebb4caSwyllys #define SET_VALUE(f, s) \
3799ebb4caSwyllys kmfrv = f; \
3899ebb4caSwyllys if (kmfrv != KMF_OK) { \
3999ebb4caSwyllys cryptoerror(LOG_STDERR, \
4099ebb4caSwyllys gettext("Failed to %s: 0x%02\n"), \
4199ebb4caSwyllys s, kmfrv); \
4299ebb4caSwyllys goto cleanup; \
4399ebb4caSwyllys }
4499ebb4caSwyllys
4599ebb4caSwyllys static KMF_RETURN
gencsr_pkcs11(KMF_HANDLE_T kmfhandle,char * token,char * subject,char * altname,KMF_GENERALNAMECHOICES alttype,int altcrit,char * certlabel,KMF_KEY_ALG keyAlg,int keylen,uint16_t kubits,int kucrit,KMF_ENCODE_FORMAT fmt,char * csrfile,KMF_CREDENTIAL * tokencred,EKU_LIST * ekulist,KMF_ALGORITHM_INDEX sigAlg,KMF_OID * curveoid)4699ebb4caSwyllys gencsr_pkcs11(KMF_HANDLE_T kmfhandle,
4799ebb4caSwyllys char *token, char *subject, char *altname,
4899ebb4caSwyllys KMF_GENERALNAMECHOICES alttype, int altcrit,
4999ebb4caSwyllys char *certlabel, KMF_KEY_ALG keyAlg,
50d00756ccSwyllys int keylen, uint16_t kubits, int kucrit,
5199ebb4caSwyllys KMF_ENCODE_FORMAT fmt, char *csrfile,
52e65e5c2dSWyllys Ingersoll KMF_CREDENTIAL *tokencred, EKU_LIST *ekulist,
53e65e5c2dSWyllys Ingersoll KMF_ALGORITHM_INDEX sigAlg, KMF_OID *curveoid)
5499ebb4caSwyllys {
5599ebb4caSwyllys KMF_RETURN kmfrv = KMF_OK;
5699ebb4caSwyllys KMF_KEY_HANDLE pubk, prik;
5799ebb4caSwyllys KMF_X509_NAME csrSubject;
5899ebb4caSwyllys KMF_CSR_DATA csr;
59*6b35cb3cSRichard PALO KMF_DATA signedCsr = { 0, NULL };
6099ebb4caSwyllys
6130a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
6230a5e8faSwyllys int numattr = 0;
6330a5e8faSwyllys KMF_ATTRIBUTE attrlist[16];
6430a5e8faSwyllys
6599ebb4caSwyllys (void) memset(&csr, 0, sizeof (csr));
6699ebb4caSwyllys (void) memset(&csrSubject, 0, sizeof (csrSubject));
6799ebb4caSwyllys
6899ebb4caSwyllys /* If the subject name cannot be parsed, flag it now and exit */
69e65e5c2dSWyllys Ingersoll if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK)
7099ebb4caSwyllys return (kmfrv);
7199ebb4caSwyllys
7299ebb4caSwyllys /* Select a PKCS11 token */
7399ebb4caSwyllys kmfrv = select_token(kmfhandle, token, FALSE);
74e65e5c2dSWyllys Ingersoll if (kmfrv != KMF_OK)
7599ebb4caSwyllys return (kmfrv);
76e65e5c2dSWyllys Ingersoll /*
77e65e5c2dSWyllys Ingersoll * Share the "genkeypair" routine for creating the keypair.
78e65e5c2dSWyllys Ingersoll */
79e65e5c2dSWyllys Ingersoll kmfrv = genkeypair_pkcs11(kmfhandle, token, certlabel,
80e65e5c2dSWyllys Ingersoll keyAlg, keylen, tokencred, curveoid, &prik, &pubk);
81e65e5c2dSWyllys Ingersoll if (kmfrv != KMF_OK)
8299ebb4caSwyllys return (kmfrv);
8399ebb4caSwyllys
8430a5e8faSwyllys SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr), "keypair");
8599ebb4caSwyllys
8630a5e8faSwyllys SET_VALUE(kmf_set_csr_version(&csr, 2), "version number");
8799ebb4caSwyllys
8830a5e8faSwyllys SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject), "subject name");
8999ebb4caSwyllys
9030a5e8faSwyllys SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg),
9199ebb4caSwyllys "SignatureAlgorithm");
9299ebb4caSwyllys
9399ebb4caSwyllys if (altname != NULL) {
9430a5e8faSwyllys SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit,
9599ebb4caSwyllys alttype), "SetCSRSubjectAltName");
9699ebb4caSwyllys }
9799ebb4caSwyllys
9899ebb4caSwyllys if (kubits != 0) {
9930a5e8faSwyllys SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits),
10099ebb4caSwyllys "SetCSRKeyUsage");
10199ebb4caSwyllys }
102d00756ccSwyllys if (ekulist != NULL) {
103d00756ccSwyllys int i;
104d00756ccSwyllys for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
105d00756ccSwyllys SET_VALUE(kmf_add_csr_eku(&csr,
106d00756ccSwyllys &ekulist->ekulist[i],
107d00756ccSwyllys ekulist->critlist[i]),
108d00756ccSwyllys "Extended Key Usage");
109d00756ccSwyllys }
110d00756ccSwyllys }
11130a5e8faSwyllys if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) ==
11299ebb4caSwyllys KMF_OK) {
11330a5e8faSwyllys kmfrv = kmf_create_csr_file(&signedCsr, fmt, csrfile);
11499ebb4caSwyllys }
11599ebb4caSwyllys
11699ebb4caSwyllys cleanup:
11730a5e8faSwyllys (void) kmf_free_data(&signedCsr);
118a44b45c8SHuie-Ying Lee (void) kmf_free_signed_csr(&csr);
119a44b45c8SHuie-Ying Lee
120a44b45c8SHuie-Ying Lee /* delete the public key */
12130a5e8faSwyllys numattr = 0;
12230a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
12330a5e8faSwyllys &kstype, sizeof (kstype));
12430a5e8faSwyllys numattr++;
12530a5e8faSwyllys
12630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR,
12730a5e8faSwyllys &pubk, sizeof (KMF_KEY_HANDLE));
12830a5e8faSwyllys numattr++;
12930a5e8faSwyllys
130a44b45c8SHuie-Ying Lee if (tokencred != NULL && tokencred->cred != NULL) {
131a44b45c8SHuie-Ying Lee kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
132a44b45c8SHuie-Ying Lee tokencred, sizeof (KMF_CREDENTIAL));
133a44b45c8SHuie-Ying Lee numattr++;
134a44b45c8SHuie-Ying Lee }
135a44b45c8SHuie-Ying Lee
13630a5e8faSwyllys (void) kmf_delete_key_from_keystore(kmfhandle, numattr, attrlist);
13730a5e8faSwyllys
138a44b45c8SHuie-Ying Lee /*
139a44b45c8SHuie-Ying Lee * If there is an error, then we need to remove the private key
140a44b45c8SHuie-Ying Lee * from the token.
141a44b45c8SHuie-Ying Lee */
142a44b45c8SHuie-Ying Lee if (kmfrv != KMF_OK) {
143a44b45c8SHuie-Ying Lee numattr = 0;
144a44b45c8SHuie-Ying Lee kmf_set_attr_at_index(attrlist, numattr,
145a44b45c8SHuie-Ying Lee KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
146a44b45c8SHuie-Ying Lee numattr++;
14799ebb4caSwyllys
148a44b45c8SHuie-Ying Lee kmf_set_attr_at_index(attrlist, numattr,
149a44b45c8SHuie-Ying Lee KMF_KEY_HANDLE_ATTR, &prik, sizeof (KMF_KEY_HANDLE));
150a44b45c8SHuie-Ying Lee numattr++;
151a44b45c8SHuie-Ying Lee
152a44b45c8SHuie-Ying Lee if (tokencred != NULL && tokencred->cred != NULL) {
153a44b45c8SHuie-Ying Lee kmf_set_attr_at_index(attrlist, numattr,
154a44b45c8SHuie-Ying Lee KMF_CREDENTIAL_ATTR, tokencred,
155a44b45c8SHuie-Ying Lee sizeof (KMF_CREDENTIAL));
156a44b45c8SHuie-Ying Lee numattr++;
157a44b45c8SHuie-Ying Lee }
158a44b45c8SHuie-Ying Lee
159a44b45c8SHuie-Ying Lee (void) kmf_delete_key_from_keystore(kmfhandle, numattr,
160a44b45c8SHuie-Ying Lee attrlist);
161a44b45c8SHuie-Ying Lee }
162a44b45c8SHuie-Ying Lee
163a44b45c8SHuie-Ying Lee (void) kmf_free_kmf_key(kmfhandle, &prik);
16499ebb4caSwyllys return (kmfrv);
16599ebb4caSwyllys }
16699ebb4caSwyllys
16799ebb4caSwyllys static KMF_RETURN
gencsr_file(KMF_HANDLE_T kmfhandle,KMF_KEY_ALG keyAlg,int keylen,KMF_ENCODE_FORMAT fmt,char * subject,char * altname,KMF_GENERALNAMECHOICES alttype,int altcrit,uint16_t kubits,int kucrit,char * outcsr,char * outkey,EKU_LIST * ekulist,KMF_ALGORITHM_INDEX sigAlg)16899ebb4caSwyllys gencsr_file(KMF_HANDLE_T kmfhandle,
16999ebb4caSwyllys KMF_KEY_ALG keyAlg,
17099ebb4caSwyllys int keylen, KMF_ENCODE_FORMAT fmt,
17199ebb4caSwyllys char *subject, char *altname, KMF_GENERALNAMECHOICES alttype,
17299ebb4caSwyllys int altcrit, uint16_t kubits, int kucrit,
173e65e5c2dSWyllys Ingersoll char *outcsr, char *outkey, EKU_LIST *ekulist,
174e65e5c2dSWyllys Ingersoll KMF_ALGORITHM_INDEX sigAlg)
17599ebb4caSwyllys {
17699ebb4caSwyllys KMF_RETURN kmfrv;
17799ebb4caSwyllys KMF_KEY_HANDLE pubk, prik;
17899ebb4caSwyllys KMF_X509_NAME csrSubject;
17999ebb4caSwyllys KMF_CSR_DATA csr;
180*6b35cb3cSRichard PALO KMF_DATA signedCsr = { 0, NULL };
18199ebb4caSwyllys char *fullcsrpath = NULL;
18299ebb4caSwyllys char *fullkeypath = NULL;
18399ebb4caSwyllys
18430a5e8faSwyllys
18599ebb4caSwyllys (void) memset(&csr, 0, sizeof (csr));
18699ebb4caSwyllys (void) memset(&csrSubject, 0, sizeof (csrSubject));
18799ebb4caSwyllys
18899ebb4caSwyllys if (EMPTYSTRING(outcsr) || EMPTYSTRING(outkey)) {
18999ebb4caSwyllys cryptoerror(LOG_STDERR,
19099ebb4caSwyllys gettext("No output file was specified for "
19199ebb4caSwyllys "the csr or key\n"));
19299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER);
19399ebb4caSwyllys }
19499ebb4caSwyllys fullcsrpath = strdup(outcsr);
19599ebb4caSwyllys if (verify_file(fullcsrpath)) {
19699ebb4caSwyllys cryptoerror(LOG_STDERR,
19799ebb4caSwyllys gettext("Cannot write the indicated output "
19899ebb4caSwyllys "certificate file (%s).\n"), fullcsrpath);
19999ebb4caSwyllys free(fullcsrpath);
20099ebb4caSwyllys return (PK_ERR_USAGE);
20199ebb4caSwyllys }
202448b8615Swyllys
20399ebb4caSwyllys /* If the subject name cannot be parsed, flag it now and exit */
20430a5e8faSwyllys if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) {
20599ebb4caSwyllys return (kmfrv);
20699ebb4caSwyllys }
207e65e5c2dSWyllys Ingersoll /*
208e65e5c2dSWyllys Ingersoll * Share the "genkeypair" routine for creating the keypair.
209e65e5c2dSWyllys Ingersoll */
210e65e5c2dSWyllys Ingersoll kmfrv = genkeypair_file(kmfhandle, keyAlg, keylen,
211e65e5c2dSWyllys Ingersoll fmt, outkey, &prik, &pubk);
212e65e5c2dSWyllys Ingersoll if (kmfrv != KMF_OK)
213e65e5c2dSWyllys Ingersoll return (kmfrv);
21499ebb4caSwyllys
21530a5e8faSwyllys SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr),
21699ebb4caSwyllys "SetCSRPubKey");
21799ebb4caSwyllys
21830a5e8faSwyllys SET_VALUE(kmf_set_csr_version(&csr, 2), "SetCSRVersion");
21999ebb4caSwyllys
22030a5e8faSwyllys SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject),
22130a5e8faSwyllys "kmf_set_csr_subject");
22299ebb4caSwyllys
22330a5e8faSwyllys SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg), "kmf_set_csr_sig_alg");
22499ebb4caSwyllys
22599ebb4caSwyllys if (altname != NULL) {
22630a5e8faSwyllys SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit,
22730a5e8faSwyllys alttype), "kmf_set_csr_subject_altname");
22899ebb4caSwyllys }
22999ebb4caSwyllys if (kubits != NULL) {
23030a5e8faSwyllys SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits),
23130a5e8faSwyllys "kmf_set_csr_ku");
23299ebb4caSwyllys }
233d00756ccSwyllys if (ekulist != NULL) {
234d00756ccSwyllys int i;
235d00756ccSwyllys for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
236d00756ccSwyllys SET_VALUE(kmf_add_csr_eku(&csr,
237d00756ccSwyllys &ekulist->ekulist[i],
238d00756ccSwyllys ekulist->critlist[i]),
239d00756ccSwyllys "Extended Key Usage");
240d00756ccSwyllys }
241d00756ccSwyllys }
24230a5e8faSwyllys if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) ==
24399ebb4caSwyllys KMF_OK) {
24430a5e8faSwyllys kmfrv = kmf_create_csr_file(&signedCsr, fmt, fullcsrpath);
24599ebb4caSwyllys }
24699ebb4caSwyllys
24799ebb4caSwyllys cleanup:
24899ebb4caSwyllys if (fullkeypath)
24999ebb4caSwyllys free(fullkeypath);
25099ebb4caSwyllys if (fullcsrpath)
25199ebb4caSwyllys free(fullcsrpath);
25299ebb4caSwyllys
25330a5e8faSwyllys kmf_free_data(&signedCsr);
25430a5e8faSwyllys kmf_free_kmf_key(kmfhandle, &prik);
25530a5e8faSwyllys kmf_free_signed_csr(&csr);
25699ebb4caSwyllys
25799ebb4caSwyllys return (kmfrv);
25899ebb4caSwyllys }
25999ebb4caSwyllys
26099ebb4caSwyllys static KMF_RETURN
gencsr_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,int keylen,uint16_t kubits,int kucrit,KMF_ENCODE_FORMAT fmt,char * csrfile,KMF_CREDENTIAL * tokencred,EKU_LIST * ekulist,KMF_ALGORITHM_INDEX sigAlg,KMF_OID * curveoid)26199ebb4caSwyllys gencsr_nss(KMF_HANDLE_T kmfhandle,
26299ebb4caSwyllys char *token, char *subject, char *altname,
26399ebb4caSwyllys KMF_GENERALNAMECHOICES alttype, int altcrit,
26499ebb4caSwyllys char *nickname, char *dir, char *prefix,
26599ebb4caSwyllys KMF_KEY_ALG keyAlg, int keylen,
26699ebb4caSwyllys uint16_t kubits, int kucrit,
26799ebb4caSwyllys KMF_ENCODE_FORMAT fmt, char *csrfile,
268e65e5c2dSWyllys Ingersoll KMF_CREDENTIAL *tokencred, EKU_LIST *ekulist,
269e65e5c2dSWyllys Ingersoll KMF_ALGORITHM_INDEX sigAlg, KMF_OID *curveoid)
27099ebb4caSwyllys {
27199ebb4caSwyllys KMF_RETURN kmfrv;
27299ebb4caSwyllys KMF_KEY_HANDLE pubk, prik;
27399ebb4caSwyllys KMF_X509_NAME csrSubject;
27499ebb4caSwyllys KMF_CSR_DATA csr;
275*6b35cb3cSRichard PALO KMF_DATA signedCsr = { 0, NULL };
27630a5e8faSwyllys
27730a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
27830a5e8faSwyllys int numattr = 0;
27930a5e8faSwyllys KMF_ATTRIBUTE attrlist[16];
28099ebb4caSwyllys
28199ebb4caSwyllys if (token == NULL)
28299ebb4caSwyllys token = DEFAULT_NSS_TOKEN;
28399ebb4caSwyllys
28499ebb4caSwyllys kmfrv = configure_nss(kmfhandle, dir, prefix);
28599ebb4caSwyllys if (kmfrv != KMF_OK)
28699ebb4caSwyllys return (kmfrv);
28799ebb4caSwyllys
28899ebb4caSwyllys (void) memset(&csr, 0, sizeof (csr));
28999ebb4caSwyllys (void) memset(&csrSubject, 0, sizeof (csrSubject));
290448b8615Swyllys (void) memset(&pubk, 0, sizeof (pubk));
291448b8615Swyllys (void) memset(&prik, 0, sizeof (prik));
29299ebb4caSwyllys
29399ebb4caSwyllys /* If the subject name cannot be parsed, flag it now and exit */
29430a5e8faSwyllys if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) {
29599ebb4caSwyllys return (kmfrv);
29699ebb4caSwyllys }
29799ebb4caSwyllys
298e65e5c2dSWyllys Ingersoll kmfrv = genkeypair_nss(kmfhandle, token, nickname, dir,
299e65e5c2dSWyllys Ingersoll prefix, keyAlg, keylen, tokencred, curveoid,
300e65e5c2dSWyllys Ingersoll &prik, &pubk);
301e65e5c2dSWyllys Ingersoll if (kmfrv != KMF_OK)
302e65e5c2dSWyllys Ingersoll return (kmfrv);
30399ebb4caSwyllys
30430a5e8faSwyllys SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr),
30530a5e8faSwyllys "kmf_set_csr_pubkey");
30630a5e8faSwyllys SET_VALUE(kmf_set_csr_version(&csr, 2), "kmf_set_csr_version");
30730a5e8faSwyllys SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject),
30830a5e8faSwyllys "kmf_set_csr_subject");
30930a5e8faSwyllys SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg), "kmf_set_csr_sig_alg");
31099ebb4caSwyllys
31199ebb4caSwyllys if (altname != NULL) {
31230a5e8faSwyllys SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit,
31330a5e8faSwyllys alttype), "kmf_set_csr_subject_altname");
31499ebb4caSwyllys }
31599ebb4caSwyllys if (kubits != NULL) {
31630a5e8faSwyllys SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits),
31730a5e8faSwyllys "kmf_set_csr_ku");
31899ebb4caSwyllys }
319d00756ccSwyllys if (ekulist != NULL) {
320d00756ccSwyllys int i;
321d00756ccSwyllys for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
322d00756ccSwyllys SET_VALUE(kmf_add_csr_eku(&csr,
323d00756ccSwyllys &ekulist->ekulist[i],
324d00756ccSwyllys ekulist->critlist[i]),
325d00756ccSwyllys "Extended Key Usage");
326d00756ccSwyllys }
327d00756ccSwyllys }
32830a5e8faSwyllys if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) ==
32999ebb4caSwyllys KMF_OK) {
33030a5e8faSwyllys kmfrv = kmf_create_csr_file(&signedCsr, fmt, csrfile);
33199ebb4caSwyllys }
33299ebb4caSwyllys
33399ebb4caSwyllys cleanup:
33430a5e8faSwyllys (void) kmf_free_data(&signedCsr);
33530a5e8faSwyllys (void) kmf_free_kmf_key(kmfhandle, &prik);
33630a5e8faSwyllys
33799ebb4caSwyllys /* delete the key */
33830a5e8faSwyllys numattr = 0;
33930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
34030a5e8faSwyllys &kstype, sizeof (kstype));
34130a5e8faSwyllys numattr++;
34230a5e8faSwyllys
34330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR,
34430a5e8faSwyllys &pubk, sizeof (KMF_KEY_HANDLE));
34530a5e8faSwyllys numattr++;
34630a5e8faSwyllys
34730a5e8faSwyllys if (tokencred != NULL && tokencred->credlen > 0) {
34830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
34930a5e8faSwyllys tokencred, sizeof (KMF_CREDENTIAL));
35030a5e8faSwyllys numattr++;
35130a5e8faSwyllys }
35230a5e8faSwyllys
35330a5e8faSwyllys if (token && strlen(token)) {
35430a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
35530a5e8faSwyllys token, strlen(token));
35630a5e8faSwyllys numattr++;
35730a5e8faSwyllys }
35830a5e8faSwyllys
35930a5e8faSwyllys (void) kmf_delete_key_from_keystore(kmfhandle, numattr, attrlist);
36030a5e8faSwyllys
36130a5e8faSwyllys (void) kmf_free_signed_csr(&csr);
36299ebb4caSwyllys
36399ebb4caSwyllys return (kmfrv);
36499ebb4caSwyllys }
36599ebb4caSwyllys
36699ebb4caSwyllys int
pk_gencsr(int argc,char * argv[])36799ebb4caSwyllys pk_gencsr(int argc, char *argv[])
36899ebb4caSwyllys {
36999ebb4caSwyllys KMF_RETURN rv;
37099ebb4caSwyllys int opt;
37199ebb4caSwyllys extern int optind_av;
37299ebb4caSwyllys extern char *optarg_av;
37399ebb4caSwyllys KMF_KEYSTORE_TYPE kstype = 0;
37499ebb4caSwyllys char *subject = NULL;
37599ebb4caSwyllys char *tokenname = NULL;
37699ebb4caSwyllys char *dir = NULL;
37799ebb4caSwyllys char *prefix = NULL;
37899ebb4caSwyllys int keylen = PK_DEFAULT_KEYLENGTH;
37999ebb4caSwyllys char *certlabel = NULL;
38099ebb4caSwyllys char *outcsr = NULL;
38199ebb4caSwyllys char *outkey = NULL;
38299ebb4caSwyllys char *format = NULL;
38399ebb4caSwyllys char *altname = NULL;
38499ebb4caSwyllys char *kustr = NULL;
385d00756ccSwyllys char *ekustr = NULL;
386e65e5c2dSWyllys Ingersoll char *hashname = NULL;
38799ebb4caSwyllys uint16_t kubits = 0;
38899ebb4caSwyllys char *keytype = PK_DEFAULT_KEYTYPE;
38999ebb4caSwyllys KMF_HANDLE_T kmfhandle = NULL;
39099ebb4caSwyllys KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1;
39199ebb4caSwyllys KMF_KEY_ALG keyAlg = KMF_RSA;
3924165f465SWyllys Ingersoll KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_SHA1WithRSA;
39399ebb4caSwyllys boolean_t interactive = B_FALSE;
39499ebb4caSwyllys char *subname = NULL;
39599ebb4caSwyllys KMF_CREDENTIAL tokencred = { NULL, 0 };
39699ebb4caSwyllys KMF_GENERALNAMECHOICES alttype = 0;
39799ebb4caSwyllys int altcrit = 0, kucrit = 0;
398d00756ccSwyllys EKU_LIST *ekulist = NULL;
399e65e5c2dSWyllys Ingersoll KMF_OID *curveoid = NULL; /* ECC */
400e65e5c2dSWyllys Ingersoll KMF_OID *hashoid = NULL;
401e65e5c2dSWyllys Ingersoll int y_flag = 0;
40299ebb4caSwyllys
40399ebb4caSwyllys while ((opt = getopt_av(argc, argv,
40499ebb4caSwyllys "ik:(keystore)s:(subject)n:(nickname)A:(altname)"
40599ebb4caSwyllys "u:(keyusage)T:(token)d:(dir)p:(prefix)t:(keytype)"
406e65e5c2dSWyllys Ingersoll "y:(keylen)l:(label)c:(outcsr)e:(eku)C:(curve)"
407e65e5c2dSWyllys Ingersoll "K:(outkey)F:(format)E(listcurves)h:(hash)")) != EOF) {
40899ebb4caSwyllys
40999ebb4caSwyllys switch (opt) {
41099ebb4caSwyllys case 'A':
41199ebb4caSwyllys altname = optarg_av;
41299ebb4caSwyllys break;
41399ebb4caSwyllys case 'i':
414592106a2SWyllys Ingersoll if (interactive)
41599ebb4caSwyllys return (PK_ERR_USAGE);
416592106a2SWyllys Ingersoll else if (subject) {
417592106a2SWyllys Ingersoll cryptoerror(LOG_STDERR,
418592106a2SWyllys Ingersoll gettext("Interactive (-i) and "
419592106a2SWyllys Ingersoll "subject options are mutually "
420592106a2SWyllys Ingersoll "exclusive.\n"));
421592106a2SWyllys Ingersoll return (PK_ERR_USAGE);
422592106a2SWyllys Ingersoll } else
42399ebb4caSwyllys interactive = B_TRUE;
42499ebb4caSwyllys break;
42599ebb4caSwyllys case 'k':
42699ebb4caSwyllys kstype = KS2Int(optarg_av);
42799ebb4caSwyllys if (kstype == 0)
42899ebb4caSwyllys return (PK_ERR_USAGE);
42999ebb4caSwyllys break;
43099ebb4caSwyllys case 's':
431592106a2SWyllys Ingersoll if (subject)
43299ebb4caSwyllys return (PK_ERR_USAGE);
433592106a2SWyllys Ingersoll else if (interactive) {
434592106a2SWyllys Ingersoll cryptoerror(LOG_STDERR,
435592106a2SWyllys Ingersoll gettext("Interactive (-i) and "
436592106a2SWyllys Ingersoll "subject options are mutually "
437592106a2SWyllys Ingersoll "exclusive.\n"));
438592106a2SWyllys Ingersoll return (PK_ERR_USAGE);
439592106a2SWyllys Ingersoll } else
44099ebb4caSwyllys subject = optarg_av;
44199ebb4caSwyllys break;
44299ebb4caSwyllys case 'l':
44399ebb4caSwyllys case 'n':
44499ebb4caSwyllys if (certlabel)
44599ebb4caSwyllys return (PK_ERR_USAGE);
44699ebb4caSwyllys certlabel = optarg_av;
44799ebb4caSwyllys break;
44899ebb4caSwyllys case 'T':
44999ebb4caSwyllys if (tokenname)
45099ebb4caSwyllys return (PK_ERR_USAGE);
45199ebb4caSwyllys tokenname = optarg_av;
45299ebb4caSwyllys break;
45399ebb4caSwyllys case 'd':
45499ebb4caSwyllys dir = optarg_av;
45599ebb4caSwyllys break;
45699ebb4caSwyllys case 'p':
45799ebb4caSwyllys if (prefix)
45899ebb4caSwyllys return (PK_ERR_USAGE);
45999ebb4caSwyllys prefix = optarg_av;
46099ebb4caSwyllys break;
46199ebb4caSwyllys case 't':
46299ebb4caSwyllys keytype = optarg_av;
46399ebb4caSwyllys break;
46499ebb4caSwyllys case 'u':
46599ebb4caSwyllys kustr = optarg_av;
46699ebb4caSwyllys break;
46799ebb4caSwyllys case 'y':
46899ebb4caSwyllys if (sscanf(optarg_av, "%d",
46999ebb4caSwyllys &keylen) != 1) {
47099ebb4caSwyllys cryptoerror(LOG_STDERR,
47199ebb4caSwyllys gettext("Unrecognized "
47230a5e8faSwyllys "key length (%s)\n"), optarg_av);
47399ebb4caSwyllys return (PK_ERR_USAGE);
47499ebb4caSwyllys }
475e65e5c2dSWyllys Ingersoll y_flag++;
47699ebb4caSwyllys break;
47799ebb4caSwyllys case 'c':
47899ebb4caSwyllys if (outcsr)
47999ebb4caSwyllys return (PK_ERR_USAGE);
48099ebb4caSwyllys outcsr = optarg_av;
48199ebb4caSwyllys break;
48299ebb4caSwyllys case 'K':
48399ebb4caSwyllys if (outkey)
48499ebb4caSwyllys return (PK_ERR_USAGE);
48599ebb4caSwyllys outkey = optarg_av;
48699ebb4caSwyllys break;
48799ebb4caSwyllys case 'F':
48899ebb4caSwyllys if (format)
48999ebb4caSwyllys return (PK_ERR_USAGE);
49099ebb4caSwyllys format = optarg_av;
49199ebb4caSwyllys break;
492d00756ccSwyllys case 'e':
493d00756ccSwyllys ekustr = optarg_av;
494d00756ccSwyllys break;
495e65e5c2dSWyllys Ingersoll case 'C':
496e65e5c2dSWyllys Ingersoll curveoid = ecc_name_to_oid(optarg_av);
497e65e5c2dSWyllys Ingersoll if (curveoid == NULL) {
498e65e5c2dSWyllys Ingersoll cryptoerror(LOG_STDERR,
499e65e5c2dSWyllys Ingersoll gettext("Unrecognized ECC "
500e65e5c2dSWyllys Ingersoll "curve.\n"));
501e65e5c2dSWyllys Ingersoll return (PK_ERR_USAGE);
502e65e5c2dSWyllys Ingersoll }
503e65e5c2dSWyllys Ingersoll break;
504e65e5c2dSWyllys Ingersoll case 'E':
505e65e5c2dSWyllys Ingersoll /*
506e65e5c2dSWyllys Ingersoll * This argument is only to be used
507e65e5c2dSWyllys Ingersoll * by itself, no other options should
508e65e5c2dSWyllys Ingersoll * be present.
509e65e5c2dSWyllys Ingersoll */
510e65e5c2dSWyllys Ingersoll if (argc != 2) {
511e65e5c2dSWyllys Ingersoll cryptoerror(LOG_STDERR,
512e65e5c2dSWyllys Ingersoll gettext("listcurves has no other "
513e65e5c2dSWyllys Ingersoll "options.\n"));
514e65e5c2dSWyllys Ingersoll return (PK_ERR_USAGE);
515e65e5c2dSWyllys Ingersoll }
516e65e5c2dSWyllys Ingersoll show_ecc_curves();
517e65e5c2dSWyllys Ingersoll return (0);
518e65e5c2dSWyllys Ingersoll case 'h':
519e65e5c2dSWyllys Ingersoll hashname = optarg_av;
520e65e5c2dSWyllys Ingersoll hashoid = ecc_name_to_oid(optarg_av);
521e65e5c2dSWyllys Ingersoll if (hashoid == NULL) {
522e65e5c2dSWyllys Ingersoll cryptoerror(LOG_STDERR,
523e65e5c2dSWyllys Ingersoll gettext("Unrecognized hash.\n"));
524e65e5c2dSWyllys Ingersoll return (PK_ERR_USAGE);
525e65e5c2dSWyllys Ingersoll }
526e65e5c2dSWyllys Ingersoll break;
52799ebb4caSwyllys default:
52899ebb4caSwyllys cryptoerror(LOG_STDERR, gettext(
52999ebb4caSwyllys "unrecognized gencsr option '%s'\n"),
53099ebb4caSwyllys argv[optind_av]);
53199ebb4caSwyllys return (PK_ERR_USAGE);
53299ebb4caSwyllys }
53399ebb4caSwyllys }
53499ebb4caSwyllys /* No additional args allowed. */
53599ebb4caSwyllys argc -= optind_av;
53699ebb4caSwyllys argv += optind_av;
53799ebb4caSwyllys if (argc) {
53899ebb4caSwyllys return (PK_ERR_USAGE);
53999ebb4caSwyllys }
54099ebb4caSwyllys
54199ebb4caSwyllys /* Assume keystore = PKCS#11 if not specified. */
54299ebb4caSwyllys if (kstype == 0)
54399ebb4caSwyllys kstype = KMF_KEYSTORE_PK11TOKEN;
54499ebb4caSwyllys
545577f4726Swyllys DIR_OPTION_CHECK(kstype, dir);
546577f4726Swyllys
5472cbed729Swyllys if (EMPTYSTRING(outcsr) && interactive) {
5482cbed729Swyllys (void) get_filename("CSR", &outcsr);
5492cbed729Swyllys }
55099ebb4caSwyllys if (EMPTYSTRING(outcsr)) {
55199ebb4caSwyllys (void) printf(gettext("A filename must be specified to hold"
55299ebb4caSwyllys "the final certificate request data.\n"));
55399ebb4caSwyllys return (PK_ERR_USAGE);
5542cbed729Swyllys }
55599ebb4caSwyllys /*
55699ebb4caSwyllys * verify that the outcsr file does not already exist
55799ebb4caSwyllys * and that it can be created.
55899ebb4caSwyllys */
55999ebb4caSwyllys rv = verify_file(outcsr);
5602c9a247fSWyllys Ingersoll if (rv == KMF_ERR_OPEN_FILE) {
5612c9a247fSWyllys Ingersoll cryptoerror(LOG_STDERR,
5622c9a247fSWyllys Ingersoll gettext("Warning: file \"%s\" exists, "
5632c9a247fSWyllys Ingersoll "will be overwritten."), outcsr);
5642c9a247fSWyllys Ingersoll if (yesno(gettext("Continue with gencsr? "),
5652c9a247fSWyllys Ingersoll gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) {
5662c9a247fSWyllys Ingersoll return (0);
5672c9a247fSWyllys Ingersoll } else {
5682c9a247fSWyllys Ingersoll /* remove the file */
5692c9a247fSWyllys Ingersoll (void) unlink(outcsr);
5702c9a247fSWyllys Ingersoll }
5712c9a247fSWyllys Ingersoll } else if (rv != KMF_OK) {
5722c9a247fSWyllys Ingersoll cryptoerror(LOG_STDERR,
5732c9a247fSWyllys Ingersoll gettext("Warning: error accessing \"%s\""), outcsr);
5742c9a247fSWyllys Ingersoll return (rv);
57599ebb4caSwyllys }
57699ebb4caSwyllys
5772cbed729Swyllys if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN)) {
5782cbed729Swyllys if (EMPTYSTRING(certlabel) && interactive)
5792cbed729Swyllys (void) get_certlabel(&certlabel);
5802cbed729Swyllys
5812cbed729Swyllys if (EMPTYSTRING(certlabel)) {
5822cbed729Swyllys cryptoerror(LOG_STDERR, gettext("A label must be "
58399ebb4caSwyllys "specified to create a certificate request.\n"));
58499ebb4caSwyllys return (PK_ERR_USAGE);
58599ebb4caSwyllys }
5862cbed729Swyllys } else if (kstype == KMF_KEYSTORE_OPENSSL) {
5872cbed729Swyllys if (EMPTYSTRING(outkey) && interactive)
5882cbed729Swyllys (void) get_filename("private key", &outkey);
5892cbed729Swyllys
5902cbed729Swyllys if (EMPTYSTRING(outkey)) {
5912cbed729Swyllys cryptoerror(LOG_STDERR, gettext("A key filename "
5922cbed729Swyllys "must be specified to create a certificate "
5932cbed729Swyllys "request.\n"));
5942cbed729Swyllys return (PK_ERR_USAGE);
5952cbed729Swyllys }
5962cbed729Swyllys }
59799ebb4caSwyllys
59899ebb4caSwyllys if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) {
59999ebb4caSwyllys cryptoerror(LOG_STDERR,
60030a5e8faSwyllys gettext("Error parsing format string (%s).\n"), format);
60199ebb4caSwyllys return (PK_ERR_USAGE);
60299ebb4caSwyllys }
60399ebb4caSwyllys if (format && fmt != KMF_FORMAT_ASN1 && fmt != KMF_FORMAT_PEM) {
60499ebb4caSwyllys cryptoerror(LOG_STDERR,
60599ebb4caSwyllys gettext("CSR must be DER or PEM format.\n"));
60699ebb4caSwyllys return (PK_ERR_USAGE);
60799ebb4caSwyllys }
60899ebb4caSwyllys
60999ebb4caSwyllys /*
61099ebb4caSwyllys * Check the subject name.
61199ebb4caSwyllys * If interactive is true, get it now interactively.
61299ebb4caSwyllys */
61399ebb4caSwyllys if (interactive) {
61499ebb4caSwyllys if (get_subname(&subname) != KMF_OK) {
61599ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("Failed to get the "
61699ebb4caSwyllys "subject name interactively.\n"));
61799ebb4caSwyllys return (PK_ERR_USAGE);
61899ebb4caSwyllys }
61999ebb4caSwyllys } else {
62099ebb4caSwyllys if (EMPTYSTRING(subject)) {
62199ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("A subject name or "
62299ebb4caSwyllys "-i must be specified to create a certificate "
62399ebb4caSwyllys "request.\n"));
62499ebb4caSwyllys return (PK_ERR_USAGE);
62599ebb4caSwyllys } else {
62699ebb4caSwyllys subname = strdup(subject);
62799ebb4caSwyllys if (subname == NULL) {
62899ebb4caSwyllys cryptoerror(LOG_STDERR,
62999ebb4caSwyllys gettext("Out of memory.\n"));
63099ebb4caSwyllys return (PK_ERR_SYSTEM);
63199ebb4caSwyllys }
63299ebb4caSwyllys }
63399ebb4caSwyllys }
63499ebb4caSwyllys if (altname != NULL) {
63599ebb4caSwyllys rv = verify_altname(altname, &alttype, &altcrit);
63699ebb4caSwyllys if (rv != KMF_OK) {
63799ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("Subject AltName "
63899ebb4caSwyllys "must be specified as a name=value pair. "
63999ebb4caSwyllys "See the man page for details."));
64099ebb4caSwyllys goto end;
64199ebb4caSwyllys } else {
64299ebb4caSwyllys /* advance the altname past the '=' sign */
64399ebb4caSwyllys char *p = strchr(altname, '=');
64499ebb4caSwyllys if (p != NULL)
64599ebb4caSwyllys altname = p + 1;
64699ebb4caSwyllys }
64799ebb4caSwyllys }
64899ebb4caSwyllys
64999ebb4caSwyllys if (kustr != NULL) {
65099ebb4caSwyllys rv = verify_keyusage(kustr, &kubits, &kucrit);
65199ebb4caSwyllys if (rv != KMF_OK) {
65299ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("KeyUsage "
65399ebb4caSwyllys "must be specified as a comma-separated list. "
65499ebb4caSwyllys "See the man page for details."));
65599ebb4caSwyllys goto end;
65699ebb4caSwyllys }
65799ebb4caSwyllys }
658d00756ccSwyllys if (ekustr != NULL) {
659d00756ccSwyllys rv = verify_ekunames(ekustr, &ekulist);
660d00756ccSwyllys if (rv != KMF_OK) {
661d00756ccSwyllys (void) fprintf(stderr, gettext("EKUs must "
662d00756ccSwyllys "be specified as a comma-separated list. "
663d00756ccSwyllys "See the man page for details.\n"));
664d00756ccSwyllys rv = PK_ERR_USAGE;
665d00756ccSwyllys goto end;
666d00756ccSwyllys }
667d00756ccSwyllys }
668e65e5c2dSWyllys Ingersoll if ((rv = Str2KeyType(keytype, hashoid, &keyAlg, &sigAlg)) != 0) {
669e65e5c2dSWyllys Ingersoll cryptoerror(LOG_STDERR,
670e65e5c2dSWyllys Ingersoll gettext("Unsupported key/hash combination (%s/%s).\n"),
671e65e5c2dSWyllys Ingersoll keytype, (hashname ? hashname : "none"));
67299ebb4caSwyllys goto end;
67399ebb4caSwyllys }
674e65e5c2dSWyllys Ingersoll if (curveoid != NULL && keyAlg != KMF_ECDSA) {
675e65e5c2dSWyllys Ingersoll cryptoerror(LOG_STDERR, gettext("EC curves are only "
676e65e5c2dSWyllys Ingersoll "valid for EC keytypes.\n"));
677e65e5c2dSWyllys Ingersoll return (PK_ERR_USAGE);
678e65e5c2dSWyllys Ingersoll }
679e65e5c2dSWyllys Ingersoll if (keyAlg == KMF_ECDSA && curveoid == NULL) {
680e65e5c2dSWyllys Ingersoll cryptoerror(LOG_STDERR, gettext("A curve must be "
681e65e5c2dSWyllys Ingersoll "specifed when using EC keys.\n"));
682e65e5c2dSWyllys Ingersoll return (PK_ERR_USAGE);
683e65e5c2dSWyllys Ingersoll }
684e65e5c2dSWyllys Ingersoll if (keyAlg == KMF_ECDSA && kstype == KMF_KEYSTORE_OPENSSL) {
685e65e5c2dSWyllys Ingersoll (void) fprintf(stderr, gettext("ECC certificates are"
686e65e5c2dSWyllys Ingersoll "only supported with the pkcs11 and nss keystores\n"));
687e65e5c2dSWyllys Ingersoll rv = PK_ERR_USAGE;
688e65e5c2dSWyllys Ingersoll goto end;
689e65e5c2dSWyllys Ingersoll }
690e65e5c2dSWyllys Ingersoll
691e65e5c2dSWyllys Ingersoll /* Adjust default keylength for NSS and DSA */
692e65e5c2dSWyllys Ingersoll if (keyAlg == KMF_DSA && !y_flag && kstype == KMF_KEYSTORE_NSS)
693e65e5c2dSWyllys Ingersoll keylen = 1024;
69499ebb4caSwyllys
69599ebb4caSwyllys if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) {
69699ebb4caSwyllys if (tokenname == NULL || !strlen(tokenname)) {
69799ebb4caSwyllys if (kstype == KMF_KEYSTORE_NSS) {
69899ebb4caSwyllys tokenname = "internal";
69999ebb4caSwyllys } else {
70099ebb4caSwyllys tokenname = PK_DEFAULT_PK11TOKEN;
70199ebb4caSwyllys }
70299ebb4caSwyllys }
70399ebb4caSwyllys
70499ebb4caSwyllys (void) get_token_password(kstype, tokenname, &tokencred);
70599ebb4caSwyllys }
70699ebb4caSwyllys
707577f4726Swyllys if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
708577f4726Swyllys cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n"));
709577f4726Swyllys return (PK_ERR_USAGE);
710577f4726Swyllys }
711577f4726Swyllys
712577f4726Swyllys
71399ebb4caSwyllys if (kstype == KMF_KEYSTORE_NSS) {
71499ebb4caSwyllys if (dir == NULL)
71599ebb4caSwyllys dir = PK_DEFAULT_DIRECTORY;
71699ebb4caSwyllys
71799ebb4caSwyllys rv = gencsr_nss(kmfhandle,
71899ebb4caSwyllys tokenname, subname, altname, alttype, altcrit,
71999ebb4caSwyllys certlabel, dir, prefix,
72099ebb4caSwyllys keyAlg, keylen, kubits, kucrit,
721e65e5c2dSWyllys Ingersoll fmt, outcsr, &tokencred, ekulist,
722e65e5c2dSWyllys Ingersoll sigAlg, curveoid);
72399ebb4caSwyllys
72499ebb4caSwyllys } else if (kstype == KMF_KEYSTORE_PK11TOKEN) {
72599ebb4caSwyllys rv = gencsr_pkcs11(kmfhandle,
72699ebb4caSwyllys tokenname, subname, altname, alttype, altcrit,
72799ebb4caSwyllys certlabel, keyAlg, keylen,
728e65e5c2dSWyllys Ingersoll kubits, kucrit, fmt, outcsr, &tokencred,
729e65e5c2dSWyllys Ingersoll ekulist, sigAlg, curveoid);
73099ebb4caSwyllys
73199ebb4caSwyllys } else if (kstype == KMF_KEYSTORE_OPENSSL) {
73299ebb4caSwyllys rv = gencsr_file(kmfhandle,
73399ebb4caSwyllys keyAlg, keylen, fmt, subname, altname,
73499ebb4caSwyllys alttype, altcrit, kubits, kucrit,
735e65e5c2dSWyllys Ingersoll outcsr, outkey, ekulist, sigAlg);
73699ebb4caSwyllys }
73799ebb4caSwyllys
73899ebb4caSwyllys end:
739592106a2SWyllys Ingersoll if (rv != KMF_OK) {
74099ebb4caSwyllys display_error(kmfhandle, rv,
74199ebb4caSwyllys gettext("Error creating CSR or keypair"));
74299ebb4caSwyllys
743592106a2SWyllys Ingersoll if (rv == KMF_ERR_RDN_PARSER) {
744592106a2SWyllys Ingersoll cryptoerror(LOG_STDERR, gettext("subject or "
745592106a2SWyllys Ingersoll "issuer name must be in proper DN format.\n"));
746592106a2SWyllys Ingersoll }
747592106a2SWyllys Ingersoll }
748592106a2SWyllys Ingersoll
749d00756ccSwyllys if (ekulist != NULL)
750d00756ccSwyllys free_eku_list(ekulist);
751d00756ccSwyllys
75299ebb4caSwyllys if (subname)
75399ebb4caSwyllys free(subname);
75499ebb4caSwyllys
75599ebb4caSwyllys if (tokencred.cred != NULL)
75699ebb4caSwyllys free(tokencred.cred);
75799ebb4caSwyllys
75830a5e8faSwyllys (void) kmf_finalize(kmfhandle);
75999ebb4caSwyllys if (rv != KMF_OK)
76099ebb4caSwyllys return (PK_ERR_USAGE);
76199ebb4caSwyllys
76299ebb4caSwyllys return (0);
76399ebb4caSwyllys }
764