xref: /onnv-gate/usr/src/cmd/cmd-crypto/pktool/gencsr.c (revision 10241:356a64b58ebc)
13089Swyllys /*
23089Swyllys  * CDDL HEADER START
33089Swyllys  *
43089Swyllys  * The contents of this file are subject to the terms of the
53089Swyllys  * Common Development and Distribution License (the "License").
63089Swyllys  * You may not use this file except in compliance with the License.
73089Swyllys  *
83089Swyllys  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93089Swyllys  * or http://www.opensolaris.org/os/licensing.
103089Swyllys  * See the License for the specific language governing permissions
113089Swyllys  * and limitations under the License.
123089Swyllys  *
133089Swyllys  * When distributing Covered Code, include this CDDL HEADER in each
143089Swyllys  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153089Swyllys  * If applicable, add the following below this CDDL HEADER, with the
163089Swyllys  * fields enclosed by brackets "[]" replaced with your own identifying
173089Swyllys  * information: Portions Copyright [yyyy] [name of copyright owner]
183089Swyllys  *
193089Swyllys  * CDDL HEADER END
203089Swyllys  *
213089Swyllys  *
229145SHuie-Ying.Lee@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
233089Swyllys  * Use is subject to license terms.
243089Swyllys  */
253089Swyllys 
263089Swyllys #include <stdio.h>
273089Swyllys #include <string.h>
283089Swyllys #include <ctype.h>
293089Swyllys #include <malloc.h>
303089Swyllys #include <libgen.h>
313089Swyllys #include <errno.h>
323089Swyllys #include <cryptoutil.h>
333089Swyllys #include <security/cryptoki.h>
343089Swyllys #include "common.h"
353089Swyllys 
363089Swyllys #include <kmfapi.h>
373089Swyllys 
383089Swyllys #define	SET_VALUE(f, s) \
393089Swyllys 	kmfrv = f; \
403089Swyllys 	if (kmfrv != KMF_OK) { \
413089Swyllys 		cryptoerror(LOG_STDERR, \
423089Swyllys 			gettext("Failed to %s: 0x%02\n"), \
433089Swyllys 			s, kmfrv); \
443089Swyllys 		goto cleanup; \
453089Swyllys 	}
463089Swyllys 
473089Swyllys static KMF_RETURN
483089Swyllys gencsr_pkcs11(KMF_HANDLE_T kmfhandle,
493089Swyllys 	char *token, char *subject, char *altname,
503089Swyllys 	KMF_GENERALNAMECHOICES alttype, int altcrit,
513089Swyllys 	char *certlabel, KMF_KEY_ALG keyAlg,
526051Swyllys 	int keylen, uint16_t kubits, int kucrit,
533089Swyllys 	KMF_ENCODE_FORMAT fmt, char *csrfile,
546051Swyllys 	KMF_CREDENTIAL *tokencred, EKU_LIST *ekulist)
553089Swyllys {
563089Swyllys 	KMF_RETURN kmfrv = KMF_OK;
573089Swyllys 	KMF_KEY_HANDLE pubk, prik;
583089Swyllys 	KMF_X509_NAME	csrSubject;
593089Swyllys 	KMF_CSR_DATA	csr;
603089Swyllys 	KMF_ALGORITHM_INDEX sigAlg;
613089Swyllys 	KMF_DATA signedCsr = {NULL, 0};
623089Swyllys 
635051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
645051Swyllys 	int numattr = 0;
655051Swyllys 	KMF_ATTRIBUTE attrlist[16];
665051Swyllys 	boolean_t storekey = TRUE;
675051Swyllys 
683089Swyllys 	(void) memset(&csr, 0, sizeof (csr));
693089Swyllys 	(void) memset(&csrSubject, 0, sizeof (csrSubject));
703089Swyllys 
713089Swyllys 	if (keyAlg == KMF_DSA)
723089Swyllys 		sigAlg = KMF_ALGID_SHA1WithDSA;
733089Swyllys 	else
743089Swyllys 		sigAlg = KMF_ALGID_MD5WithRSA;
753089Swyllys 
763089Swyllys 
773089Swyllys 	/* If the subject name cannot be parsed, flag it now and exit */
785051Swyllys 	if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) {
793089Swyllys 		return (kmfrv);
803089Swyllys 	}
813089Swyllys 
823089Swyllys 	/* Select a PKCS11 token */
833089Swyllys 	kmfrv = select_token(kmfhandle, token, FALSE);
843089Swyllys 	if (kmfrv != KMF_OK) {
853089Swyllys 		return (kmfrv);
863089Swyllys 	}
873089Swyllys 
885051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
895051Swyllys 	    &kstype, sizeof (kstype));
905051Swyllys 	numattr++;
915051Swyllys 
925051Swyllys 	if (certlabel != NULL && strlen(certlabel)) {
935051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR,
945051Swyllys 		    certlabel, strlen(certlabel));
955051Swyllys 		numattr++;
965051Swyllys 	}
975051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLENGTH_ATTR,
985051Swyllys 	    &keylen, sizeof (keylen));
995051Swyllys 	numattr++;
1005051Swyllys 
1015051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYALG_ATTR,
1025051Swyllys 	    &keyAlg, sizeof (keyAlg));
1035051Swyllys 	numattr++;
1045051Swyllys 
1055051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
1065051Swyllys 	    tokencred, sizeof (KMF_CREDENTIAL));
1075051Swyllys 	numattr++;
1085051Swyllys 
1095051Swyllys 	if (token && strlen(token)) {
1105051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
1115051Swyllys 		    token, strlen(token));
1125051Swyllys 		numattr++;
1135051Swyllys 	}
1145051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR,
1155051Swyllys 	    &pubk, sizeof (KMF_KEY_HANDLE));
1165051Swyllys 	numattr++;
1175051Swyllys 
1185051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVKEY_HANDLE_ATTR,
1195051Swyllys 	    &prik, sizeof (KMF_KEY_HANDLE));
1205051Swyllys 	numattr++;
1215051Swyllys 
1225051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_STOREKEY_BOOL_ATTR,
1235051Swyllys 	    &storekey, sizeof (storekey));
1245051Swyllys 	numattr++;
1255051Swyllys 
1265051Swyllys 	kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist);
1273089Swyllys 	if (kmfrv != KMF_OK) {
1283089Swyllys 		return (kmfrv);
1293089Swyllys 	}
1303089Swyllys 
1315051Swyllys 	SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr), "keypair");
1323089Swyllys 
1335051Swyllys 	SET_VALUE(kmf_set_csr_version(&csr, 2), "version number");
1343089Swyllys 
1355051Swyllys 	SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject), "subject name");
1363089Swyllys 
1375051Swyllys 	SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg),
1385051Swyllys 	    "SignatureAlgorithm");
1393089Swyllys 
1403089Swyllys 	if (altname != NULL) {
1415051Swyllys 		SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit,
1425051Swyllys 		    alttype), "SetCSRSubjectAltName");
1433089Swyllys 	}
1443089Swyllys 
1453089Swyllys 	if (kubits != 0) {
1465051Swyllys 		SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits),
1475051Swyllys 		    "SetCSRKeyUsage");
1483089Swyllys 	}
1496051Swyllys 	if (ekulist != NULL) {
1506051Swyllys 		int i;
1516051Swyllys 		for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
1526051Swyllys 			SET_VALUE(kmf_add_csr_eku(&csr,
1536051Swyllys 			    &ekulist->ekulist[i],
1546051Swyllys 			    ekulist->critlist[i]),
1556051Swyllys 			    "Extended Key Usage");
1566051Swyllys 		}
1576051Swyllys 	}
1585051Swyllys 	if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) ==
1595051Swyllys 	    KMF_OK) {
1605051Swyllys 		kmfrv = kmf_create_csr_file(&signedCsr, fmt, csrfile);
1613089Swyllys 	}
1623089Swyllys 
1633089Swyllys cleanup:
1645051Swyllys 	(void) kmf_free_data(&signedCsr);
1659145SHuie-Ying.Lee@Sun.COM 	(void) kmf_free_signed_csr(&csr);
1669145SHuie-Ying.Lee@Sun.COM 
1679145SHuie-Ying.Lee@Sun.COM 	/* delete the public key */
1685051Swyllys 	numattr = 0;
1695051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
1705051Swyllys 	    &kstype, sizeof (kstype));
1715051Swyllys 	numattr++;
1725051Swyllys 
1735051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR,
1745051Swyllys 	    &pubk, sizeof (KMF_KEY_HANDLE));
1755051Swyllys 	numattr++;
1765051Swyllys 
1779145SHuie-Ying.Lee@Sun.COM 	if (tokencred != NULL && tokencred->cred != NULL) {
1789145SHuie-Ying.Lee@Sun.COM 		kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
1799145SHuie-Ying.Lee@Sun.COM 		    tokencred, sizeof (KMF_CREDENTIAL));
1809145SHuie-Ying.Lee@Sun.COM 		numattr++;
1819145SHuie-Ying.Lee@Sun.COM 	}
1829145SHuie-Ying.Lee@Sun.COM 
1835051Swyllys 	(void) kmf_delete_key_from_keystore(kmfhandle, numattr, attrlist);
1845051Swyllys 
1859145SHuie-Ying.Lee@Sun.COM 	/*
1869145SHuie-Ying.Lee@Sun.COM 	 * If there is an error, then we need to remove the private key
1879145SHuie-Ying.Lee@Sun.COM 	 * from the token.
1889145SHuie-Ying.Lee@Sun.COM 	 */
1899145SHuie-Ying.Lee@Sun.COM 	if (kmfrv != KMF_OK) {
1909145SHuie-Ying.Lee@Sun.COM 		numattr = 0;
1919145SHuie-Ying.Lee@Sun.COM 		kmf_set_attr_at_index(attrlist, numattr,
1929145SHuie-Ying.Lee@Sun.COM 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
1939145SHuie-Ying.Lee@Sun.COM 		numattr++;
1943089Swyllys 
1959145SHuie-Ying.Lee@Sun.COM 		kmf_set_attr_at_index(attrlist, numattr,
1969145SHuie-Ying.Lee@Sun.COM 		    KMF_KEY_HANDLE_ATTR, &prik, sizeof (KMF_KEY_HANDLE));
1979145SHuie-Ying.Lee@Sun.COM 		numattr++;
1989145SHuie-Ying.Lee@Sun.COM 
1999145SHuie-Ying.Lee@Sun.COM 		if (tokencred != NULL && tokencred->cred != NULL) {
2009145SHuie-Ying.Lee@Sun.COM 			kmf_set_attr_at_index(attrlist, numattr,
2019145SHuie-Ying.Lee@Sun.COM 			    KMF_CREDENTIAL_ATTR, tokencred,
2029145SHuie-Ying.Lee@Sun.COM 			    sizeof (KMF_CREDENTIAL));
2039145SHuie-Ying.Lee@Sun.COM 			numattr++;
2049145SHuie-Ying.Lee@Sun.COM 		}
2059145SHuie-Ying.Lee@Sun.COM 
2069145SHuie-Ying.Lee@Sun.COM 		(void) kmf_delete_key_from_keystore(kmfhandle, numattr,
2079145SHuie-Ying.Lee@Sun.COM 		    attrlist);
2089145SHuie-Ying.Lee@Sun.COM 	}
2099145SHuie-Ying.Lee@Sun.COM 
2109145SHuie-Ying.Lee@Sun.COM 	(void) kmf_free_kmf_key(kmfhandle, &prik);
2113089Swyllys 	return (kmfrv);
2123089Swyllys }
2133089Swyllys 
2143089Swyllys static KMF_RETURN
2153089Swyllys gencsr_file(KMF_HANDLE_T kmfhandle,
2163089Swyllys 	KMF_KEY_ALG keyAlg,
2173089Swyllys 	int keylen, KMF_ENCODE_FORMAT fmt,
2183089Swyllys 	char *subject, char *altname, KMF_GENERALNAMECHOICES alttype,
2193089Swyllys 	int altcrit, uint16_t kubits, int kucrit,
2206669Swyllys 	char *outcsr, char *outkey, EKU_LIST *ekulist)
2213089Swyllys {
2223089Swyllys 	KMF_RETURN kmfrv;
2233089Swyllys 	KMF_KEY_HANDLE pubk, prik;
2243089Swyllys 	KMF_X509_NAME	csrSubject;
2253089Swyllys 	KMF_CSR_DATA	csr;
2263089Swyllys 	KMF_ALGORITHM_INDEX sigAlg;
2273089Swyllys 	KMF_DATA signedCsr = {NULL, 0};
2283089Swyllys 	char *fullcsrpath = NULL;
2293089Swyllys 	char *fullkeypath = NULL;
2303089Swyllys 
2315051Swyllys 	int numattr = 0;
2325051Swyllys 	KMF_ATTRIBUTE attrlist[16];
2335051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
2345051Swyllys 	boolean_t	storekey = TRUE;
2355051Swyllys 
2363089Swyllys 	(void) memset(&csr, 0, sizeof (csr));
2373089Swyllys 	(void) memset(&csrSubject, 0, sizeof (csrSubject));
2383089Swyllys 
2393089Swyllys 	if (EMPTYSTRING(outcsr) || EMPTYSTRING(outkey)) {
2403089Swyllys 		cryptoerror(LOG_STDERR,
2415051Swyllys 		    gettext("No output file was specified for "
2425051Swyllys 		    "the csr or key\n"));
2433089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
2443089Swyllys 	}
2456669Swyllys 	fullcsrpath = strdup(outcsr);
2463089Swyllys 	if (verify_file(fullcsrpath)) {
2473089Swyllys 		cryptoerror(LOG_STDERR,
2485051Swyllys 		    gettext("Cannot write the indicated output "
2495051Swyllys 		    "certificate file (%s).\n"), fullcsrpath);
2503089Swyllys 		free(fullcsrpath);
2513089Swyllys 		return (PK_ERR_USAGE);
2523089Swyllys 	}
2536669Swyllys 
2546669Swyllys 	fullkeypath = strdup(outkey);
2553089Swyllys 	if (verify_file(fullcsrpath)) {
2563089Swyllys 		cryptoerror(LOG_STDERR,
2575051Swyllys 		    gettext("Cannot write the indicated output "
2585051Swyllys 		    "key file (%s).\n"), fullkeypath);
2593089Swyllys 		free(fullcsrpath);
2603089Swyllys 		return (PK_ERR_USAGE);
2613089Swyllys 	}
2623089Swyllys 
2633089Swyllys 	if (keyAlg == KMF_DSA)
2643089Swyllys 		sigAlg = KMF_ALGID_SHA1WithDSA;
2653089Swyllys 	else
2663089Swyllys 		sigAlg = KMF_ALGID_MD5WithRSA;
2673089Swyllys 
2683089Swyllys 	/* If the subject name cannot be parsed, flag it now and exit */
2695051Swyllys 	if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) {
2703089Swyllys 		return (kmfrv);
2713089Swyllys 	}
2723089Swyllys 
2735051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
2745051Swyllys 	    &kstype, sizeof (kstype));
2755051Swyllys 	numattr++;
2765051Swyllys 
2775051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR,
2785051Swyllys 	    fullkeypath, strlen(fullkeypath));
2795051Swyllys 	numattr++;
2805051Swyllys 
2815051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLENGTH_ATTR,
2825051Swyllys 	    &keylen, sizeof (keylen));
2835051Swyllys 	numattr++;
2845051Swyllys 
2855051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYALG_ATTR,
2865051Swyllys 	    &keyAlg, sizeof (keyAlg));
2875051Swyllys 	numattr++;
2883089Swyllys 
2895051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR,
2905051Swyllys 	    &fmt, sizeof (fmt));
2915051Swyllys 	numattr++;
2925051Swyllys 
2935051Swyllys 	(void) memset(&prik, 0, sizeof (prik));
2945051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVKEY_HANDLE_ATTR,
2955051Swyllys 	    &prik, sizeof (KMF_KEY_HANDLE));
2965051Swyllys 	numattr++;
2973089Swyllys 
2985051Swyllys 	(void) memset(&pubk, 0, sizeof (pubk));
2995051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR,
3005051Swyllys 	    &pubk, sizeof (KMF_KEY_HANDLE));
3015051Swyllys 	numattr++;
3025051Swyllys 
3035051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_STOREKEY_BOOL_ATTR,
3045051Swyllys 	    &storekey, sizeof (storekey));
3055051Swyllys 	numattr++;
3065051Swyllys 
3075051Swyllys 	kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist);
3083089Swyllys 	if (kmfrv != KMF_OK) {
3093089Swyllys 		goto cleanup;
3103089Swyllys 	}
3115051Swyllys 	SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr),
3125051Swyllys 	    "SetCSRPubKey");
3133089Swyllys 
3145051Swyllys 	SET_VALUE(kmf_set_csr_version(&csr, 2), "SetCSRVersion");
3153089Swyllys 
3165051Swyllys 	SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject),
3175051Swyllys 	    "kmf_set_csr_subject");
3183089Swyllys 
3195051Swyllys 	SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg), "kmf_set_csr_sig_alg");
3203089Swyllys 
3213089Swyllys 	if (altname != NULL) {
3225051Swyllys 		SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit,
3235051Swyllys 		    alttype), "kmf_set_csr_subject_altname");
3243089Swyllys 	}
3253089Swyllys 	if (kubits != NULL) {
3265051Swyllys 		SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits),
3275051Swyllys 		    "kmf_set_csr_ku");
3283089Swyllys 	}
3296051Swyllys 	if (ekulist != NULL) {
3306051Swyllys 		int i;
3316051Swyllys 		for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
3326051Swyllys 			SET_VALUE(kmf_add_csr_eku(&csr,
3336051Swyllys 			    &ekulist->ekulist[i],
3346051Swyllys 			    ekulist->critlist[i]),
3356051Swyllys 			    "Extended Key Usage");
3366051Swyllys 		}
3376051Swyllys 	}
3385051Swyllys 	if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) ==
3395051Swyllys 	    KMF_OK) {
3405051Swyllys 		kmfrv = kmf_create_csr_file(&signedCsr, fmt, fullcsrpath);
3413089Swyllys 	}
3423089Swyllys 
3433089Swyllys cleanup:
3443089Swyllys 	if (fullkeypath)
3453089Swyllys 		free(fullkeypath);
3463089Swyllys 	if (fullcsrpath)
3473089Swyllys 		free(fullcsrpath);
3483089Swyllys 
3495051Swyllys 	kmf_free_data(&signedCsr);
3505051Swyllys 	kmf_free_kmf_key(kmfhandle, &prik);
3515051Swyllys 	kmf_free_signed_csr(&csr);
3523089Swyllys 
3533089Swyllys 	return (kmfrv);
3543089Swyllys }
3553089Swyllys 
3563089Swyllys static KMF_RETURN
3573089Swyllys gencsr_nss(KMF_HANDLE_T kmfhandle,
3583089Swyllys 	char *token, char *subject, char *altname,
3593089Swyllys 	KMF_GENERALNAMECHOICES alttype, int altcrit,
3603089Swyllys 	char *nickname, char *dir, char *prefix,
3613089Swyllys 	KMF_KEY_ALG keyAlg, int keylen,
3623089Swyllys 	uint16_t kubits, int kucrit,
3633089Swyllys 	KMF_ENCODE_FORMAT fmt, char *csrfile,
3646051Swyllys 	KMF_CREDENTIAL *tokencred, EKU_LIST *ekulist)
3653089Swyllys {
3663089Swyllys 	KMF_RETURN kmfrv;
3673089Swyllys 	KMF_KEY_HANDLE pubk, prik;
3683089Swyllys 	KMF_X509_NAME	csrSubject;
3693089Swyllys 	KMF_CSR_DATA	csr;
3703089Swyllys 	KMF_ALGORITHM_INDEX sigAlg;
3713089Swyllys 	KMF_DATA signedCsr = {NULL, 0};
3725051Swyllys 
3735051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
3745051Swyllys 	int numattr = 0;
3755051Swyllys 	KMF_ATTRIBUTE attrlist[16];
3765051Swyllys 	boolean_t storekey = TRUE;
3773089Swyllys 
3783089Swyllys 	if (token == NULL)
3793089Swyllys 		token = DEFAULT_NSS_TOKEN;
3803089Swyllys 
3813089Swyllys 	if (keyAlg == KMF_DSA)
3823089Swyllys 		sigAlg = KMF_ALGID_SHA1WithDSA;
3833089Swyllys 	else
3843089Swyllys 		sigAlg = KMF_ALGID_MD5WithRSA;
3853089Swyllys 
3863089Swyllys 	kmfrv = configure_nss(kmfhandle, dir, prefix);
3873089Swyllys 	if (kmfrv != KMF_OK)
3883089Swyllys 		return (kmfrv);
3893089Swyllys 
3903089Swyllys 	(void) memset(&csr, 0, sizeof (csr));
3913089Swyllys 	(void) memset(&csrSubject, 0, sizeof (csrSubject));
3926669Swyllys 	(void) memset(&pubk, 0, sizeof (pubk));
3936669Swyllys 	(void) memset(&prik, 0, sizeof (prik));
3943089Swyllys 
3953089Swyllys 	/* If the subject name cannot be parsed, flag it now and exit */
3965051Swyllys 	if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) {
3973089Swyllys 		return (kmfrv);
3983089Swyllys 	}
3993089Swyllys 
4005051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
4015051Swyllys 	    &kstype, sizeof (kstype));
4025051Swyllys 	numattr++;
4035051Swyllys 
4045051Swyllys 	if (nickname != NULL && strlen(nickname)) {
4055051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR,
4065051Swyllys 		    nickname, strlen(nickname));
4075051Swyllys 		numattr++;
4085051Swyllys 	}
4095051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLENGTH_ATTR,
4105051Swyllys 	    &keylen, sizeof (keylen));
4115051Swyllys 	numattr++;
4125051Swyllys 
4135051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYALG_ATTR,
4145051Swyllys 	    &keyAlg, sizeof (keyAlg));
4155051Swyllys 	numattr++;
4163089Swyllys 
4175051Swyllys 	if (tokencred != NULL && tokencred->credlen > 0) {
4185051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
4195051Swyllys 		    tokencred, sizeof (KMF_CREDENTIAL));
4205051Swyllys 		numattr++;
4215051Swyllys 	}
4223089Swyllys 
4235051Swyllys 	if (token && strlen(token)) {
4245051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
4255051Swyllys 		    token, strlen(token));
4265051Swyllys 		numattr++;
4275051Swyllys 	}
4285051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR,
4295051Swyllys 	    &pubk, sizeof (KMF_KEY_HANDLE));
4305051Swyllys 	numattr++;
4315051Swyllys 
4325051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVKEY_HANDLE_ATTR,
4335051Swyllys 	    &prik, sizeof (KMF_KEY_HANDLE));
4345051Swyllys 	numattr++;
4355051Swyllys 
4365051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_STOREKEY_BOOL_ATTR,
4375051Swyllys 	    &storekey, sizeof (storekey));
4385051Swyllys 	numattr++;
4395051Swyllys 
4405051Swyllys 	kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist);
4413089Swyllys 	if (kmfrv != KMF_OK) {
4423089Swyllys 		goto cleanup;
4433089Swyllys 	}
4443089Swyllys 
4455051Swyllys 	SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr),
4465051Swyllys 	    "kmf_set_csr_pubkey");
4475051Swyllys 	SET_VALUE(kmf_set_csr_version(&csr, 2), "kmf_set_csr_version");
4485051Swyllys 	SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject),
4495051Swyllys 	    "kmf_set_csr_subject");
4505051Swyllys 	SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg), "kmf_set_csr_sig_alg");
4513089Swyllys 
4523089Swyllys 	if (altname != NULL) {
4535051Swyllys 		SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit,
4545051Swyllys 		    alttype), "kmf_set_csr_subject_altname");
4553089Swyllys 	}
4563089Swyllys 	if (kubits != NULL) {
4575051Swyllys 		SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits),
4585051Swyllys 		    "kmf_set_csr_ku");
4593089Swyllys 	}
4606051Swyllys 	if (ekulist != NULL) {
4616051Swyllys 		int i;
4626051Swyllys 		for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
4636051Swyllys 			SET_VALUE(kmf_add_csr_eku(&csr,
4646051Swyllys 			    &ekulist->ekulist[i],
4656051Swyllys 			    ekulist->critlist[i]),
4666051Swyllys 			    "Extended Key Usage");
4676051Swyllys 		}
4686051Swyllys 	}
4695051Swyllys 	if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) ==
4705051Swyllys 	    KMF_OK) {
4715051Swyllys 		kmfrv = kmf_create_csr_file(&signedCsr, fmt, csrfile);
4723089Swyllys 	}
4733089Swyllys 
4743089Swyllys cleanup:
4755051Swyllys 	(void) kmf_free_data(&signedCsr);
4765051Swyllys 	(void) kmf_free_kmf_key(kmfhandle, &prik);
4775051Swyllys 
4783089Swyllys 	/* delete the key */
4795051Swyllys 	numattr = 0;
4805051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
4815051Swyllys 	    &kstype, sizeof (kstype));
4825051Swyllys 	numattr++;
4835051Swyllys 
4845051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR,
4855051Swyllys 	    &pubk, sizeof (KMF_KEY_HANDLE));
4865051Swyllys 	numattr++;
4875051Swyllys 
4885051Swyllys 	if (tokencred != NULL && tokencred->credlen > 0) {
4895051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
4905051Swyllys 		    tokencred, sizeof (KMF_CREDENTIAL));
4915051Swyllys 		numattr++;
4925051Swyllys 	}
4935051Swyllys 
4945051Swyllys 	if (token && strlen(token)) {
4955051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
4965051Swyllys 		    token, strlen(token));
4975051Swyllys 		numattr++;
4985051Swyllys 	}
4995051Swyllys 
5005051Swyllys 	(void) kmf_delete_key_from_keystore(kmfhandle, numattr, attrlist);
5015051Swyllys 
5025051Swyllys 	(void) kmf_free_signed_csr(&csr);
5033089Swyllys 
5043089Swyllys 	return (kmfrv);
5053089Swyllys }
5063089Swyllys 
5073089Swyllys int
5083089Swyllys pk_gencsr(int argc, char *argv[])
5093089Swyllys {
5103089Swyllys 	KMF_RETURN rv;
5113089Swyllys 	int opt;
5123089Swyllys 	extern int	optind_av;
5133089Swyllys 	extern char	*optarg_av;
5143089Swyllys 	KMF_KEYSTORE_TYPE kstype = 0;
5153089Swyllys 	char *subject = NULL;
5163089Swyllys 	char *tokenname = NULL;
5173089Swyllys 	char *dir = NULL;
5183089Swyllys 	char *prefix = NULL;
5193089Swyllys 	int keylen = PK_DEFAULT_KEYLENGTH;
5203089Swyllys 	char *certlabel = NULL;
5213089Swyllys 	char *outcsr = NULL;
5223089Swyllys 	char *outkey = NULL;
5233089Swyllys 	char *format = NULL;
5243089Swyllys 	char *altname = NULL;
5253089Swyllys 	char *kustr = NULL;
5266051Swyllys 	char *ekustr = NULL;
5273089Swyllys 	uint16_t kubits = 0;
5283089Swyllys 	char *keytype = PK_DEFAULT_KEYTYPE;
5293089Swyllys 	KMF_HANDLE_T kmfhandle = NULL;
5303089Swyllys 	KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1;
5313089Swyllys 	KMF_KEY_ALG keyAlg = KMF_RSA;
5323089Swyllys 	KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_MD5WithRSA;
5333089Swyllys 	boolean_t interactive = B_FALSE;
5343089Swyllys 	char *subname = NULL;
5353089Swyllys 	KMF_CREDENTIAL tokencred = {NULL, 0};
5363089Swyllys 	KMF_GENERALNAMECHOICES alttype = 0;
5373089Swyllys 	int altcrit = 0, kucrit = 0;
5386051Swyllys 	EKU_LIST *ekulist = NULL;
5393089Swyllys 
5403089Swyllys 	while ((opt = getopt_av(argc, argv,
5415051Swyllys 	    "ik:(keystore)s:(subject)n:(nickname)A:(altname)"
5425051Swyllys 	    "u:(keyusage)T:(token)d:(dir)p:(prefix)t:(keytype)"
5436051Swyllys 	    "y:(keylen)l:(label)c:(outcsr)e:(eku)"
5445051Swyllys 	    "K:(outkey)F:(format)")) != EOF) {
5453089Swyllys 
5463089Swyllys 		if (opt != 'i' && EMPTYSTRING(optarg_av))
5473089Swyllys 			return (PK_ERR_USAGE);
5483089Swyllys 
5493089Swyllys 		switch (opt) {
5503089Swyllys 			case 'A':
5513089Swyllys 				altname = optarg_av;
5523089Swyllys 				break;
5533089Swyllys 			case 'i':
554*10241Swyllys.ingersoll@sun.com 				if (interactive)
5553089Swyllys 					return (PK_ERR_USAGE);
556*10241Swyllys.ingersoll@sun.com 				else if (subject) {
557*10241Swyllys.ingersoll@sun.com 					cryptoerror(LOG_STDERR,
558*10241Swyllys.ingersoll@sun.com 					    gettext("Interactive (-i) and "
559*10241Swyllys.ingersoll@sun.com 					    "subject options are mutually "
560*10241Swyllys.ingersoll@sun.com 					    "exclusive.\n"));
561*10241Swyllys.ingersoll@sun.com 					return (PK_ERR_USAGE);
562*10241Swyllys.ingersoll@sun.com 				} else
5633089Swyllys 					interactive = B_TRUE;
5643089Swyllys 				break;
5653089Swyllys 			case 'k':
5663089Swyllys 				kstype = KS2Int(optarg_av);
5673089Swyllys 				if (kstype == 0)
5683089Swyllys 					return (PK_ERR_USAGE);
5693089Swyllys 				break;
5703089Swyllys 			case 's':
571*10241Swyllys.ingersoll@sun.com 				if (subject)
5723089Swyllys 					return (PK_ERR_USAGE);
573*10241Swyllys.ingersoll@sun.com 				else if (interactive) {
574*10241Swyllys.ingersoll@sun.com 					cryptoerror(LOG_STDERR,
575*10241Swyllys.ingersoll@sun.com 					    gettext("Interactive (-i) and "
576*10241Swyllys.ingersoll@sun.com 					    "subject options are mutually "
577*10241Swyllys.ingersoll@sun.com 					    "exclusive.\n"));
578*10241Swyllys.ingersoll@sun.com 					return (PK_ERR_USAGE);
579*10241Swyllys.ingersoll@sun.com 				} else
5803089Swyllys 					subject = optarg_av;
5813089Swyllys 				break;
5823089Swyllys 			case 'l':
5833089Swyllys 			case 'n':
5843089Swyllys 				if (certlabel)
5853089Swyllys 					return (PK_ERR_USAGE);
5863089Swyllys 				certlabel = optarg_av;
5873089Swyllys 				break;
5883089Swyllys 			case 'T':
5893089Swyllys 				if (tokenname)
5903089Swyllys 					return (PK_ERR_USAGE);
5913089Swyllys 				tokenname = optarg_av;
5923089Swyllys 				break;
5933089Swyllys 			case 'd':
5943089Swyllys 				dir = optarg_av;
5953089Swyllys 				break;
5963089Swyllys 			case 'p':
5973089Swyllys 				if (prefix)
5983089Swyllys 					return (PK_ERR_USAGE);
5993089Swyllys 				prefix = optarg_av;
6003089Swyllys 				break;
6013089Swyllys 			case 't':
6023089Swyllys 				keytype = optarg_av;
6033089Swyllys 				break;
6043089Swyllys 			case 'u':
6053089Swyllys 				kustr = optarg_av;
6063089Swyllys 				break;
6073089Swyllys 			case 'y':
6083089Swyllys 				if (sscanf(optarg_av, "%d",
6095051Swyllys 				    &keylen) != 1) {
6103089Swyllys 					cryptoerror(LOG_STDERR,
6115051Swyllys 					    gettext("Unrecognized "
6125051Swyllys 					    "key length (%s)\n"), optarg_av);
6133089Swyllys 					return (PK_ERR_USAGE);
6143089Swyllys 				}
6153089Swyllys 				break;
6163089Swyllys 			case 'c':
6173089Swyllys 				if (outcsr)
6183089Swyllys 					return (PK_ERR_USAGE);
6193089Swyllys 				outcsr = optarg_av;
6203089Swyllys 				break;
6213089Swyllys 			case 'K':
6223089Swyllys 				if (outkey)
6233089Swyllys 					return (PK_ERR_USAGE);
6243089Swyllys 				outkey = optarg_av;
6253089Swyllys 				break;
6263089Swyllys 			case 'F':
6273089Swyllys 				if (format)
6283089Swyllys 					return (PK_ERR_USAGE);
6293089Swyllys 				format = optarg_av;
6303089Swyllys 				break;
6316051Swyllys 			case 'e':
6326051Swyllys 				ekustr = optarg_av;
6336051Swyllys 				break;
6343089Swyllys 			default:
6353089Swyllys 				cryptoerror(LOG_STDERR, gettext(
6365051Swyllys 				    "unrecognized gencsr option '%s'\n"),
6375051Swyllys 				    argv[optind_av]);
6383089Swyllys 				return (PK_ERR_USAGE);
6393089Swyllys 		}
6403089Swyllys 	}
6413089Swyllys 	/* No additional args allowed. */
6423089Swyllys 	argc -= optind_av;
6433089Swyllys 	argv += optind_av;
6443089Swyllys 	if (argc) {
6453089Swyllys 		return (PK_ERR_USAGE);
6463089Swyllys 	}
6473089Swyllys 
6483089Swyllys 	/* Assume keystore = PKCS#11 if not specified. */
6493089Swyllys 	if (kstype == 0)
6503089Swyllys 		kstype = KMF_KEYSTORE_PK11TOKEN;
6513089Swyllys 
6526884Swyllys 	DIR_OPTION_CHECK(kstype, dir);
6536884Swyllys 
6545221Swyllys 	if (EMPTYSTRING(outcsr) && interactive) {
6555221Swyllys 		(void) get_filename("CSR", &outcsr);
6565221Swyllys 	}
6573089Swyllys 	if (EMPTYSTRING(outcsr)) {
6583089Swyllys 		(void) printf(gettext("A filename must be specified to hold"
6595051Swyllys 		    "the final certificate request data.\n"));
6603089Swyllys 		return (PK_ERR_USAGE);
6615221Swyllys 	}
6625221Swyllys 	/*
6635221Swyllys 	 * verify that the outcsr file does not already exist
6645221Swyllys 	 * and that it can be created.
6655221Swyllys 	 */
6665221Swyllys 	rv = verify_file(outcsr);
6675221Swyllys 	if (rv != KMF_OK) {
6685221Swyllys 		cryptoerror(LOG_STDERR, gettext("output file (%s) "
6695221Swyllys 		    "cannot be created.\n"), outcsr);
6705221Swyllys 		return (PK_ERR_USAGE);
6715221Swyllys 	}
6725221Swyllys 
6735221Swyllys 	if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN)) {
6745221Swyllys 		if (EMPTYSTRING(certlabel) && interactive)
6755221Swyllys 			(void) get_certlabel(&certlabel);
6765221Swyllys 
6775221Swyllys 		if (EMPTYSTRING(certlabel)) {
6785221Swyllys 			cryptoerror(LOG_STDERR, gettext("A label must be "
6795221Swyllys 			    "specified to create a certificate request.\n"));
6803089Swyllys 			return (PK_ERR_USAGE);
6813089Swyllys 		}
6825221Swyllys 	} else if (kstype == KMF_KEYSTORE_OPENSSL) {
6835221Swyllys 		if (EMPTYSTRING(outkey) && interactive)
6845221Swyllys 			(void) get_filename("private key", &outkey);
6853089Swyllys 
6865221Swyllys 		if (EMPTYSTRING(outkey)) {
6875221Swyllys 			cryptoerror(LOG_STDERR, gettext("A key filename "
6885221Swyllys 			    "must be specified to create a certificate "
6895221Swyllys 			    "request.\n"));
6905221Swyllys 			return (PK_ERR_USAGE);
6915221Swyllys 		}
6923089Swyllys 	}
6933089Swyllys 
6943089Swyllys 	if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) {
6953089Swyllys 		cryptoerror(LOG_STDERR,
6965051Swyllys 		    gettext("Error parsing format string (%s).\n"), format);
6973089Swyllys 		return (PK_ERR_USAGE);
6983089Swyllys 	}
6993089Swyllys 	if (format && fmt != KMF_FORMAT_ASN1 && fmt != KMF_FORMAT_PEM) {
7003089Swyllys 		cryptoerror(LOG_STDERR,
7015051Swyllys 		    gettext("CSR must be DER or PEM format.\n"));
7023089Swyllys 		return (PK_ERR_USAGE);
7033089Swyllys 	}
7043089Swyllys 
7053089Swyllys 	/*
7063089Swyllys 	 * Check the subject name.
7073089Swyllys 	 * If interactive is true, get it now interactively.
7083089Swyllys 	 */
7093089Swyllys 	if (interactive) {
7103089Swyllys 		if (get_subname(&subname) != KMF_OK) {
7113089Swyllys 			cryptoerror(LOG_STDERR, gettext("Failed to get the "
7123089Swyllys 			    "subject name interactively.\n"));
7133089Swyllys 			return (PK_ERR_USAGE);
7143089Swyllys 		}
7153089Swyllys 	} else {
7163089Swyllys 		if (EMPTYSTRING(subject)) {
7173089Swyllys 			cryptoerror(LOG_STDERR, gettext("A subject name or "
7183089Swyllys 			    "-i must be specified to create a certificate "
7193089Swyllys 			    "request.\n"));
7203089Swyllys 			return (PK_ERR_USAGE);
7213089Swyllys 		} else {
7223089Swyllys 			subname = strdup(subject);
7233089Swyllys 			if (subname == NULL) {
7243089Swyllys 				cryptoerror(LOG_STDERR,
7253089Swyllys 				    gettext("Out of memory.\n"));
7263089Swyllys 				return (PK_ERR_SYSTEM);
7273089Swyllys 			}
7283089Swyllys 		}
7293089Swyllys 	}
7303089Swyllys 	if (altname != NULL) {
7313089Swyllys 		rv = verify_altname(altname, &alttype, &altcrit);
7323089Swyllys 		if (rv != KMF_OK) {
7333089Swyllys 			cryptoerror(LOG_STDERR, gettext("Subject AltName "
7345051Swyllys 			    "must be specified as a name=value pair. "
7355051Swyllys 			    "See the man page for details."));
7363089Swyllys 			goto end;
7373089Swyllys 		} else {
7383089Swyllys 			/* advance the altname past the '=' sign */
7393089Swyllys 			char *p = strchr(altname, '=');
7403089Swyllys 			if (p != NULL)
7413089Swyllys 				altname = p + 1;
7423089Swyllys 		}
7433089Swyllys 	}
7443089Swyllys 
7453089Swyllys 	if (kustr != NULL) {
7463089Swyllys 		rv = verify_keyusage(kustr, &kubits, &kucrit);
7473089Swyllys 		if (rv != KMF_OK) {
7483089Swyllys 			cryptoerror(LOG_STDERR, gettext("KeyUsage "
7495051Swyllys 			    "must be specified as a comma-separated list. "
7505051Swyllys 			    "See the man page for details."));
7513089Swyllys 			goto end;
7523089Swyllys 		}
7533089Swyllys 	}
7546051Swyllys 	if (ekustr != NULL) {
7556051Swyllys 		rv = verify_ekunames(ekustr, &ekulist);
7566051Swyllys 		if (rv != KMF_OK) {
7576051Swyllys 			(void) fprintf(stderr, gettext("EKUs must "
7586051Swyllys 			    "be specified as a comma-separated list. "
7596051Swyllys 			    "See the man page for details.\n"));
7606051Swyllys 			rv = PK_ERR_USAGE;
7616051Swyllys 			goto end;
7626051Swyllys 		}
7636051Swyllys 	}
7646051Swyllys 
7653089Swyllys 	if ((rv = Str2KeyType(keytype, &keyAlg, &sigAlg)) != 0) {
7663089Swyllys 		cryptoerror(LOG_STDERR, gettext("Unrecognized keytype (%s).\n"),
7675051Swyllys 		    keytype);
7683089Swyllys 		goto end;
7693089Swyllys 	}
7703089Swyllys 
7713089Swyllys 	if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) {
7723089Swyllys 		if (tokenname == NULL || !strlen(tokenname)) {
7733089Swyllys 			if (kstype == KMF_KEYSTORE_NSS) {
7743089Swyllys 				tokenname = "internal";
7753089Swyllys 			} else  {
7763089Swyllys 				tokenname = PK_DEFAULT_PK11TOKEN;
7773089Swyllys 			}
7783089Swyllys 		}
7793089Swyllys 
7803089Swyllys 		(void) get_token_password(kstype, tokenname, &tokencred);
7813089Swyllys 	}
7823089Swyllys 
7836884Swyllys 	if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
7846884Swyllys 		cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n"));
7856884Swyllys 		return (PK_ERR_USAGE);
7866884Swyllys 	}
7876884Swyllys 
7886884Swyllys 
7893089Swyllys 	if (kstype == KMF_KEYSTORE_NSS) {
7903089Swyllys 		if (dir == NULL)
7913089Swyllys 			dir = PK_DEFAULT_DIRECTORY;
7923089Swyllys 
7933089Swyllys 		rv = gencsr_nss(kmfhandle,
7945051Swyllys 		    tokenname, subname, altname, alttype, altcrit,
7955051Swyllys 		    certlabel, dir, prefix,
7965051Swyllys 		    keyAlg, keylen, kubits, kucrit,
7976051Swyllys 		    fmt, outcsr, &tokencred, ekulist);
7983089Swyllys 
7993089Swyllys 	} else if (kstype == KMF_KEYSTORE_PK11TOKEN) {
8003089Swyllys 		rv = gencsr_pkcs11(kmfhandle,
8015051Swyllys 		    tokenname, subname, altname, alttype, altcrit,
8025051Swyllys 		    certlabel, keyAlg, keylen,
8036051Swyllys 		    kubits, kucrit, fmt, outcsr, &tokencred, ekulist);
8043089Swyllys 
8053089Swyllys 	} else if (kstype == KMF_KEYSTORE_OPENSSL) {
8063089Swyllys 		rv = gencsr_file(kmfhandle,
8075051Swyllys 		    keyAlg, keylen, fmt, subname, altname,
8085051Swyllys 		    alttype, altcrit, kubits, kucrit,
8096669Swyllys 		    outcsr, outkey, ekulist);
8103089Swyllys 	}
8113089Swyllys 
8123089Swyllys end:
813*10241Swyllys.ingersoll@sun.com 	if (rv != KMF_OK) {
8143089Swyllys 		display_error(kmfhandle, rv,
8155051Swyllys 		    gettext("Error creating CSR or keypair"));
8163089Swyllys 
817*10241Swyllys.ingersoll@sun.com 		if (rv == KMF_ERR_RDN_PARSER) {
818*10241Swyllys.ingersoll@sun.com 			cryptoerror(LOG_STDERR, gettext("subject or "
819*10241Swyllys.ingersoll@sun.com 			    "issuer name must be in proper DN format.\n"));
820*10241Swyllys.ingersoll@sun.com 		}
821*10241Swyllys.ingersoll@sun.com 	}
822*10241Swyllys.ingersoll@sun.com 
8236051Swyllys 	if (ekulist != NULL)
8246051Swyllys 		free_eku_list(ekulist);
8256051Swyllys 
8263089Swyllys 	if (subname)
8273089Swyllys 		free(subname);
8283089Swyllys 
8293089Swyllys 	if (tokencred.cred != NULL)
8303089Swyllys 		free(tokencred.cred);
8313089Swyllys 
8325051Swyllys 	(void) kmf_finalize(kmfhandle);
8333089Swyllys 	if (rv != KMF_OK)
8343089Swyllys 		return (PK_ERR_USAGE);
8353089Swyllys 
8363089Swyllys 	return (0);
8373089Swyllys }
838