xref: /titanic_44/usr/src/cmd/cmd-crypto/pktool/gencsr.c (revision 448b8615fe9e8af757530284920a235430ead7e8)
199ebb4caSwyllys /*
299ebb4caSwyllys  * CDDL HEADER START
399ebb4caSwyllys  *
499ebb4caSwyllys  * The contents of this file are subject to the terms of the
599ebb4caSwyllys  * Common Development and Distribution License (the "License").
699ebb4caSwyllys  * You may not use this file except in compliance with the License.
799ebb4caSwyllys  *
899ebb4caSwyllys  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
999ebb4caSwyllys  * or http://www.opensolaris.org/os/licensing.
1099ebb4caSwyllys  * See the License for the specific language governing permissions
1199ebb4caSwyllys  * and limitations under the License.
1299ebb4caSwyllys  *
1399ebb4caSwyllys  * When distributing Covered Code, include this CDDL HEADER in each
1499ebb4caSwyllys  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1599ebb4caSwyllys  * If applicable, add the following below this CDDL HEADER, with the
1699ebb4caSwyllys  * fields enclosed by brackets "[]" replaced with your own identifying
1799ebb4caSwyllys  * information: Portions Copyright [yyyy] [name of copyright owner]
1899ebb4caSwyllys  *
1999ebb4caSwyllys  * CDDL HEADER END
2099ebb4caSwyllys  *
2199ebb4caSwyllys  *
22d00756ccSwyllys  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
2399ebb4caSwyllys  * Use is subject to license terms.
2499ebb4caSwyllys  */
2599ebb4caSwyllys 
2699ebb4caSwyllys #pragma ident	"%Z%%M%	%I%	%E% SMI"
2799ebb4caSwyllys 
2899ebb4caSwyllys #include <stdio.h>
2999ebb4caSwyllys #include <string.h>
3099ebb4caSwyllys #include <ctype.h>
3199ebb4caSwyllys #include <malloc.h>
3299ebb4caSwyllys #include <libgen.h>
3399ebb4caSwyllys #include <errno.h>
3499ebb4caSwyllys #include <cryptoutil.h>
3599ebb4caSwyllys #include <security/cryptoki.h>
3699ebb4caSwyllys #include "common.h"
3799ebb4caSwyllys 
3899ebb4caSwyllys #include <kmfapi.h>
3999ebb4caSwyllys 
4099ebb4caSwyllys #define	SET_VALUE(f, s) \
4199ebb4caSwyllys 	kmfrv = f; \
4299ebb4caSwyllys 	if (kmfrv != KMF_OK) { \
4399ebb4caSwyllys 		cryptoerror(LOG_STDERR, \
4499ebb4caSwyllys 			gettext("Failed to %s: 0x%02\n"), \
4599ebb4caSwyllys 			s, kmfrv); \
4699ebb4caSwyllys 		goto cleanup; \
4799ebb4caSwyllys 	}
4899ebb4caSwyllys 
4999ebb4caSwyllys static KMF_RETURN
5099ebb4caSwyllys gencsr_pkcs11(KMF_HANDLE_T kmfhandle,
5199ebb4caSwyllys 	char *token, char *subject, char *altname,
5299ebb4caSwyllys 	KMF_GENERALNAMECHOICES alttype, int altcrit,
5399ebb4caSwyllys 	char *certlabel, KMF_KEY_ALG keyAlg,
54d00756ccSwyllys 	int keylen, uint16_t kubits, int kucrit,
5599ebb4caSwyllys 	KMF_ENCODE_FORMAT fmt, char *csrfile,
56d00756ccSwyllys 	KMF_CREDENTIAL *tokencred, EKU_LIST *ekulist)
5799ebb4caSwyllys {
5899ebb4caSwyllys 	KMF_RETURN kmfrv = KMF_OK;
5999ebb4caSwyllys 	KMF_KEY_HANDLE pubk, prik;
6099ebb4caSwyllys 	KMF_X509_NAME	csrSubject;
6199ebb4caSwyllys 	KMF_CSR_DATA	csr;
6299ebb4caSwyllys 	KMF_ALGORITHM_INDEX sigAlg;
6399ebb4caSwyllys 	KMF_DATA signedCsr = {NULL, 0};
6499ebb4caSwyllys 
6530a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
6630a5e8faSwyllys 	int numattr = 0;
6730a5e8faSwyllys 	KMF_ATTRIBUTE attrlist[16];
6830a5e8faSwyllys 	boolean_t storekey = TRUE;
6930a5e8faSwyllys 
7099ebb4caSwyllys 	(void) memset(&csr, 0, sizeof (csr));
7199ebb4caSwyllys 	(void) memset(&csrSubject, 0, sizeof (csrSubject));
7299ebb4caSwyllys 
7399ebb4caSwyllys 	if (keyAlg == KMF_DSA)
7499ebb4caSwyllys 		sigAlg = KMF_ALGID_SHA1WithDSA;
7599ebb4caSwyllys 	else
7699ebb4caSwyllys 		sigAlg = KMF_ALGID_MD5WithRSA;
7799ebb4caSwyllys 
7899ebb4caSwyllys 
7999ebb4caSwyllys 	/* If the subject name cannot be parsed, flag it now and exit */
8030a5e8faSwyllys 	if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) {
8199ebb4caSwyllys 		return (kmfrv);
8299ebb4caSwyllys 	}
8399ebb4caSwyllys 
8499ebb4caSwyllys 	/* Select a PKCS11 token */
8599ebb4caSwyllys 	kmfrv = select_token(kmfhandle, token, FALSE);
8699ebb4caSwyllys 	if (kmfrv != KMF_OK) {
8799ebb4caSwyllys 		return (kmfrv);
8899ebb4caSwyllys 	}
8999ebb4caSwyllys 
9030a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
9130a5e8faSwyllys 	    &kstype, sizeof (kstype));
9230a5e8faSwyllys 	numattr++;
9330a5e8faSwyllys 
9430a5e8faSwyllys 	if (certlabel != NULL && strlen(certlabel)) {
9530a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR,
9630a5e8faSwyllys 		    certlabel, strlen(certlabel));
9730a5e8faSwyllys 		numattr++;
9830a5e8faSwyllys 	}
9930a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLENGTH_ATTR,
10030a5e8faSwyllys 	    &keylen, sizeof (keylen));
10130a5e8faSwyllys 	numattr++;
10230a5e8faSwyllys 
10330a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYALG_ATTR,
10430a5e8faSwyllys 	    &keyAlg, sizeof (keyAlg));
10530a5e8faSwyllys 	numattr++;
10630a5e8faSwyllys 
10730a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
10830a5e8faSwyllys 	    tokencred, sizeof (KMF_CREDENTIAL));
10930a5e8faSwyllys 	numattr++;
11030a5e8faSwyllys 
11130a5e8faSwyllys 	if (token && strlen(token)) {
11230a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
11330a5e8faSwyllys 		    token, strlen(token));
11430a5e8faSwyllys 		numattr++;
11530a5e8faSwyllys 	}
11630a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR,
11730a5e8faSwyllys 	    &pubk, sizeof (KMF_KEY_HANDLE));
11830a5e8faSwyllys 	numattr++;
11930a5e8faSwyllys 
12030a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVKEY_HANDLE_ATTR,
12130a5e8faSwyllys 	    &prik, sizeof (KMF_KEY_HANDLE));
12230a5e8faSwyllys 	numattr++;
12330a5e8faSwyllys 
12430a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_STOREKEY_BOOL_ATTR,
12530a5e8faSwyllys 	    &storekey, sizeof (storekey));
12630a5e8faSwyllys 	numattr++;
12730a5e8faSwyllys 
12830a5e8faSwyllys 	kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist);
12999ebb4caSwyllys 	if (kmfrv != KMF_OK) {
13099ebb4caSwyllys 		return (kmfrv);
13199ebb4caSwyllys 	}
13299ebb4caSwyllys 
13330a5e8faSwyllys 	SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr), "keypair");
13499ebb4caSwyllys 
13530a5e8faSwyllys 	SET_VALUE(kmf_set_csr_version(&csr, 2), "version number");
13699ebb4caSwyllys 
13730a5e8faSwyllys 	SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject), "subject name");
13899ebb4caSwyllys 
13930a5e8faSwyllys 	SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg),
14099ebb4caSwyllys 	    "SignatureAlgorithm");
14199ebb4caSwyllys 
14299ebb4caSwyllys 	if (altname != NULL) {
14330a5e8faSwyllys 		SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit,
14499ebb4caSwyllys 		    alttype), "SetCSRSubjectAltName");
14599ebb4caSwyllys 	}
14699ebb4caSwyllys 
14799ebb4caSwyllys 	if (kubits != 0) {
14830a5e8faSwyllys 		SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits),
14999ebb4caSwyllys 		    "SetCSRKeyUsage");
15099ebb4caSwyllys 	}
151d00756ccSwyllys 	if (ekulist != NULL) {
152d00756ccSwyllys 		int i;
153d00756ccSwyllys 		for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
154d00756ccSwyllys 			SET_VALUE(kmf_add_csr_eku(&csr,
155d00756ccSwyllys 			    &ekulist->ekulist[i],
156d00756ccSwyllys 			    ekulist->critlist[i]),
157d00756ccSwyllys 			    "Extended Key Usage");
158d00756ccSwyllys 		}
159d00756ccSwyllys 	}
16030a5e8faSwyllys 	if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) ==
16199ebb4caSwyllys 	    KMF_OK) {
16230a5e8faSwyllys 		kmfrv = kmf_create_csr_file(&signedCsr, fmt, csrfile);
16399ebb4caSwyllys 	}
16499ebb4caSwyllys 
16599ebb4caSwyllys cleanup:
16630a5e8faSwyllys 	(void) kmf_free_data(&signedCsr);
16730a5e8faSwyllys 	(void) kmf_free_kmf_key(kmfhandle, &prik);
16899ebb4caSwyllys 	/* delete the key */
16930a5e8faSwyllys 	numattr = 0;
17030a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
17130a5e8faSwyllys 	    &kstype, sizeof (kstype));
17230a5e8faSwyllys 	numattr++;
17330a5e8faSwyllys 
17430a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR,
17530a5e8faSwyllys 	    &pubk, sizeof (KMF_KEY_HANDLE));
17630a5e8faSwyllys 	numattr++;
17730a5e8faSwyllys 
17830a5e8faSwyllys 	(void) kmf_delete_key_from_keystore(kmfhandle, numattr, attrlist);
17930a5e8faSwyllys 
18030a5e8faSwyllys 	(void) kmf_free_signed_csr(&csr);
18199ebb4caSwyllys 
18299ebb4caSwyllys 	return (kmfrv);
18399ebb4caSwyllys }
18499ebb4caSwyllys 
18599ebb4caSwyllys static KMF_RETURN
18699ebb4caSwyllys gencsr_file(KMF_HANDLE_T kmfhandle,
18799ebb4caSwyllys 	KMF_KEY_ALG keyAlg,
18899ebb4caSwyllys 	int keylen, KMF_ENCODE_FORMAT fmt,
18999ebb4caSwyllys 	char *subject, char *altname, KMF_GENERALNAMECHOICES alttype,
19099ebb4caSwyllys 	int altcrit, uint16_t kubits, int kucrit,
191*448b8615Swyllys 	char *outcsr, char *outkey, EKU_LIST *ekulist)
19299ebb4caSwyllys {
19399ebb4caSwyllys 	KMF_RETURN kmfrv;
19499ebb4caSwyllys 	KMF_KEY_HANDLE pubk, prik;
19599ebb4caSwyllys 	KMF_X509_NAME	csrSubject;
19699ebb4caSwyllys 	KMF_CSR_DATA	csr;
19799ebb4caSwyllys 	KMF_ALGORITHM_INDEX sigAlg;
19899ebb4caSwyllys 	KMF_DATA signedCsr = {NULL, 0};
19999ebb4caSwyllys 	char *fullcsrpath = NULL;
20099ebb4caSwyllys 	char *fullkeypath = NULL;
20199ebb4caSwyllys 
20230a5e8faSwyllys 	int numattr = 0;
20330a5e8faSwyllys 	KMF_ATTRIBUTE attrlist[16];
20430a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
20530a5e8faSwyllys 	boolean_t	storekey = TRUE;
20630a5e8faSwyllys 
20799ebb4caSwyllys 	(void) memset(&csr, 0, sizeof (csr));
20899ebb4caSwyllys 	(void) memset(&csrSubject, 0, sizeof (csrSubject));
20999ebb4caSwyllys 
21099ebb4caSwyllys 	if (EMPTYSTRING(outcsr) || EMPTYSTRING(outkey)) {
21199ebb4caSwyllys 		cryptoerror(LOG_STDERR,
21299ebb4caSwyllys 		    gettext("No output file was specified for "
21399ebb4caSwyllys 		    "the csr or key\n"));
21499ebb4caSwyllys 		return (KMF_ERR_BAD_PARAMETER);
21599ebb4caSwyllys 	}
21699ebb4caSwyllys 	fullcsrpath = strdup(outcsr);
21799ebb4caSwyllys 	if (verify_file(fullcsrpath)) {
21899ebb4caSwyllys 		cryptoerror(LOG_STDERR,
21999ebb4caSwyllys 		    gettext("Cannot write the indicated output "
22099ebb4caSwyllys 		    "certificate file (%s).\n"), fullcsrpath);
22199ebb4caSwyllys 		free(fullcsrpath);
22299ebb4caSwyllys 		return (PK_ERR_USAGE);
22399ebb4caSwyllys 	}
224*448b8615Swyllys 
22599ebb4caSwyllys 	fullkeypath = strdup(outkey);
22699ebb4caSwyllys 	if (verify_file(fullcsrpath)) {
22799ebb4caSwyllys 		cryptoerror(LOG_STDERR,
22899ebb4caSwyllys 		    gettext("Cannot write the indicated output "
22999ebb4caSwyllys 		    "key file (%s).\n"), fullkeypath);
23099ebb4caSwyllys 		free(fullcsrpath);
23199ebb4caSwyllys 		return (PK_ERR_USAGE);
23299ebb4caSwyllys 	}
23399ebb4caSwyllys 
23499ebb4caSwyllys 	if (keyAlg == KMF_DSA)
23599ebb4caSwyllys 		sigAlg = KMF_ALGID_SHA1WithDSA;
23699ebb4caSwyllys 	else
23799ebb4caSwyllys 		sigAlg = KMF_ALGID_MD5WithRSA;
23899ebb4caSwyllys 
23999ebb4caSwyllys 	/* If the subject name cannot be parsed, flag it now and exit */
24030a5e8faSwyllys 	if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) {
24199ebb4caSwyllys 		return (kmfrv);
24299ebb4caSwyllys 	}
24399ebb4caSwyllys 
24430a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
24530a5e8faSwyllys 	    &kstype, sizeof (kstype));
24630a5e8faSwyllys 	numattr++;
24799ebb4caSwyllys 
24830a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR,
24930a5e8faSwyllys 	    fullkeypath, strlen(fullkeypath));
25030a5e8faSwyllys 	numattr++;
25199ebb4caSwyllys 
25230a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLENGTH_ATTR,
25330a5e8faSwyllys 	    &keylen, sizeof (keylen));
25430a5e8faSwyllys 	numattr++;
25530a5e8faSwyllys 
25630a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYALG_ATTR,
25730a5e8faSwyllys 	    &keyAlg, sizeof (keyAlg));
25830a5e8faSwyllys 	numattr++;
25930a5e8faSwyllys 
26030a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR,
26130a5e8faSwyllys 	    &fmt, sizeof (fmt));
26230a5e8faSwyllys 	numattr++;
26330a5e8faSwyllys 
26430a5e8faSwyllys 	(void) memset(&prik, 0, sizeof (prik));
26530a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVKEY_HANDLE_ATTR,
26630a5e8faSwyllys 	    &prik, sizeof (KMF_KEY_HANDLE));
26730a5e8faSwyllys 	numattr++;
26830a5e8faSwyllys 
26930a5e8faSwyllys 	(void) memset(&pubk, 0, sizeof (pubk));
27030a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR,
27130a5e8faSwyllys 	    &pubk, sizeof (KMF_KEY_HANDLE));
27230a5e8faSwyllys 	numattr++;
27330a5e8faSwyllys 
27430a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_STOREKEY_BOOL_ATTR,
27530a5e8faSwyllys 	    &storekey, sizeof (storekey));
27630a5e8faSwyllys 	numattr++;
27730a5e8faSwyllys 
27830a5e8faSwyllys 	kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist);
27999ebb4caSwyllys 	if (kmfrv != KMF_OK) {
28099ebb4caSwyllys 		goto cleanup;
28199ebb4caSwyllys 	}
28230a5e8faSwyllys 	SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr),
28399ebb4caSwyllys 	    "SetCSRPubKey");
28499ebb4caSwyllys 
28530a5e8faSwyllys 	SET_VALUE(kmf_set_csr_version(&csr, 2), "SetCSRVersion");
28699ebb4caSwyllys 
28730a5e8faSwyllys 	SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject),
28830a5e8faSwyllys 	    "kmf_set_csr_subject");
28999ebb4caSwyllys 
29030a5e8faSwyllys 	SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg), "kmf_set_csr_sig_alg");
29199ebb4caSwyllys 
29299ebb4caSwyllys 	if (altname != NULL) {
29330a5e8faSwyllys 		SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit,
29430a5e8faSwyllys 		    alttype), "kmf_set_csr_subject_altname");
29599ebb4caSwyllys 	}
29699ebb4caSwyllys 	if (kubits != NULL) {
29730a5e8faSwyllys 		SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits),
29830a5e8faSwyllys 		    "kmf_set_csr_ku");
29999ebb4caSwyllys 	}
300d00756ccSwyllys 	if (ekulist != NULL) {
301d00756ccSwyllys 		int i;
302d00756ccSwyllys 		for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
303d00756ccSwyllys 			SET_VALUE(kmf_add_csr_eku(&csr,
304d00756ccSwyllys 			    &ekulist->ekulist[i],
305d00756ccSwyllys 			    ekulist->critlist[i]),
306d00756ccSwyllys 			    "Extended Key Usage");
307d00756ccSwyllys 		}
308d00756ccSwyllys 	}
30930a5e8faSwyllys 	if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) ==
31099ebb4caSwyllys 	    KMF_OK) {
31130a5e8faSwyllys 		kmfrv = kmf_create_csr_file(&signedCsr, fmt, fullcsrpath);
31299ebb4caSwyllys 	}
31399ebb4caSwyllys 
31499ebb4caSwyllys cleanup:
31599ebb4caSwyllys 	if (fullkeypath)
31699ebb4caSwyllys 		free(fullkeypath);
31799ebb4caSwyllys 	if (fullcsrpath)
31899ebb4caSwyllys 		free(fullcsrpath);
31999ebb4caSwyllys 
32030a5e8faSwyllys 	kmf_free_data(&signedCsr);
32130a5e8faSwyllys 	kmf_free_kmf_key(kmfhandle, &prik);
32230a5e8faSwyllys 	kmf_free_signed_csr(&csr);
32399ebb4caSwyllys 
32499ebb4caSwyllys 	return (kmfrv);
32599ebb4caSwyllys }
32699ebb4caSwyllys 
32799ebb4caSwyllys static KMF_RETURN
32899ebb4caSwyllys gencsr_nss(KMF_HANDLE_T kmfhandle,
32999ebb4caSwyllys 	char *token, char *subject, char *altname,
33099ebb4caSwyllys 	KMF_GENERALNAMECHOICES alttype, int altcrit,
33199ebb4caSwyllys 	char *nickname, char *dir, char *prefix,
33299ebb4caSwyllys 	KMF_KEY_ALG keyAlg, int keylen,
33399ebb4caSwyllys 	uint16_t kubits, int kucrit,
33499ebb4caSwyllys 	KMF_ENCODE_FORMAT fmt, char *csrfile,
335d00756ccSwyllys 	KMF_CREDENTIAL *tokencred, EKU_LIST *ekulist)
33699ebb4caSwyllys {
33799ebb4caSwyllys 	KMF_RETURN kmfrv;
33899ebb4caSwyllys 	KMF_KEY_HANDLE pubk, prik;
33999ebb4caSwyllys 	KMF_X509_NAME	csrSubject;
34099ebb4caSwyllys 	KMF_CSR_DATA	csr;
34199ebb4caSwyllys 	KMF_ALGORITHM_INDEX sigAlg;
34299ebb4caSwyllys 	KMF_DATA signedCsr = {NULL, 0};
34330a5e8faSwyllys 
34430a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
34530a5e8faSwyllys 	int numattr = 0;
34630a5e8faSwyllys 	KMF_ATTRIBUTE attrlist[16];
34730a5e8faSwyllys 	boolean_t storekey = TRUE;
34899ebb4caSwyllys 
34999ebb4caSwyllys 	if (token == NULL)
35099ebb4caSwyllys 		token = DEFAULT_NSS_TOKEN;
35199ebb4caSwyllys 
35299ebb4caSwyllys 	if (keyAlg == KMF_DSA)
35399ebb4caSwyllys 		sigAlg = KMF_ALGID_SHA1WithDSA;
35499ebb4caSwyllys 	else
35599ebb4caSwyllys 		sigAlg = KMF_ALGID_MD5WithRSA;
35699ebb4caSwyllys 
35799ebb4caSwyllys 	kmfrv = configure_nss(kmfhandle, dir, prefix);
35899ebb4caSwyllys 	if (kmfrv != KMF_OK)
35999ebb4caSwyllys 		return (kmfrv);
36099ebb4caSwyllys 
36199ebb4caSwyllys 	(void) memset(&csr, 0, sizeof (csr));
36299ebb4caSwyllys 	(void) memset(&csrSubject, 0, sizeof (csrSubject));
363*448b8615Swyllys 	(void) memset(&pubk, 0, sizeof (pubk));
364*448b8615Swyllys 	(void) memset(&prik, 0, sizeof (prik));
36599ebb4caSwyllys 
36699ebb4caSwyllys 	/* If the subject name cannot be parsed, flag it now and exit */
36730a5e8faSwyllys 	if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) {
36899ebb4caSwyllys 		return (kmfrv);
36999ebb4caSwyllys 	}
37099ebb4caSwyllys 
37130a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
37230a5e8faSwyllys 	    &kstype, sizeof (kstype));
37330a5e8faSwyllys 	numattr++;
37499ebb4caSwyllys 
37530a5e8faSwyllys 	if (nickname != NULL && strlen(nickname)) {
37630a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR,
37730a5e8faSwyllys 		    nickname, strlen(nickname));
37830a5e8faSwyllys 		numattr++;
37930a5e8faSwyllys 	}
38030a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLENGTH_ATTR,
38130a5e8faSwyllys 	    &keylen, sizeof (keylen));
38230a5e8faSwyllys 	numattr++;
38399ebb4caSwyllys 
38430a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYALG_ATTR,
38530a5e8faSwyllys 	    &keyAlg, sizeof (keyAlg));
38630a5e8faSwyllys 	numattr++;
38730a5e8faSwyllys 
38830a5e8faSwyllys 	if (tokencred != NULL && tokencred->credlen > 0) {
38930a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
39030a5e8faSwyllys 		    tokencred, sizeof (KMF_CREDENTIAL));
39130a5e8faSwyllys 		numattr++;
39230a5e8faSwyllys 	}
39330a5e8faSwyllys 
39430a5e8faSwyllys 	if (token && strlen(token)) {
39530a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
39630a5e8faSwyllys 		    token, strlen(token));
39730a5e8faSwyllys 		numattr++;
39830a5e8faSwyllys 	}
39930a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR,
40030a5e8faSwyllys 	    &pubk, sizeof (KMF_KEY_HANDLE));
40130a5e8faSwyllys 	numattr++;
40230a5e8faSwyllys 
40330a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVKEY_HANDLE_ATTR,
40430a5e8faSwyllys 	    &prik, sizeof (KMF_KEY_HANDLE));
40530a5e8faSwyllys 	numattr++;
40630a5e8faSwyllys 
40730a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_STOREKEY_BOOL_ATTR,
40830a5e8faSwyllys 	    &storekey, sizeof (storekey));
40930a5e8faSwyllys 	numattr++;
41030a5e8faSwyllys 
41130a5e8faSwyllys 	kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist);
41299ebb4caSwyllys 	if (kmfrv != KMF_OK) {
41399ebb4caSwyllys 		goto cleanup;
41499ebb4caSwyllys 	}
41599ebb4caSwyllys 
41630a5e8faSwyllys 	SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr),
41730a5e8faSwyllys 	    "kmf_set_csr_pubkey");
41830a5e8faSwyllys 	SET_VALUE(kmf_set_csr_version(&csr, 2), "kmf_set_csr_version");
41930a5e8faSwyllys 	SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject),
42030a5e8faSwyllys 	    "kmf_set_csr_subject");
42130a5e8faSwyllys 	SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg), "kmf_set_csr_sig_alg");
42299ebb4caSwyllys 
42399ebb4caSwyllys 	if (altname != NULL) {
42430a5e8faSwyllys 		SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit,
42530a5e8faSwyllys 		    alttype), "kmf_set_csr_subject_altname");
42699ebb4caSwyllys 	}
42799ebb4caSwyllys 	if (kubits != NULL) {
42830a5e8faSwyllys 		SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits),
42930a5e8faSwyllys 		    "kmf_set_csr_ku");
43099ebb4caSwyllys 	}
431d00756ccSwyllys 	if (ekulist != NULL) {
432d00756ccSwyllys 		int i;
433d00756ccSwyllys 		for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
434d00756ccSwyllys 			SET_VALUE(kmf_add_csr_eku(&csr,
435d00756ccSwyllys 			    &ekulist->ekulist[i],
436d00756ccSwyllys 			    ekulist->critlist[i]),
437d00756ccSwyllys 			    "Extended Key Usage");
438d00756ccSwyllys 		}
439d00756ccSwyllys 	}
44030a5e8faSwyllys 	if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) ==
44199ebb4caSwyllys 	    KMF_OK) {
44230a5e8faSwyllys 		kmfrv = kmf_create_csr_file(&signedCsr, fmt, csrfile);
44399ebb4caSwyllys 	}
44499ebb4caSwyllys 
44599ebb4caSwyllys cleanup:
44630a5e8faSwyllys 	(void) kmf_free_data(&signedCsr);
44730a5e8faSwyllys 	(void) kmf_free_kmf_key(kmfhandle, &prik);
44830a5e8faSwyllys 
44999ebb4caSwyllys 	/* delete the key */
45030a5e8faSwyllys 	numattr = 0;
45130a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
45230a5e8faSwyllys 	    &kstype, sizeof (kstype));
45330a5e8faSwyllys 	numattr++;
45430a5e8faSwyllys 
45530a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR,
45630a5e8faSwyllys 	    &pubk, sizeof (KMF_KEY_HANDLE));
45730a5e8faSwyllys 	numattr++;
45830a5e8faSwyllys 
45930a5e8faSwyllys 	if (tokencred != NULL && tokencred->credlen > 0) {
46030a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
46130a5e8faSwyllys 		    tokencred, sizeof (KMF_CREDENTIAL));
46230a5e8faSwyllys 		numattr++;
46330a5e8faSwyllys 	}
46430a5e8faSwyllys 
46530a5e8faSwyllys 	if (token && strlen(token)) {
46630a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
46730a5e8faSwyllys 		    token, strlen(token));
46830a5e8faSwyllys 		numattr++;
46930a5e8faSwyllys 	}
47030a5e8faSwyllys 
47130a5e8faSwyllys 	(void) kmf_delete_key_from_keystore(kmfhandle, numattr, attrlist);
47230a5e8faSwyllys 
47330a5e8faSwyllys 	(void) kmf_free_signed_csr(&csr);
47499ebb4caSwyllys 
47599ebb4caSwyllys 	return (kmfrv);
47699ebb4caSwyllys }
47799ebb4caSwyllys 
47899ebb4caSwyllys int
47999ebb4caSwyllys pk_gencsr(int argc, char *argv[])
48099ebb4caSwyllys {
48199ebb4caSwyllys 	KMF_RETURN rv;
48299ebb4caSwyllys 	int opt;
48399ebb4caSwyllys 	extern int	optind_av;
48499ebb4caSwyllys 	extern char	*optarg_av;
48599ebb4caSwyllys 	KMF_KEYSTORE_TYPE kstype = 0;
48699ebb4caSwyllys 	char *subject = NULL;
48799ebb4caSwyllys 	char *tokenname = NULL;
48899ebb4caSwyllys 	char *dir = NULL;
48999ebb4caSwyllys 	char *prefix = NULL;
49099ebb4caSwyllys 	int keylen = PK_DEFAULT_KEYLENGTH;
49199ebb4caSwyllys 	char *certlabel = NULL;
49299ebb4caSwyllys 	char *outcsr = NULL;
49399ebb4caSwyllys 	char *outkey = NULL;
49499ebb4caSwyllys 	char *format = NULL;
49599ebb4caSwyllys 	char *altname = NULL;
49699ebb4caSwyllys 	char *kustr = NULL;
497d00756ccSwyllys 	char *ekustr = NULL;
49899ebb4caSwyllys 	uint16_t kubits = 0;
49999ebb4caSwyllys 	char *keytype = PK_DEFAULT_KEYTYPE;
50099ebb4caSwyllys 	KMF_HANDLE_T kmfhandle = NULL;
50199ebb4caSwyllys 	KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1;
50299ebb4caSwyllys 	KMF_KEY_ALG keyAlg = KMF_RSA;
50399ebb4caSwyllys 	KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_MD5WithRSA;
50499ebb4caSwyllys 	boolean_t interactive = B_FALSE;
50599ebb4caSwyllys 	char *subname = NULL;
50699ebb4caSwyllys 	KMF_CREDENTIAL tokencred = {NULL, 0};
50799ebb4caSwyllys 	KMF_GENERALNAMECHOICES alttype = 0;
50899ebb4caSwyllys 	int altcrit = 0, kucrit = 0;
509d00756ccSwyllys 	EKU_LIST *ekulist = NULL;
51099ebb4caSwyllys 
51199ebb4caSwyllys 	while ((opt = getopt_av(argc, argv,
51299ebb4caSwyllys 	    "ik:(keystore)s:(subject)n:(nickname)A:(altname)"
51399ebb4caSwyllys 	    "u:(keyusage)T:(token)d:(dir)p:(prefix)t:(keytype)"
514d00756ccSwyllys 	    "y:(keylen)l:(label)c:(outcsr)e:(eku)"
51599ebb4caSwyllys 	    "K:(outkey)F:(format)")) != EOF) {
51699ebb4caSwyllys 
51799ebb4caSwyllys 		if (opt != 'i' && EMPTYSTRING(optarg_av))
51899ebb4caSwyllys 			return (PK_ERR_USAGE);
51999ebb4caSwyllys 
52099ebb4caSwyllys 		switch (opt) {
52199ebb4caSwyllys 			case 'A':
52299ebb4caSwyllys 				altname = optarg_av;
52399ebb4caSwyllys 				break;
52499ebb4caSwyllys 			case 'i':
52599ebb4caSwyllys 				if (interactive || subject)
52699ebb4caSwyllys 					return (PK_ERR_USAGE);
52799ebb4caSwyllys 				else
52899ebb4caSwyllys 					interactive = B_TRUE;
52999ebb4caSwyllys 				break;
53099ebb4caSwyllys 			case 'k':
53199ebb4caSwyllys 				kstype = KS2Int(optarg_av);
53299ebb4caSwyllys 				if (kstype == 0)
53399ebb4caSwyllys 					return (PK_ERR_USAGE);
53499ebb4caSwyllys 				break;
53599ebb4caSwyllys 			case 's':
53699ebb4caSwyllys 				if (interactive || subject)
53799ebb4caSwyllys 					return (PK_ERR_USAGE);
53899ebb4caSwyllys 				else
53999ebb4caSwyllys 					subject = optarg_av;
54099ebb4caSwyllys 				break;
54199ebb4caSwyllys 			case 'l':
54299ebb4caSwyllys 			case 'n':
54399ebb4caSwyllys 				if (certlabel)
54499ebb4caSwyllys 					return (PK_ERR_USAGE);
54599ebb4caSwyllys 				certlabel = optarg_av;
54699ebb4caSwyllys 				break;
54799ebb4caSwyllys 			case 'T':
54899ebb4caSwyllys 				if (tokenname)
54999ebb4caSwyllys 					return (PK_ERR_USAGE);
55099ebb4caSwyllys 				tokenname = optarg_av;
55199ebb4caSwyllys 				break;
55299ebb4caSwyllys 			case 'd':
55399ebb4caSwyllys 				dir = optarg_av;
55499ebb4caSwyllys 				break;
55599ebb4caSwyllys 			case 'p':
55699ebb4caSwyllys 				if (prefix)
55799ebb4caSwyllys 					return (PK_ERR_USAGE);
55899ebb4caSwyllys 				prefix = optarg_av;
55999ebb4caSwyllys 				break;
56099ebb4caSwyllys 			case 't':
56199ebb4caSwyllys 				keytype = optarg_av;
56299ebb4caSwyllys 				break;
56399ebb4caSwyllys 			case 'u':
56499ebb4caSwyllys 				kustr = optarg_av;
56599ebb4caSwyllys 				break;
56699ebb4caSwyllys 			case 'y':
56799ebb4caSwyllys 				if (sscanf(optarg_av, "%d",
56899ebb4caSwyllys 				    &keylen) != 1) {
56999ebb4caSwyllys 					cryptoerror(LOG_STDERR,
57099ebb4caSwyllys 					    gettext("Unrecognized "
57130a5e8faSwyllys 					    "key length (%s)\n"), optarg_av);
57299ebb4caSwyllys 					return (PK_ERR_USAGE);
57399ebb4caSwyllys 				}
57499ebb4caSwyllys 				break;
57599ebb4caSwyllys 			case 'c':
57699ebb4caSwyllys 				if (outcsr)
57799ebb4caSwyllys 					return (PK_ERR_USAGE);
57899ebb4caSwyllys 				outcsr = optarg_av;
57999ebb4caSwyllys 				break;
58099ebb4caSwyllys 			case 'K':
58199ebb4caSwyllys 				if (outkey)
58299ebb4caSwyllys 					return (PK_ERR_USAGE);
58399ebb4caSwyllys 				outkey = optarg_av;
58499ebb4caSwyllys 				break;
58599ebb4caSwyllys 			case 'F':
58699ebb4caSwyllys 				if (format)
58799ebb4caSwyllys 					return (PK_ERR_USAGE);
58899ebb4caSwyllys 				format = optarg_av;
58999ebb4caSwyllys 				break;
590d00756ccSwyllys 			case 'e':
591d00756ccSwyllys 				ekustr = optarg_av;
592d00756ccSwyllys 				break;
59399ebb4caSwyllys 			default:
59499ebb4caSwyllys 				cryptoerror(LOG_STDERR, gettext(
59599ebb4caSwyllys 				    "unrecognized gencsr option '%s'\n"),
59699ebb4caSwyllys 				    argv[optind_av]);
59799ebb4caSwyllys 				return (PK_ERR_USAGE);
59899ebb4caSwyllys 		}
59999ebb4caSwyllys 	}
60099ebb4caSwyllys 	/* No additional args allowed. */
60199ebb4caSwyllys 	argc -= optind_av;
60299ebb4caSwyllys 	argv += optind_av;
60399ebb4caSwyllys 	if (argc) {
60499ebb4caSwyllys 		return (PK_ERR_USAGE);
60599ebb4caSwyllys 	}
60699ebb4caSwyllys 
60730a5e8faSwyllys 	if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
60899ebb4caSwyllys 		cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n"));
60999ebb4caSwyllys 		return (PK_ERR_USAGE);
61099ebb4caSwyllys 	}
61199ebb4caSwyllys 
61299ebb4caSwyllys 	/* Assume keystore = PKCS#11 if not specified. */
61399ebb4caSwyllys 	if (kstype == 0)
61499ebb4caSwyllys 		kstype = KMF_KEYSTORE_PK11TOKEN;
61599ebb4caSwyllys 
6162cbed729Swyllys 	if (EMPTYSTRING(outcsr) && interactive) {
6172cbed729Swyllys 		(void) get_filename("CSR", &outcsr);
6182cbed729Swyllys 	}
61999ebb4caSwyllys 	if (EMPTYSTRING(outcsr)) {
62099ebb4caSwyllys 		(void) printf(gettext("A filename must be specified to hold"
62199ebb4caSwyllys 		    "the final certificate request data.\n"));
62299ebb4caSwyllys 		return (PK_ERR_USAGE);
6232cbed729Swyllys 	}
62499ebb4caSwyllys 	/*
62599ebb4caSwyllys 	 * verify that the outcsr file does not already exist
62699ebb4caSwyllys 	 * and that it can be created.
62799ebb4caSwyllys 	 */
62899ebb4caSwyllys 	rv = verify_file(outcsr);
62999ebb4caSwyllys 	if (rv != KMF_OK) {
63099ebb4caSwyllys 		cryptoerror(LOG_STDERR, gettext("output file (%s) "
63199ebb4caSwyllys 		    "cannot be created.\n"), outcsr);
63299ebb4caSwyllys 		return (PK_ERR_USAGE);
63399ebb4caSwyllys 	}
63499ebb4caSwyllys 
6352cbed729Swyllys 	if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN)) {
6362cbed729Swyllys 		if (EMPTYSTRING(certlabel) && interactive)
6372cbed729Swyllys 			(void) get_certlabel(&certlabel);
6382cbed729Swyllys 
6392cbed729Swyllys 		if (EMPTYSTRING(certlabel)) {
6402cbed729Swyllys 			cryptoerror(LOG_STDERR, gettext("A label must be "
64199ebb4caSwyllys 			    "specified to create a certificate request.\n"));
64299ebb4caSwyllys 			return (PK_ERR_USAGE);
64399ebb4caSwyllys 		}
6442cbed729Swyllys 	} else if (kstype == KMF_KEYSTORE_OPENSSL) {
6452cbed729Swyllys 		if (EMPTYSTRING(outkey) && interactive)
6462cbed729Swyllys 			(void) get_filename("private key", &outkey);
6472cbed729Swyllys 
6482cbed729Swyllys 		if (EMPTYSTRING(outkey)) {
6492cbed729Swyllys 			cryptoerror(LOG_STDERR, gettext("A key filename "
6502cbed729Swyllys 			    "must be specified to create a certificate "
6512cbed729Swyllys 			    "request.\n"));
6522cbed729Swyllys 			return (PK_ERR_USAGE);
6532cbed729Swyllys 		}
6542cbed729Swyllys 	}
65599ebb4caSwyllys 
65699ebb4caSwyllys 	if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) {
65799ebb4caSwyllys 		cryptoerror(LOG_STDERR,
65830a5e8faSwyllys 		    gettext("Error parsing format string (%s).\n"), format);
65999ebb4caSwyllys 		return (PK_ERR_USAGE);
66099ebb4caSwyllys 	}
66199ebb4caSwyllys 	if (format && fmt != KMF_FORMAT_ASN1 && fmt != KMF_FORMAT_PEM) {
66299ebb4caSwyllys 		cryptoerror(LOG_STDERR,
66399ebb4caSwyllys 		    gettext("CSR must be DER or PEM format.\n"));
66499ebb4caSwyllys 		return (PK_ERR_USAGE);
66599ebb4caSwyllys 	}
66699ebb4caSwyllys 
66799ebb4caSwyllys 	/*
66899ebb4caSwyllys 	 * Check the subject name.
66999ebb4caSwyllys 	 * If interactive is true, get it now interactively.
67099ebb4caSwyllys 	 */
67199ebb4caSwyllys 	if (interactive) {
67299ebb4caSwyllys 		if (get_subname(&subname) != KMF_OK) {
67399ebb4caSwyllys 			cryptoerror(LOG_STDERR, gettext("Failed to get the "
67499ebb4caSwyllys 			    "subject name interactively.\n"));
67599ebb4caSwyllys 			return (PK_ERR_USAGE);
67699ebb4caSwyllys 		}
67799ebb4caSwyllys 	} else {
67899ebb4caSwyllys 		if (EMPTYSTRING(subject)) {
67999ebb4caSwyllys 			cryptoerror(LOG_STDERR, gettext("A subject name or "
68099ebb4caSwyllys 			    "-i must be specified to create a certificate "
68199ebb4caSwyllys 			    "request.\n"));
68299ebb4caSwyllys 			return (PK_ERR_USAGE);
68399ebb4caSwyllys 		} else {
68499ebb4caSwyllys 			subname = strdup(subject);
68599ebb4caSwyllys 			if (subname == NULL) {
68699ebb4caSwyllys 				cryptoerror(LOG_STDERR,
68799ebb4caSwyllys 				    gettext("Out of memory.\n"));
68899ebb4caSwyllys 				return (PK_ERR_SYSTEM);
68999ebb4caSwyllys 			}
69099ebb4caSwyllys 		}
69199ebb4caSwyllys 	}
69299ebb4caSwyllys 	if (altname != NULL) {
69399ebb4caSwyllys 		rv = verify_altname(altname, &alttype, &altcrit);
69499ebb4caSwyllys 		if (rv != KMF_OK) {
69599ebb4caSwyllys 			cryptoerror(LOG_STDERR, gettext("Subject AltName "
69699ebb4caSwyllys 			    "must be specified as a name=value pair. "
69799ebb4caSwyllys 			    "See the man page for details."));
69899ebb4caSwyllys 			goto end;
69999ebb4caSwyllys 		} else {
70099ebb4caSwyllys 			/* advance the altname past the '=' sign */
70199ebb4caSwyllys 			char *p = strchr(altname, '=');
70299ebb4caSwyllys 			if (p != NULL)
70399ebb4caSwyllys 				altname = p + 1;
70499ebb4caSwyllys 		}
70599ebb4caSwyllys 	}
70699ebb4caSwyllys 
70799ebb4caSwyllys 	if (kustr != NULL) {
70899ebb4caSwyllys 		rv = verify_keyusage(kustr, &kubits, &kucrit);
70999ebb4caSwyllys 		if (rv != KMF_OK) {
71099ebb4caSwyllys 			cryptoerror(LOG_STDERR, gettext("KeyUsage "
71199ebb4caSwyllys 			    "must be specified as a comma-separated list. "
71299ebb4caSwyllys 			    "See the man page for details."));
71399ebb4caSwyllys 			goto end;
71499ebb4caSwyllys 		}
71599ebb4caSwyllys 	}
716d00756ccSwyllys 	if (ekustr != NULL) {
717d00756ccSwyllys 		rv = verify_ekunames(ekustr, &ekulist);
718d00756ccSwyllys 		if (rv != KMF_OK) {
719d00756ccSwyllys 			(void) fprintf(stderr, gettext("EKUs must "
720d00756ccSwyllys 			    "be specified as a comma-separated list. "
721d00756ccSwyllys 			    "See the man page for details.\n"));
722d00756ccSwyllys 			rv = PK_ERR_USAGE;
723d00756ccSwyllys 			goto end;
724d00756ccSwyllys 		}
725d00756ccSwyllys 	}
726d00756ccSwyllys 
727d00756ccSwyllys 
72899ebb4caSwyllys 	if ((rv = Str2KeyType(keytype, &keyAlg, &sigAlg)) != 0) {
72999ebb4caSwyllys 		cryptoerror(LOG_STDERR, gettext("Unrecognized keytype (%s).\n"),
73099ebb4caSwyllys 		    keytype);
73199ebb4caSwyllys 		goto end;
73299ebb4caSwyllys 	}
73399ebb4caSwyllys 
73499ebb4caSwyllys 	if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) {
73599ebb4caSwyllys 		if (tokenname == NULL || !strlen(tokenname)) {
73699ebb4caSwyllys 			if (kstype == KMF_KEYSTORE_NSS) {
73799ebb4caSwyllys 				tokenname = "internal";
73899ebb4caSwyllys 			} else  {
73999ebb4caSwyllys 				tokenname = PK_DEFAULT_PK11TOKEN;
74099ebb4caSwyllys 			}
74199ebb4caSwyllys 		}
74299ebb4caSwyllys 
74399ebb4caSwyllys 		(void) get_token_password(kstype, tokenname, &tokencred);
74499ebb4caSwyllys 	}
74599ebb4caSwyllys 
74699ebb4caSwyllys 	if (kstype == KMF_KEYSTORE_NSS) {
74799ebb4caSwyllys 		if (dir == NULL)
74899ebb4caSwyllys 			dir = PK_DEFAULT_DIRECTORY;
74999ebb4caSwyllys 
75099ebb4caSwyllys 		rv = gencsr_nss(kmfhandle,
75199ebb4caSwyllys 		    tokenname, subname, altname, alttype, altcrit,
75299ebb4caSwyllys 		    certlabel, dir, prefix,
75399ebb4caSwyllys 		    keyAlg, keylen, kubits, kucrit,
754d00756ccSwyllys 		    fmt, outcsr, &tokencred, ekulist);
75599ebb4caSwyllys 
75699ebb4caSwyllys 	} else if (kstype == KMF_KEYSTORE_PK11TOKEN) {
75799ebb4caSwyllys 		rv = gencsr_pkcs11(kmfhandle,
75899ebb4caSwyllys 		    tokenname, subname, altname, alttype, altcrit,
75999ebb4caSwyllys 		    certlabel, keyAlg, keylen,
760d00756ccSwyllys 		    kubits, kucrit, fmt, outcsr, &tokencred, ekulist);
76199ebb4caSwyllys 
76299ebb4caSwyllys 	} else if (kstype == KMF_KEYSTORE_OPENSSL) {
76399ebb4caSwyllys 		rv = gencsr_file(kmfhandle,
76499ebb4caSwyllys 		    keyAlg, keylen, fmt, subname, altname,
76599ebb4caSwyllys 		    alttype, altcrit, kubits, kucrit,
766*448b8615Swyllys 		    outcsr, outkey, ekulist);
76799ebb4caSwyllys 	}
76899ebb4caSwyllys 
76999ebb4caSwyllys end:
77099ebb4caSwyllys 	if (rv != KMF_OK)
77199ebb4caSwyllys 		display_error(kmfhandle, rv,
77299ebb4caSwyllys 		    gettext("Error creating CSR or keypair"));
77399ebb4caSwyllys 
774d00756ccSwyllys 	if (ekulist != NULL)
775d00756ccSwyllys 		free_eku_list(ekulist);
776d00756ccSwyllys 
77799ebb4caSwyllys 	if (subname)
77899ebb4caSwyllys 		free(subname);
77999ebb4caSwyllys 
78099ebb4caSwyllys 	if (tokencred.cred != NULL)
78199ebb4caSwyllys 		free(tokencred.cred);
78299ebb4caSwyllys 
78330a5e8faSwyllys 	(void) kmf_finalize(kmfhandle);
78499ebb4caSwyllys 	if (rv != KMF_OK)
78599ebb4caSwyllys 		return (PK_ERR_USAGE);
78699ebb4caSwyllys 
78799ebb4caSwyllys 	return (0);
78899ebb4caSwyllys }
789