xref: /titanic_52/usr/src/cmd/cmd-crypto/pktool/signcsr.c (revision 448b8615fe9e8af757530284920a235430ead7e8)
1d00756ccSwyllys /*
2d00756ccSwyllys  * CDDL HEADER START
3d00756ccSwyllys  *
4d00756ccSwyllys  * The contents of this file are subject to the terms of the
5d00756ccSwyllys  * Common Development and Distribution License (the "License").
6d00756ccSwyllys  * You may not use this file except in compliance with the License.
7d00756ccSwyllys  *
8d00756ccSwyllys  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9d00756ccSwyllys  * or http://www.opensolaris.org/os/licensing.
10d00756ccSwyllys  * See the License for the specific language governing permissions
11d00756ccSwyllys  * and limitations under the License.
12d00756ccSwyllys  *
13d00756ccSwyllys  * When distributing Covered Code, include this CDDL HEADER in each
14d00756ccSwyllys  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15d00756ccSwyllys  * If applicable, add the following below this CDDL HEADER, with the
16d00756ccSwyllys  * fields enclosed by brackets "[]" replaced with your own identifying
17d00756ccSwyllys  * information: Portions Copyright [yyyy] [name of copyright owner]
18d00756ccSwyllys  *
19d00756ccSwyllys  * CDDL HEADER END
20d00756ccSwyllys  */
21d00756ccSwyllys /*
22d00756ccSwyllys  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23d00756ccSwyllys  * Use is subject to license terms.
24d00756ccSwyllys  */
25d00756ccSwyllys 
26d00756ccSwyllys #pragma ident	"%Z%%M%	%I%	%E% SMI"
27d00756ccSwyllys 
28d00756ccSwyllys /*
29d00756ccSwyllys  * This file implements the sign CSR operation for this tool.
30d00756ccSwyllys  */
31d00756ccSwyllys 
32d00756ccSwyllys #include <stdio.h>
33d00756ccSwyllys #include <errno.h>
34d00756ccSwyllys #include <string.h>
35d00756ccSwyllys #include <cryptoutil.h>
36d00756ccSwyllys #include <security/cryptoki.h>
37d00756ccSwyllys #include "common.h"
38d00756ccSwyllys 
39d00756ccSwyllys #include <kmfapi.h>
40*448b8615Swyllys #include <kmfapiP.h>
41*448b8615Swyllys 
42d00756ccSwyllys #define	SET_VALUE(f, s) \
43d00756ccSwyllys 	rv = f; \
44d00756ccSwyllys 	if (rv != KMF_OK) { \
45d00756ccSwyllys 		cryptoerror(LOG_STDERR, \
46d00756ccSwyllys 		    gettext("Failed to set %s: 0x%02x\n"), s, rv); \
47d00756ccSwyllys 		goto cleanup; \
48d00756ccSwyllys 	}
49d00756ccSwyllys 
50d00756ccSwyllys 
51d00756ccSwyllys static int
52d00756ccSwyllys read_csrdata(KMF_HANDLE_T handle, char *csrfile, KMF_CSR_DATA *csrdata)
53d00756ccSwyllys {
54d00756ccSwyllys 	KMF_RETURN rv = KMF_OK;
55d00756ccSwyllys 	KMF_ENCODE_FORMAT csrfmt;
56d00756ccSwyllys 	KMF_DATA csrfiledata = {NULL, 0};
57d00756ccSwyllys 	KMF_DATA rawcsr = {NULL, 0};
58d00756ccSwyllys 
59d00756ccSwyllys 	rv = kmf_get_file_format(csrfile, &csrfmt);
60d00756ccSwyllys 	if (rv != KMF_OK)
61d00756ccSwyllys 		return (rv);
62d00756ccSwyllys 
63d00756ccSwyllys 	rv = kmf_read_input_file(handle, csrfile, &csrfiledata);
64d00756ccSwyllys 	if (rv != KMF_OK)
65d00756ccSwyllys 		return (rv);
66d00756ccSwyllys 
67d00756ccSwyllys 	if (csrfmt == KMF_FORMAT_PEM) {
68d00756ccSwyllys 		rv = kmf_pem_to_der(csrfiledata.Data, csrfiledata.Length,
69d00756ccSwyllys 		    &rawcsr.Data, (int *)&rawcsr.Length);
70d00756ccSwyllys 		if (rv != KMF_OK)
71d00756ccSwyllys 			return (rv);
72d00756ccSwyllys 
73d00756ccSwyllys 		kmf_free_data(&csrfiledata);
74d00756ccSwyllys 	} else {
75d00756ccSwyllys 		rawcsr.Data = csrfiledata.Data;
76d00756ccSwyllys 		rawcsr.Length = csrfiledata.Length;
77d00756ccSwyllys 	}
78d00756ccSwyllys 
79d00756ccSwyllys 	rv = kmf_decode_csr(handle, &rawcsr, csrdata);
80d00756ccSwyllys 	kmf_free_data(&rawcsr);
81d00756ccSwyllys 
82d00756ccSwyllys 	return (rv);
83d00756ccSwyllys }
84d00756ccSwyllys 
85*448b8615Swyllys static KMF_RETURN
86*448b8615Swyllys find_csr_extn(KMF_X509_EXTENSIONS *extnlist, KMF_OID *extoid,
87*448b8615Swyllys 	KMF_X509_EXTENSION *outextn)
88*448b8615Swyllys {
89*448b8615Swyllys 	int i, found = 0;
90*448b8615Swyllys 	KMF_X509_EXTENSION *eptr;
91*448b8615Swyllys 	KMF_RETURN rv = KMF_OK;
92*448b8615Swyllys 
93*448b8615Swyllys 	(void) memset(outextn, 0, sizeof (KMF_X509_EXTENSION));
94*448b8615Swyllys 	for (i = 0; !found && i < extnlist->numberOfExtensions; i++) {
95*448b8615Swyllys 		eptr = &extnlist->extensions[i];
96*448b8615Swyllys 		if (IsEqualOid(extoid, &eptr->extnId)) {
97*448b8615Swyllys 			rv = copy_extension_data(outextn, eptr);
98*448b8615Swyllys 			found++;
99*448b8615Swyllys 		}
100*448b8615Swyllys 	}
101*448b8615Swyllys 	if (found == 0 || rv != KMF_OK)
102*448b8615Swyllys 		return (1);
103*448b8615Swyllys 	else
104*448b8615Swyllys 		return (rv);
105*448b8615Swyllys }
106*448b8615Swyllys 
107d00756ccSwyllys static int
108d00756ccSwyllys build_cert_from_csr(KMF_CSR_DATA *csrdata,
109d00756ccSwyllys 	KMF_X509_CERTIFICATE *signedCert,
110d00756ccSwyllys 	KMF_BIGINT *serial,
111d00756ccSwyllys 	uint32_t ltime,
112d00756ccSwyllys 	char *issuer, char *subject,
113d00756ccSwyllys 	char *altname,
114d00756ccSwyllys 	KMF_GENERALNAMECHOICES alttype,
115d00756ccSwyllys 	int altcrit,
116d00756ccSwyllys 	uint16_t kubits,
117d00756ccSwyllys 	int kucrit,
118d00756ccSwyllys 	EKU_LIST *ekulist)
119d00756ccSwyllys {
120d00756ccSwyllys 	KMF_RETURN rv = KMF_OK;
121d00756ccSwyllys 	KMF_X509_NAME issuerDN, subjectDN;
122d00756ccSwyllys 
123d00756ccSwyllys 	/*
124d00756ccSwyllys 	 * If the CSR is ok, now we can generate the final certificate.
125d00756ccSwyllys 	 */
126d00756ccSwyllys 	(void) memset(signedCert, 0, sizeof (KMF_X509_CERTIFICATE));
127d00756ccSwyllys 	(void) memset(&issuerDN, 0, sizeof (issuerDN));
128d00756ccSwyllys 	(void) memset(&subjectDN, 0, sizeof (subjectDN));
129d00756ccSwyllys 
130d00756ccSwyllys 	SET_VALUE(kmf_set_cert_version(signedCert, 2), "version number");
131d00756ccSwyllys 
132d00756ccSwyllys 	SET_VALUE(kmf_set_cert_serial(signedCert, serial), "serial number");
133d00756ccSwyllys 
134d00756ccSwyllys 	SET_VALUE(kmf_set_cert_validity(signedCert, NULL, ltime),
135d00756ccSwyllys 	    "validity time");
136d00756ccSwyllys 
137d00756ccSwyllys 	if (issuer) {
138d00756ccSwyllys 		if (kmf_dn_parser(issuer, &issuerDN) != KMF_OK) {
139d00756ccSwyllys 			cryptoerror(LOG_STDERR,
140d00756ccSwyllys 			    gettext("Issuer name cannot be parsed\n"));
141d00756ccSwyllys 			return (PK_ERR_USAGE);
142d00756ccSwyllys 		}
143d00756ccSwyllys 		SET_VALUE(kmf_set_cert_issuer(signedCert, &issuerDN),
144d00756ccSwyllys 		    "Issuer Name");
145d00756ccSwyllys 	}
146d00756ccSwyllys 	if (subject) {
147d00756ccSwyllys 		if (kmf_dn_parser(subject, &subjectDN) != KMF_OK) {
148d00756ccSwyllys 			cryptoerror(LOG_STDERR,
149d00756ccSwyllys 			    gettext("Subject name cannot be parsed\n"));
150d00756ccSwyllys 			return (PK_ERR_USAGE);
151d00756ccSwyllys 		}
152d00756ccSwyllys 		SET_VALUE(kmf_set_cert_subject(signedCert, &subjectDN),
153d00756ccSwyllys 		    "Subject Name");
154d00756ccSwyllys 	} else {
155d00756ccSwyllys 		signedCert->certificate.subject = csrdata->csr.subject;
156d00756ccSwyllys 	}
157d00756ccSwyllys 
158d00756ccSwyllys 	signedCert->certificate.subjectPublicKeyInfo =
159d00756ccSwyllys 	    csrdata->csr.subjectPublicKeyInfo;
160d00756ccSwyllys 
161d00756ccSwyllys 	signedCert->certificate.extensions = csrdata->csr.extensions;
162d00756ccSwyllys 
163d00756ccSwyllys 	signedCert->certificate.signature =
164d00756ccSwyllys 	    csrdata->signature.algorithmIdentifier;
165d00756ccSwyllys 
166d00756ccSwyllys 	if (kubits != 0) {
167*448b8615Swyllys 		KMF_X509_EXTENSION extn;
168*448b8615Swyllys 		uint16_t oldbits;
169*448b8615Swyllys 		/*
170*448b8615Swyllys 		 * If the CSR already has KU, merge them.
171*448b8615Swyllys 		 */
172*448b8615Swyllys 		rv = find_csr_extn(&csrdata->csr.extensions,
173*448b8615Swyllys 		    (KMF_OID *)&KMFOID_KeyUsage, &extn);
174*448b8615Swyllys 		if (rv == KMF_OK) {
175*448b8615Swyllys 			extn.critical |= kucrit;
176*448b8615Swyllys 			if (extn.value.tagAndValue->value.Length > 1) {
177*448b8615Swyllys 				oldbits =
178*448b8615Swyllys 				    extn.value.tagAndValue->value.Data[1] << 8;
179*448b8615Swyllys 			} else {
180*448b8615Swyllys 				oldbits =
181*448b8615Swyllys 				    extn.value.tagAndValue->value.Data[0];
182*448b8615Swyllys 			}
183*448b8615Swyllys 			oldbits |= kubits;
184*448b8615Swyllys 		} else {
185d00756ccSwyllys 			SET_VALUE(kmf_set_cert_ku(signedCert, kucrit, kubits),
186d00756ccSwyllys 			    "KeyUsage");
187d00756ccSwyllys 		}
188*448b8615Swyllys 	}
189d00756ccSwyllys 	if (altname != NULL) {
190d00756ccSwyllys 		SET_VALUE(kmf_set_cert_subject_altname(signedCert,
191d00756ccSwyllys 		    altcrit, alttype, altname), "subjectAltName");
192d00756ccSwyllys 	}
193d00756ccSwyllys 	if (ekulist != NULL) {
194d00756ccSwyllys 		int i;
195d00756ccSwyllys 		for (i = 0; rv == KMF_OK && i < ekulist->eku_count; i++) {
196d00756ccSwyllys 			SET_VALUE(kmf_add_cert_eku(signedCert,
197d00756ccSwyllys 			    &ekulist->ekulist[i],
198d00756ccSwyllys 			    ekulist->critlist[i]), "Extended Key Usage");
199d00756ccSwyllys 		}
200d00756ccSwyllys 	}
201d00756ccSwyllys cleanup:
202d00756ccSwyllys 	if (issuer != NULL)
203d00756ccSwyllys 		kmf_free_dn(&issuerDN);
204d00756ccSwyllys 	if (subject != NULL)
205d00756ccSwyllys 		kmf_free_dn(&subjectDN);
206d00756ccSwyllys 
207d00756ccSwyllys 	return (rv);
208d00756ccSwyllys }
209d00756ccSwyllys 
210d00756ccSwyllys static int
211d00756ccSwyllys pk_sign_cert(KMF_HANDLE_T handle, KMF_X509_CERTIFICATE *cert,
212d00756ccSwyllys 	KMF_KEY_HANDLE *key, KMF_DATA *outdata)
213d00756ccSwyllys {
214d00756ccSwyllys 	KMF_RETURN rv;
215d00756ccSwyllys 	int numattr;
216d00756ccSwyllys 	KMF_ATTRIBUTE attrlist[4];
217d00756ccSwyllys 
218d00756ccSwyllys 	numattr = 0;
219d00756ccSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
220d00756ccSwyllys 	    &key->kstype, sizeof (KMF_KEYSTORE_TYPE));
221d00756ccSwyllys 	numattr++;
222d00756ccSwyllys 
223d00756ccSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
224d00756ccSwyllys 	    key, sizeof (KMF_KEY_HANDLE_ATTR));
225d00756ccSwyllys 	numattr++;
226d00756ccSwyllys 
227d00756ccSwyllys 	/* cert data that is to be signed */
228d00756ccSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR,
229d00756ccSwyllys 	    cert, sizeof (KMF_X509_CERTIFICATE));
230d00756ccSwyllys 	numattr++;
231d00756ccSwyllys 
232d00756ccSwyllys 	/* output buffer for the signed cert */
233d00756ccSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
234d00756ccSwyllys 	    outdata, sizeof (KMF_DATA));
235d00756ccSwyllys 	numattr++;
236d00756ccSwyllys 
237d00756ccSwyllys 	if ((rv = kmf_sign_cert(handle, numattr, attrlist)) != KMF_OK) {
238d00756ccSwyllys 		cryptoerror(LOG_STDERR,
239d00756ccSwyllys 		    gettext("Failed to sign certificate.\n"));
240d00756ccSwyllys 		return (rv);
241d00756ccSwyllys 	}
242d00756ccSwyllys 
243d00756ccSwyllys 	return (rv);
244d00756ccSwyllys }
245d00756ccSwyllys 
246d00756ccSwyllys static int
247d00756ccSwyllys pk_signcsr_files(KMF_HANDLE_T handle,
248d00756ccSwyllys 	char *signkey,
249d00756ccSwyllys 	char *csrfile,
250d00756ccSwyllys 	KMF_BIGINT *serial,
251d00756ccSwyllys 	char *certfile,
252d00756ccSwyllys 	char *issuer,
253d00756ccSwyllys 	char *subject,
254d00756ccSwyllys 	char *altname,
255d00756ccSwyllys 	KMF_GENERALNAMECHOICES alttype,
256d00756ccSwyllys 	int altcrit,
257d00756ccSwyllys 	uint16_t kubits,
258d00756ccSwyllys 	int kucrit,
259d00756ccSwyllys 	EKU_LIST *ekulist,
260d00756ccSwyllys 	uint32_t ltime,
261d00756ccSwyllys 	KMF_ENCODE_FORMAT fmt)
262d00756ccSwyllys {
263d00756ccSwyllys 	KMF_RETURN rv = KMF_OK;
264d00756ccSwyllys 	KMF_CSR_DATA csrdata;
265d00756ccSwyllys 	KMF_ATTRIBUTE attrlist[16];
266d00756ccSwyllys 	KMF_X509_CERTIFICATE signedCert;
267d00756ccSwyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
268d00756ccSwyllys 	KMF_KEY_CLASS keyclass = KMF_ASYM_PRI;
269d00756ccSwyllys 	KMF_KEY_HANDLE cakey;
270d00756ccSwyllys 	KMF_DATA certdata = {NULL, 0};
271d00756ccSwyllys 	int numattr, count;
272d00756ccSwyllys 
273d00756ccSwyllys 	rv = read_csrdata(handle, csrfile, &csrdata);
274d00756ccSwyllys 	if (rv != KMF_OK) {
275d00756ccSwyllys 		cryptoerror(LOG_STDERR,
276d00756ccSwyllys 		    gettext("Error reading CSR data\n"));
277d00756ccSwyllys 		return (rv);
278d00756ccSwyllys 	}
279d00756ccSwyllys 
280d00756ccSwyllys 	/* verify the signature first */
281d00756ccSwyllys 	numattr = 0;
282d00756ccSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_CSR_DATA_ATTR,
283d00756ccSwyllys 	    &csrdata, sizeof (csrdata));
284d00756ccSwyllys 	numattr++;
285d00756ccSwyllys 
286d00756ccSwyllys 	rv = kmf_verify_csr(handle, numattr, attrlist);
287d00756ccSwyllys 	if (rv != KMF_OK) {
288d00756ccSwyllys 		cryptoerror(LOG_STDERR, gettext("CSR signature "
289d00756ccSwyllys 		    "verification failed.\n"));
290d00756ccSwyllys 		goto cleanup;
291d00756ccSwyllys 	}
292d00756ccSwyllys 
293d00756ccSwyllys 	rv = build_cert_from_csr(&csrdata, &signedCert, serial, ltime,
294d00756ccSwyllys 	    issuer, subject, altname, alttype, altcrit, kubits,
295d00756ccSwyllys 	    kucrit, ekulist);
296d00756ccSwyllys 
297d00756ccSwyllys 	if (rv != KMF_OK)
298d00756ccSwyllys 		goto cleanup;
299d00756ccSwyllys 
300d00756ccSwyllys 	/*
301d00756ccSwyllys 	 * Find the signing key.
302d00756ccSwyllys 	 */
303d00756ccSwyllys 	(void) memset(&cakey, 0, sizeof (cakey));
304d00756ccSwyllys 
305d00756ccSwyllys 	numattr = 0;
306d00756ccSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
307d00756ccSwyllys 	    &kstype, sizeof (kstype));
308d00756ccSwyllys 	numattr++;
309d00756ccSwyllys 
310d00756ccSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR,
311d00756ccSwyllys 	    signkey, strlen(signkey));
312d00756ccSwyllys 	numattr++;
313d00756ccSwyllys 
314d00756ccSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
315d00756ccSwyllys 	    &keyclass, sizeof (keyclass));
316d00756ccSwyllys 	numattr++;
317d00756ccSwyllys 
318d00756ccSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
319d00756ccSwyllys 	    &cakey, sizeof (cakey));
320d00756ccSwyllys 	numattr++;
321d00756ccSwyllys 
322d00756ccSwyllys 	count = 1;
323d00756ccSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
324d00756ccSwyllys 	    &count, sizeof (count));
325d00756ccSwyllys 	numattr++;
326d00756ccSwyllys 
327d00756ccSwyllys 	rv = kmf_find_key(handle, numattr, attrlist);
328d00756ccSwyllys 	if (rv != KMF_OK) {
329d00756ccSwyllys 		cryptoerror(LOG_STDERR, gettext(
330d00756ccSwyllys 		    "Error finding CA signing key\n"));
331d00756ccSwyllys 		goto cleanup;
332d00756ccSwyllys 	}
333d00756ccSwyllys 
334d00756ccSwyllys 	rv = pk_sign_cert(handle, &signedCert, &cakey, &certdata);
335d00756ccSwyllys 	if (rv != KMF_OK) {
336d00756ccSwyllys 		cryptoerror(LOG_STDERR, gettext(
337d00756ccSwyllys 		    "Error signing certificate.\n"));
338d00756ccSwyllys 		goto cleanup;
339d00756ccSwyllys 	}
340d00756ccSwyllys 
341d00756ccSwyllys 	rv = kmf_create_cert_file(&certdata, fmt, certfile);
342d00756ccSwyllys 
343d00756ccSwyllys cleanup:
344d00756ccSwyllys 	kmf_free_signed_csr(&csrdata);
345d00756ccSwyllys 	kmf_free_data(&certdata);
346d00756ccSwyllys 	kmf_free_kmf_key(handle, &cakey);
347d00756ccSwyllys 	return (rv);
348d00756ccSwyllys }
349d00756ccSwyllys 
350d00756ccSwyllys static int
351d00756ccSwyllys pk_signcsr_pk11_nss(KMF_HANDLE_T handle,
352d00756ccSwyllys 	KMF_KEYSTORE_TYPE kstype,
353d00756ccSwyllys 	char *dir, char *prefix,
354d00756ccSwyllys 	char *token, KMF_CREDENTIAL *cred,
355d00756ccSwyllys 	char *signkey, char *csrfile,
356d00756ccSwyllys 	KMF_BIGINT *serial, char *certfile, char *issuer, char *subject,
357d00756ccSwyllys 	char *altname, KMF_GENERALNAMECHOICES alttype, int altcrit,
358d00756ccSwyllys 	uint16_t kubits, int kucrit,
359d00756ccSwyllys 	EKU_LIST *ekulist, uint32_t ltime,
360d00756ccSwyllys 	KMF_ENCODE_FORMAT fmt, int store, char *outlabel)
361d00756ccSwyllys {
362d00756ccSwyllys 	KMF_RETURN rv = KMF_OK;
363d00756ccSwyllys 	KMF_DATA outcert = {NULL, 0};
364d00756ccSwyllys 	KMF_CSR_DATA csrdata;
365d00756ccSwyllys 	KMF_KEY_HANDLE casignkey;
366d00756ccSwyllys 	KMF_KEY_CLASS keyclass = KMF_ASYM_PRI;
367d00756ccSwyllys 	int numattr = 0;
368d00756ccSwyllys 	int keys = 1;
369d00756ccSwyllys 	KMF_ATTRIBUTE attrlist[16];
370d00756ccSwyllys 	KMF_X509_CERTIFICATE signedCert;
371d00756ccSwyllys 	boolean_t token_bool = B_TRUE;
372d00756ccSwyllys 	boolean_t private_bool = B_TRUE;
373d00756ccSwyllys 
374d00756ccSwyllys 	rv = read_csrdata(handle, csrfile, &csrdata);
375d00756ccSwyllys 	if (rv != KMF_OK) {
376d00756ccSwyllys 		cryptoerror(LOG_STDERR,
377d00756ccSwyllys 		    gettext("Error reading CSR data\n"));
378d00756ccSwyllys 		return (rv);
379d00756ccSwyllys 	}
380d00756ccSwyllys 
381d00756ccSwyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
382d00756ccSwyllys 		rv = select_token(handle, token, FALSE);
383d00756ccSwyllys 	} else if (kstype == KMF_KEYSTORE_NSS) {
384d00756ccSwyllys 		rv = configure_nss(handle, dir, prefix);
385d00756ccSwyllys 	}
386d00756ccSwyllys 
387d00756ccSwyllys 	/* verify the signature first */
388d00756ccSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_CSR_DATA_ATTR,
389d00756ccSwyllys 	    &csrdata, sizeof (csrdata));
390d00756ccSwyllys 	numattr++;
391d00756ccSwyllys 
392d00756ccSwyllys 	rv = kmf_verify_csr(handle, numattr, attrlist);
393d00756ccSwyllys 	if (rv != KMF_OK) {
394d00756ccSwyllys 		cryptoerror(LOG_STDERR, gettext("CSR signature "
395d00756ccSwyllys 		    "verification failed.\n"));
396d00756ccSwyllys 		goto cleanup;
397d00756ccSwyllys 	}
398d00756ccSwyllys 
399d00756ccSwyllys 	rv = build_cert_from_csr(&csrdata,
400d00756ccSwyllys 	    &signedCert, serial, ltime,
401d00756ccSwyllys 	    issuer, subject, altname,
402d00756ccSwyllys 	    alttype, altcrit, kubits,
403d00756ccSwyllys 	    kucrit, ekulist);
404d00756ccSwyllys 
405d00756ccSwyllys 	if (rv != KMF_OK)
406d00756ccSwyllys 		goto cleanup;
407d00756ccSwyllys 
408d00756ccSwyllys 	/*
409d00756ccSwyllys 	 * Find the signing key.
410d00756ccSwyllys 	 */
411d00756ccSwyllys 	numattr = 0;
412d00756ccSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
413d00756ccSwyllys 	    &kstype, sizeof (kstype));
414d00756ccSwyllys 	numattr++;
415d00756ccSwyllys 	if (kstype == KMF_KEYSTORE_NSS) {
416d00756ccSwyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
417d00756ccSwyllys 		    token, strlen(token));
418d00756ccSwyllys 		numattr++;
419d00756ccSwyllys 	}
420d00756ccSwyllys 
421d00756ccSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR, signkey,
422d00756ccSwyllys 	    strlen(signkey));
423d00756ccSwyllys 	numattr++;
424d00756ccSwyllys 
425d00756ccSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVATE_BOOL_ATTR,
426d00756ccSwyllys 	    &private_bool, sizeof (private_bool));
427d00756ccSwyllys 	numattr++;
428d00756ccSwyllys 
429d00756ccSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_BOOL_ATTR,
430d00756ccSwyllys 	    &token_bool, sizeof (token_bool));
431d00756ccSwyllys 	numattr++;
432d00756ccSwyllys 
433d00756ccSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
434d00756ccSwyllys 	    &keyclass, sizeof (keyclass));
435d00756ccSwyllys 	numattr++;
436d00756ccSwyllys 
437d00756ccSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
438d00756ccSwyllys 	    cred, sizeof (KMF_CREDENTIAL_ATTR));
439d00756ccSwyllys 	numattr++;
440d00756ccSwyllys 
441d00756ccSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
442d00756ccSwyllys 	    &keys, sizeof (keys));
443d00756ccSwyllys 	numattr++;
444d00756ccSwyllys 
445d00756ccSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
446d00756ccSwyllys 	    &casignkey, sizeof (casignkey));
447d00756ccSwyllys 	numattr++;
448d00756ccSwyllys 
449d00756ccSwyllys 	rv = kmf_find_key(handle, numattr, attrlist);
450d00756ccSwyllys 	if (rv != KMF_OK) {
451d00756ccSwyllys 		cryptoerror(LOG_STDERR,
452d00756ccSwyllys 		    gettext("Failed to find signing key\n"));
453d00756ccSwyllys 		goto cleanup;
454d00756ccSwyllys 	}
455d00756ccSwyllys 
456d00756ccSwyllys 	/*
457d00756ccSwyllys 	 * If we found the key, now we can sign the cert.
458d00756ccSwyllys 	 */
459d00756ccSwyllys 	rv = pk_sign_cert(handle, &signedCert, &casignkey, &outcert);
460d00756ccSwyllys 	if (rv != KMF_OK) {
461d00756ccSwyllys 		cryptoerror(LOG_STDERR, gettext(
462d00756ccSwyllys 		    "Error signing certificate.\n"));
463d00756ccSwyllys 		goto cleanup;
464d00756ccSwyllys 	}
465d00756ccSwyllys 
466d00756ccSwyllys 	/*
467d00756ccSwyllys 	 * Store it on the token if the user asked for it.
468d00756ccSwyllys 	 */
469d00756ccSwyllys 	if (store) {
470d00756ccSwyllys 		numattr = 0;
471d00756ccSwyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
472d00756ccSwyllys 		    &kstype, sizeof (kstype));
473d00756ccSwyllys 		numattr++;
474d00756ccSwyllys 
475d00756ccSwyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
476d00756ccSwyllys 		    &outcert, sizeof (KMF_DATA));
477d00756ccSwyllys 		numattr++;
478d00756ccSwyllys 
479d00756ccSwyllys 		if (outlabel != NULL) {
480d00756ccSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
481d00756ccSwyllys 			    KMF_CERT_LABEL_ATTR,
482d00756ccSwyllys 			    outlabel, strlen(outlabel));
483d00756ccSwyllys 			numattr++;
484d00756ccSwyllys 		}
485d00756ccSwyllys 
486d00756ccSwyllys 		if (kstype == KMF_KEYSTORE_NSS) {
487d00756ccSwyllys 			if (token != NULL)
488d00756ccSwyllys 				kmf_set_attr_at_index(attrlist, numattr,
489d00756ccSwyllys 				    KMF_TOKEN_LABEL_ATTR,
490d00756ccSwyllys 				    token, strlen(token));
491d00756ccSwyllys 			numattr++;
492d00756ccSwyllys 		}
493d00756ccSwyllys 
494d00756ccSwyllys 		rv = kmf_store_cert(handle, numattr, attrlist);
495d00756ccSwyllys 		if (rv != KMF_OK) {
496d00756ccSwyllys 			display_error(handle, rv,
497d00756ccSwyllys 			    gettext("Failed to store cert "
498d00756ccSwyllys 			    "on PKCS#11 token.\n"));
499d00756ccSwyllys 			rv = KMF_OK;
500d00756ccSwyllys 			/* Not fatal, we can still write it to a file. */
501d00756ccSwyllys 		}
502d00756ccSwyllys 	}
503d00756ccSwyllys 	rv = kmf_create_cert_file(&outcert, fmt, certfile);
504d00756ccSwyllys 
505d00756ccSwyllys cleanup:
506d00756ccSwyllys 	kmf_free_signed_csr(&csrdata);
507d00756ccSwyllys 	kmf_free_data(&outcert);
508d00756ccSwyllys 	kmf_free_kmf_key(handle, &casignkey);
509d00756ccSwyllys 
510d00756ccSwyllys 	return (rv);
511d00756ccSwyllys }
512d00756ccSwyllys 
513d00756ccSwyllys /*
514d00756ccSwyllys  * sign a CSR and generate an x509v3 certificate file.
515d00756ccSwyllys  */
516d00756ccSwyllys int
517d00756ccSwyllys pk_signcsr(int argc, char *argv[])
518d00756ccSwyllys {
519d00756ccSwyllys 	int			opt;
520d00756ccSwyllys 	extern int		optind_av;
521d00756ccSwyllys 	extern char		*optarg_av;
522d00756ccSwyllys 	char			*token_spec = NULL;
523d00756ccSwyllys 	char			*subject = NULL;
524d00756ccSwyllys 	char			*issuer = NULL;
525d00756ccSwyllys 	char			*dir = NULL;
526d00756ccSwyllys 	char			*prefix = NULL;
527d00756ccSwyllys 	char			*csrfile = NULL;
528d00756ccSwyllys 	char			*serstr = NULL;
529d00756ccSwyllys 	char			*ekustr = NULL;
530d00756ccSwyllys 	char			*kustr = NULL;
531d00756ccSwyllys 	char			*format = NULL;
532d00756ccSwyllys 	char			*storestr = NULL;
533d00756ccSwyllys 	char			*altname = NULL;
534d00756ccSwyllys 	char			*certfile = NULL;
535d00756ccSwyllys 	char			*lifetime = NULL;
536d00756ccSwyllys 	char			*signkey = NULL;
537d00756ccSwyllys 	char			*outlabel = NULL;
538d00756ccSwyllys 	uint32_t		ltime = 365 * 24 * 60 * 60; /* 1 Year */
539d00756ccSwyllys 	int			store = 0;
540d00756ccSwyllys 	uint16_t		kubits = 0;
541d00756ccSwyllys 	int			altcrit = 0, kucrit = 0;
542d00756ccSwyllys 	KMF_BIGINT		serial = { NULL, 0 };
543d00756ccSwyllys 	EKU_LIST		*ekulist = NULL;
544d00756ccSwyllys 	KMF_KEYSTORE_TYPE	kstype = 0;
545d00756ccSwyllys 	KMF_RETURN		rv = KMF_OK;
546d00756ccSwyllys 	KMF_HANDLE_T		kmfhandle = NULL;
547d00756ccSwyllys 	KMF_CREDENTIAL		tokencred = {NULL, 0};
548d00756ccSwyllys 	KMF_GENERALNAMECHOICES	alttype = 0;
549d00756ccSwyllys 	KMF_ENCODE_FORMAT	fmt = KMF_FORMAT_PEM;
550d00756ccSwyllys 
551d00756ccSwyllys 	/* Parse command line options.  Do NOT i18n/l10n. */
552d00756ccSwyllys 	while ((opt = getopt_av(argc, argv,
553d00756ccSwyllys 	    "k:(keystore)c:(csr)T:(token)d:(dir)"
554d00756ccSwyllys 	    "p:(prefix)S:(serial)s:(subject)a:(altname)"
555d00756ccSwyllys 	    "t:(store)F:(format)K:(keyusage)l:(signkey)"
556d00756ccSwyllys 	    "L:(lifetime)e:(eku)i:(issuer)"
557d00756ccSwyllys 	    "n:(outlabel)o:(outcert)")) != EOF) {
558d00756ccSwyllys 		if (EMPTYSTRING(optarg_av))
559d00756ccSwyllys 			return (PK_ERR_USAGE);
560d00756ccSwyllys 		switch (opt) {
561d00756ccSwyllys 			case 'k':
562d00756ccSwyllys 				if (kstype != 0)
563d00756ccSwyllys 					return (PK_ERR_USAGE);
564d00756ccSwyllys 				kstype = KS2Int(optarg_av);
565d00756ccSwyllys 				if (kstype == 0)
566d00756ccSwyllys 					return (PK_ERR_USAGE);
567d00756ccSwyllys 				break;
568d00756ccSwyllys 			case 't':
569d00756ccSwyllys 				if (storestr != NULL)
570d00756ccSwyllys 					return (PK_ERR_USAGE);
571d00756ccSwyllys 				storestr = optarg_av;
572d00756ccSwyllys 				store = yn_to_int(optarg_av);
573d00756ccSwyllys 				if (store == -1)
574d00756ccSwyllys 					return (PK_ERR_USAGE);
575d00756ccSwyllys 				break;
576d00756ccSwyllys 			case 'a':
577d00756ccSwyllys 				if (altname)
578d00756ccSwyllys 					return (PK_ERR_USAGE);
579d00756ccSwyllys 				altname = optarg_av;
580d00756ccSwyllys 				break;
581d00756ccSwyllys 			case 's':
582d00756ccSwyllys 				if (subject)
583d00756ccSwyllys 					return (PK_ERR_USAGE);
584d00756ccSwyllys 				subject = optarg_av;
585d00756ccSwyllys 				break;
586d00756ccSwyllys 			case 'i':
587d00756ccSwyllys 				if (issuer)
588d00756ccSwyllys 					return (PK_ERR_USAGE);
589d00756ccSwyllys 				issuer = optarg_av;
590d00756ccSwyllys 				break;
591d00756ccSwyllys 			case 'd':
592d00756ccSwyllys 				if (dir)
593d00756ccSwyllys 					return (PK_ERR_USAGE);
594d00756ccSwyllys 				dir = optarg_av;
595d00756ccSwyllys 				break;
596d00756ccSwyllys 			case 'p':
597d00756ccSwyllys 				if (prefix)
598d00756ccSwyllys 					return (PK_ERR_USAGE);
599d00756ccSwyllys 				prefix = optarg_av;
600d00756ccSwyllys 				break;
601d00756ccSwyllys 			case 'S':
602d00756ccSwyllys 				if (serstr != NULL)
603d00756ccSwyllys 					return (PK_ERR_USAGE);
604d00756ccSwyllys 				serstr = optarg_av;
605d00756ccSwyllys 				break;
606d00756ccSwyllys 			case 'c':
607d00756ccSwyllys 				if (csrfile)
608d00756ccSwyllys 					return (PK_ERR_USAGE);
609d00756ccSwyllys 				csrfile = optarg_av;
610d00756ccSwyllys 				break;
611d00756ccSwyllys 			case 'T':	/* token specifier */
612d00756ccSwyllys 				if (token_spec)
613d00756ccSwyllys 					return (PK_ERR_USAGE);
614d00756ccSwyllys 				token_spec = optarg_av;
615d00756ccSwyllys 				break;
616d00756ccSwyllys 			case 'l':	/* object with specific label */
617d00756ccSwyllys 				if (signkey)
618d00756ccSwyllys 					return (PK_ERR_USAGE);
619d00756ccSwyllys 				signkey = optarg_av;
620d00756ccSwyllys 				break;
621d00756ccSwyllys 			case 'e':
622d00756ccSwyllys 				if (ekustr != NULL)
623d00756ccSwyllys 					return (PK_ERR_USAGE);
624d00756ccSwyllys 				ekustr = optarg_av;
625d00756ccSwyllys 				break;
626d00756ccSwyllys 			case 'K':
627d00756ccSwyllys 				if (kustr != NULL)
628d00756ccSwyllys 					return (PK_ERR_USAGE);
629d00756ccSwyllys 				kustr = optarg_av;
630d00756ccSwyllys 				break;
631d00756ccSwyllys 			case 'F':
632d00756ccSwyllys 				if (format != NULL)
633d00756ccSwyllys 					return (PK_ERR_USAGE);
634d00756ccSwyllys 				format = optarg_av;
635d00756ccSwyllys 				break;
636d00756ccSwyllys 			case 'o':
637d00756ccSwyllys 				if (certfile != NULL)
638d00756ccSwyllys 					return (PK_ERR_USAGE);
639d00756ccSwyllys 				certfile = optarg_av;
640d00756ccSwyllys 				break;
641d00756ccSwyllys 			case 'L':
642d00756ccSwyllys 				if (lifetime != NULL)
643d00756ccSwyllys 					return (PK_ERR_USAGE);
644d00756ccSwyllys 				lifetime = optarg_av;
645d00756ccSwyllys 				break;
646d00756ccSwyllys 			case 'n':
647d00756ccSwyllys 				if (outlabel != NULL)
648d00756ccSwyllys 					return (PK_ERR_USAGE);
649d00756ccSwyllys 				outlabel = optarg_av;
650d00756ccSwyllys 				break;
651d00756ccSwyllys 			default:
652d00756ccSwyllys 				return (PK_ERR_USAGE);
653d00756ccSwyllys 		}
654d00756ccSwyllys 	}
655d00756ccSwyllys 	/* No additional args allowed. */
656d00756ccSwyllys 	argc -= optind_av;
657d00756ccSwyllys 	argv += optind_av;
658d00756ccSwyllys 	if (argc)
659d00756ccSwyllys 		return (PK_ERR_USAGE);
660d00756ccSwyllys 
661d00756ccSwyllys 	if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
662d00756ccSwyllys 		return (rv);
663d00756ccSwyllys 	}
664d00756ccSwyllys 
665d00756ccSwyllys 	/* Assume keystore = PKCS#11 if not specified. */
666d00756ccSwyllys 	if (kstype == 0)
667d00756ccSwyllys 		kstype = KMF_KEYSTORE_PK11TOKEN;
668d00756ccSwyllys 
669d00756ccSwyllys 	if (signkey == NULL) {
670d00756ccSwyllys 		(void) fprintf(stderr, gettext("The signing key label "
671d00756ccSwyllys 		    "or filename was not specified\n"));
672d00756ccSwyllys 		return (PK_ERR_USAGE);
673d00756ccSwyllys 	}
674d00756ccSwyllys 	if (csrfile == NULL) {
675d00756ccSwyllys 		(void) fprintf(stderr, gettext("The CSR filename was not"
676d00756ccSwyllys 		    " specified\n"));
677d00756ccSwyllys 		return (PK_ERR_USAGE);
678d00756ccSwyllys 	}
679d00756ccSwyllys 	if (certfile == NULL) {
680d00756ccSwyllys 		(void) fprintf(stderr, gettext("The output certificate file "
681d00756ccSwyllys 		    "was not specified\n"));
682d00756ccSwyllys 		return (PK_ERR_USAGE);
683d00756ccSwyllys 	}
684d00756ccSwyllys 	if (issuer == NULL) {
685d00756ccSwyllys 		(void) fprintf(stderr, gettext("The issuer DN "
686d00756ccSwyllys 		    "was not specified\n"));
687d00756ccSwyllys 		return (PK_ERR_USAGE);
688d00756ccSwyllys 	}
689d00756ccSwyllys 	if (lifetime != NULL) {
690d00756ccSwyllys 		if (Str2Lifetime(lifetime, &ltime) != 0) {
691d00756ccSwyllys 			cryptoerror(LOG_STDERR,
692d00756ccSwyllys 			    gettext("Error parsing lifetime string\n"));
693d00756ccSwyllys 			return (PK_ERR_USAGE);
694d00756ccSwyllys 		}
695d00756ccSwyllys 	}
696d00756ccSwyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) {
697d00756ccSwyllys 		token_spec = PK_DEFAULT_PK11TOKEN;
698d00756ccSwyllys 	} else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) {
699d00756ccSwyllys 		token_spec = DEFAULT_NSS_TOKEN;
700d00756ccSwyllys 	}
701d00756ccSwyllys 
702d00756ccSwyllys 	if (serstr != NULL) {
703d00756ccSwyllys 		uchar_t *bytes = NULL;
704d00756ccSwyllys 		size_t bytelen;
705d00756ccSwyllys 
706d00756ccSwyllys 		rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen);
707d00756ccSwyllys 		if (rv != KMF_OK || bytes == NULL) {
708d00756ccSwyllys 			(void) fprintf(stderr, gettext("Serial number "
709d00756ccSwyllys 			    "must be specified as a hex number "
710d00756ccSwyllys 			    "(ex: 0x0102030405ffeeddee)\n"));
711d00756ccSwyllys 			return (PK_ERR_USAGE);
712d00756ccSwyllys 		}
713d00756ccSwyllys 		serial.val = bytes;
714d00756ccSwyllys 		serial.len = bytelen;
715d00756ccSwyllys 	} else {
716d00756ccSwyllys 		(void) fprintf(stderr, gettext("The serial number was not"
717d00756ccSwyllys 		    " specified\n"));
718d00756ccSwyllys 		return (PK_ERR_USAGE);
719d00756ccSwyllys 	}
720d00756ccSwyllys 
721d00756ccSwyllys 	if ((kstype == KMF_KEYSTORE_PK11TOKEN ||
722d00756ccSwyllys 	    kstype == KMF_KEYSTORE_NSS)) {
723d00756ccSwyllys 		/* Need to get password for private key access */
724d00756ccSwyllys 		(void) get_token_password(kstype, token_spec,
725d00756ccSwyllys 		    &tokencred);
726d00756ccSwyllys 	}
727*448b8615Swyllys 	if (kustr != NULL) {
728*448b8615Swyllys 		rv = verify_keyusage(kustr, &kubits, &kucrit);
729*448b8615Swyllys 		if (rv != KMF_OK) {
730*448b8615Swyllys 			(void) fprintf(stderr, gettext("KeyUsage "
731*448b8615Swyllys 			    "must be specified as a comma-separated list. "
732*448b8615Swyllys 			    "See the man page for details.\n"));
733*448b8615Swyllys 			rv = PK_ERR_USAGE;
734*448b8615Swyllys 			goto end;
735*448b8615Swyllys 		}
736*448b8615Swyllys 	}
737d00756ccSwyllys 	if (ekustr != NULL) {
738d00756ccSwyllys 		rv = verify_ekunames(ekustr, &ekulist);
739d00756ccSwyllys 		if (rv != KMF_OK) {
740d00756ccSwyllys 			(void) fprintf(stderr, gettext("EKUs must "
741d00756ccSwyllys 			    "be specified as a comma-separated list. "
742d00756ccSwyllys 			    "See the man page for details.\n"));
743d00756ccSwyllys 			rv = PK_ERR_USAGE;
744d00756ccSwyllys 			goto end;
745d00756ccSwyllys 		}
746d00756ccSwyllys 	}
747d00756ccSwyllys 	if (altname != NULL) {
748d00756ccSwyllys 		char *p;
749d00756ccSwyllys 		rv = verify_altname(altname, &alttype, &altcrit);
750d00756ccSwyllys 		if (rv != KMF_OK) {
751d00756ccSwyllys 			(void) fprintf(stderr, gettext("Subject AltName "
752d00756ccSwyllys 			    "must be specified as a name=value pair. "
753d00756ccSwyllys 			    "See the man page for details.\n"));
754d00756ccSwyllys 			rv = PK_ERR_USAGE;
755d00756ccSwyllys 			goto end;
756d00756ccSwyllys 		}
757d00756ccSwyllys 		/* advance the altname past the '=' sign */
758d00756ccSwyllys 		p = strchr(altname, '=');
759d00756ccSwyllys 		if (p != NULL)
760d00756ccSwyllys 			altname = p + 1;
761d00756ccSwyllys 	}
762d00756ccSwyllys 	if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) {
763d00756ccSwyllys 		cryptoerror(LOG_STDERR,
764d00756ccSwyllys 		    gettext("Error parsing format string (%s).\n"),
765d00756ccSwyllys 		    format);
766d00756ccSwyllys 		return (PK_ERR_USAGE);
767d00756ccSwyllys 	}
768d00756ccSwyllys 
769d00756ccSwyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
770d00756ccSwyllys 		rv = pk_signcsr_pk11_nss(kmfhandle,
771d00756ccSwyllys 		    kstype, dir, prefix, token_spec, &tokencred,
772d00756ccSwyllys 		    signkey, csrfile, &serial, certfile, issuer, subject,
773d00756ccSwyllys 		    altname, alttype, altcrit, kubits, kucrit,
774d00756ccSwyllys 		    ekulist, ltime, fmt, store, outlabel);
775d00756ccSwyllys 
776d00756ccSwyllys 	} else if (kstype == KMF_KEYSTORE_NSS) {
777d00756ccSwyllys 		if (dir == NULL)
778d00756ccSwyllys 			dir = PK_DEFAULT_DIRECTORY;
779d00756ccSwyllys 
780d00756ccSwyllys 		rv = pk_signcsr_pk11_nss(kmfhandle,
781d00756ccSwyllys 		    kstype, dir, prefix, token_spec, &tokencred,
782d00756ccSwyllys 		    signkey, csrfile, &serial, certfile, issuer, subject,
783d00756ccSwyllys 		    altname, alttype, altcrit, kubits, kucrit,
784d00756ccSwyllys 		    ekulist, ltime, fmt, store, outlabel);
785d00756ccSwyllys 
786d00756ccSwyllys 	} else if (kstype == KMF_KEYSTORE_OPENSSL) {
787d00756ccSwyllys 		rv = pk_signcsr_files(kmfhandle,
788d00756ccSwyllys 		    signkey, csrfile, &serial, certfile, issuer, subject,
789d00756ccSwyllys 		    altname, alttype, altcrit, kubits, kucrit,
790d00756ccSwyllys 		    ekulist, ltime, fmt);
791d00756ccSwyllys 	}
792d00756ccSwyllys 
793d00756ccSwyllys end:
794d00756ccSwyllys 	if (rv != KMF_OK) {
795d00756ccSwyllys 		display_error(kmfhandle, rv,
796d00756ccSwyllys 		    gettext("Error listing objects"));
797d00756ccSwyllys 	}
798d00756ccSwyllys 
799d00756ccSwyllys 	if (serial.val != NULL)
800d00756ccSwyllys 		free(serial.val);
801d00756ccSwyllys 
802d00756ccSwyllys 	if (tokencred.cred != NULL)
803d00756ccSwyllys 		free(tokencred.cred);
804d00756ccSwyllys 
805d00756ccSwyllys 	free_eku_list(ekulist);
806d00756ccSwyllys 
807d00756ccSwyllys 	(void) kmf_finalize(kmfhandle);
808d00756ccSwyllys 	return (rv);
809d00756ccSwyllys }
810