xref: /onnv-gate/usr/src/cmd/cmd-crypto/pktool/export.c (revision 5051:cbbb7c8b40a9)
117Sdinak /*
217Sdinak  * CDDL HEADER START
317Sdinak  *
417Sdinak  * The contents of this file are subject to the terms of the
51837Sdinak  * Common Development and Distribution License (the "License").
61837Sdinak  * You may not use this file except in compliance with the License.
717Sdinak  *
817Sdinak  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
917Sdinak  * or http://www.opensolaris.org/os/licensing.
1017Sdinak  * See the License for the specific language governing permissions
1117Sdinak  * and limitations under the License.
1217Sdinak  *
1317Sdinak  * When distributing Covered Code, include this CDDL HEADER in each
1417Sdinak  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1517Sdinak  * If applicable, add the following below this CDDL HEADER, with the
1617Sdinak  * fields enclosed by brackets "[]" replaced with your own identifying
1717Sdinak  * information: Portions Copyright [yyyy] [name of copyright owner]
1817Sdinak  *
1917Sdinak  * CDDL HEADER END
203089Swyllys  *
213089Swyllys  *
22*5051Swyllys  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
2317Sdinak  * Use is subject to license terms.
2417Sdinak  */
2517Sdinak 
2617Sdinak #pragma ident	"%Z%%M%	%I%	%E% SMI"
2717Sdinak 
2817Sdinak /*
2917Sdinak  * This file implements the export operation for this tool.
3017Sdinak  * The basic flow of the process is to find the soft token,
3117Sdinak  * log into it, find the PKCS#11 objects in the soft token
3217Sdinak  * to be exported matching keys with their certificates, export
3317Sdinak  * them to the PKCS#12 file encrypting them with a file password
3417Sdinak  * if desired, and log out.
3517Sdinak  */
3617Sdinak 
3717Sdinak #include <stdio.h>
3817Sdinak #include <stdlib.h>
3917Sdinak #include <string.h>
4017Sdinak #include <errno.h>
413089Swyllys #include <fcntl.h>
4217Sdinak #include "common.h"
433089Swyllys 
443089Swyllys #include <kmfapi.h>
4517Sdinak 
463089Swyllys static KMF_RETURN
47*5051Swyllys pk_find_export_cert(KMF_HANDLE_T kmfhandle, KMF_ATTRIBUTE *attrlist,
48*5051Swyllys 	int numattr, KMF_X509_DER_CERT *cert)
4917Sdinak {
503089Swyllys 	KMF_RETURN rv = KMF_OK;
513089Swyllys 	uint32_t numcerts = 0;
5217Sdinak 
533089Swyllys 	numcerts = 0;
543089Swyllys 	(void) memset(cert, 0, sizeof (KMF_X509_DER_CERT));
55*5051Swyllys 
56*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
57*5051Swyllys 	    &numcerts, sizeof (uint32_t));
58*5051Swyllys 	numattr++;
59*5051Swyllys 
60*5051Swyllys 	rv = kmf_find_cert(kmfhandle, numattr, attrlist);
613089Swyllys 	if (rv != KMF_OK) {
623089Swyllys 		return (rv);
6317Sdinak 	}
643089Swyllys 	if (numcerts == 0) {
653089Swyllys 		cryptoerror(LOG_STDERR,
66*5051Swyllys 		    gettext("No matching certificates found."));
673089Swyllys 		return (KMF_ERR_CERT_NOT_FOUND);
6817Sdinak 
693089Swyllys 	} else if (numcerts == 1) {
70*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
71*5051Swyllys 		    KMF_X509_DER_CERT_ATTR, cert,
72*5051Swyllys 		    sizeof (KMF_X509_DER_CERT));
73*5051Swyllys 		numattr++;
74*5051Swyllys 		rv = kmf_find_cert(kmfhandle, numattr, attrlist);
7517Sdinak 
763089Swyllys 	} else if (numcerts > 1) {
773089Swyllys 		cryptoerror(LOG_STDERR,
78*5051Swyllys 		    gettext("%d certificates found, refine the "
79*5051Swyllys 		    "search parameters to eliminate ambiguity\n"),
80*5051Swyllys 		    numcerts);
813089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
823089Swyllys 	}
833089Swyllys 	return (rv);
843089Swyllys }
8517Sdinak 
863089Swyllys static KMF_RETURN
873089Swyllys pk_export_file_objects(KMF_HANDLE_T kmfhandle, int oclass,
883089Swyllys 	char *issuer, char *subject, KMF_BIGINT *serial,
893089Swyllys 	char *dir, char *infile, char *filename)
903089Swyllys {
913089Swyllys 	KMF_RETURN rv = KMF_OK;
923089Swyllys 	KMF_X509_DER_CERT kmfcert;
93*5051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
94*5051Swyllys 	int numattr = 0;
95*5051Swyllys 	KMF_ATTRIBUTE attrlist[16];
9617Sdinak 
973089Swyllys 	/* If searching for public objects or certificates, find certs now */
983089Swyllys 	if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) {
99*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
100*5051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
101*5051Swyllys 		    sizeof (kstype));
102*5051Swyllys 		numattr++;
103*5051Swyllys 
104*5051Swyllys 		if (issuer != NULL) {
105*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
106*5051Swyllys 			    KMF_ISSUER_NAME_ATTR, issuer,
107*5051Swyllys 			    strlen(issuer));
108*5051Swyllys 			numattr++;
109*5051Swyllys 		}
110*5051Swyllys 
111*5051Swyllys 		if (subject != NULL) {
112*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
113*5051Swyllys 			    KMF_SUBJECT_NAME_ATTR, subject,
114*5051Swyllys 			    strlen(subject));
115*5051Swyllys 			numattr++;
116*5051Swyllys 		}
117*5051Swyllys 
118*5051Swyllys 		if (serial != NULL) {
119*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
120*5051Swyllys 			    KMF_BIGINT_ATTR, serial,
121*5051Swyllys 			    sizeof (KMF_BIGINT));
122*5051Swyllys 			numattr++;
123*5051Swyllys 		}
12417Sdinak 
125*5051Swyllys 		if (dir != NULL) {
126*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
127*5051Swyllys 			    KMF_DIRPATH_ATTR, dir,
128*5051Swyllys 			    strlen(dir));
129*5051Swyllys 			numattr++;
130*5051Swyllys 		}
131*5051Swyllys 
132*5051Swyllys 		if (infile != NULL) {
133*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
134*5051Swyllys 			    KMF_CERT_FILENAME_ATTR, infile,
135*5051Swyllys 			    strlen(infile));
136*5051Swyllys 			numattr++;
137*5051Swyllys 		}
13817Sdinak 
139*5051Swyllys 		rv = pk_find_export_cert(kmfhandle, attrlist, numattr,
140*5051Swyllys 		    &kmfcert);
1413089Swyllys 		if (rv == KMF_OK) {
142*5051Swyllys 			kstype = KMF_KEYSTORE_OPENSSL;
143*5051Swyllys 			numattr = 0;
144*5051Swyllys 
145*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
146*5051Swyllys 			    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
147*5051Swyllys 			numattr++;
14817Sdinak 
149*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
150*5051Swyllys 			    KMF_CERT_DATA_ATTR, &kmfcert.certificate,
151*5051Swyllys 			    sizeof (KMF_DATA));
152*5051Swyllys 			numattr++;
153*5051Swyllys 
154*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
155*5051Swyllys 			    KMF_CERT_FILENAME_ATTR, filename,
156*5051Swyllys 			    strlen(filename));
157*5051Swyllys 			numattr++;
158*5051Swyllys 
159*5051Swyllys 			rv = kmf_store_cert(kmfhandle, numattr,
160*5051Swyllys 			    attrlist);
161*5051Swyllys 
162*5051Swyllys 			kmf_free_kmf_cert(kmfhandle, &kmfcert);
16317Sdinak 		}
16417Sdinak 	}
1653089Swyllys 	return (rv);
1663089Swyllys }
16717Sdinak 
1683089Swyllys static KMF_RETURN
1693089Swyllys pk_export_pk12_nss(KMF_HANDLE_T kmfhandle,
1703089Swyllys 	char *token_spec, char *dir, char *prefix,
1713089Swyllys 	char *certlabel, char *issuer, char *subject,
1723089Swyllys 	KMF_BIGINT *serial, KMF_CREDENTIAL *tokencred,
1733089Swyllys 	char *filename)
1743089Swyllys {
1753089Swyllys 	KMF_RETURN rv = KMF_OK;
176*5051Swyllys 	KMF_KEYSTORE_TYPE kstype;
177*5051Swyllys 	KMF_CREDENTIAL p12cred = { NULL, 0};
178*5051Swyllys 	KMF_ATTRIBUTE attrlist[16];
179*5051Swyllys 	int numattr = 0;
18017Sdinak 
1813089Swyllys 	rv = configure_nss(kmfhandle, dir, prefix);
1823089Swyllys 	if (rv != KMF_OK)
1833089Swyllys 		return (rv);
18417Sdinak 
1853089Swyllys 	if (token_spec == NULL)
1863089Swyllys 		token_spec = DEFAULT_NSS_TOKEN;
18717Sdinak 
188*5051Swyllys 	kstype = KMF_KEYSTORE_NSS;
189*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
190*5051Swyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
191*5051Swyllys 	numattr++;
192*5051Swyllys 
193*5051Swyllys 	if (certlabel != NULL) {
194*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
195*5051Swyllys 		    KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel));
196*5051Swyllys 		numattr++;
197*5051Swyllys 	}
198*5051Swyllys 
199*5051Swyllys 	if (issuer != NULL) {
200*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
201*5051Swyllys 		    KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer));
202*5051Swyllys 		numattr++;
203*5051Swyllys 	}
204*5051Swyllys 
205*5051Swyllys 	if (subject != NULL) {
206*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
207*5051Swyllys 		    KMF_SUBJECT_NAME_ATTR, subject, strlen(subject));
208*5051Swyllys 		numattr++;
209*5051Swyllys 	}
21017Sdinak 
211*5051Swyllys 	if (serial != NULL) {
212*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
213*5051Swyllys 		    KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT));
214*5051Swyllys 		numattr++;
215*5051Swyllys 	}
216*5051Swyllys 
217*5051Swyllys 	if (tokencred != NULL) {
218*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
219*5051Swyllys 		    KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL));
220*5051Swyllys 		numattr++;
221*5051Swyllys 	}
22217Sdinak 
223*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
224*5051Swyllys 	    token_spec, strlen(token_spec));
225*5051Swyllys 	numattr++;
226*5051Swyllys 
227*5051Swyllys 	(void) get_pk12_password(&p12cred);
228*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
229*5051Swyllys 	    KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL));
230*5051Swyllys 	numattr++;
231*5051Swyllys 
232*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
233*5051Swyllys 	    KMF_OUTPUT_FILENAME_ATTR, filename, strlen(filename));
234*5051Swyllys 	numattr++;
235*5051Swyllys 
236*5051Swyllys 	rv = kmf_export_pk12(kmfhandle, numattr, attrlist);
237*5051Swyllys 
238*5051Swyllys 	if (p12cred.cred)
239*5051Swyllys 		free(p12cred.cred);
24017Sdinak 
2413089Swyllys 	return (rv);
24217Sdinak }
24317Sdinak 
2443089Swyllys static KMF_RETURN
2453089Swyllys pk_export_pk12_files(KMF_HANDLE_T kmfhandle,
2463089Swyllys 	char *certfile, char *keyfile, char *dir,
2473089Swyllys 	char *outfile)
24817Sdinak {
2493089Swyllys 	KMF_RETURN rv;
250*5051Swyllys 	KMF_KEYSTORE_TYPE kstype;
251*5051Swyllys 	KMF_CREDENTIAL p12cred = { NULL, 0};
252*5051Swyllys 	KMF_ATTRIBUTE attrlist[16];
253*5051Swyllys 	int numattr = 0;
25417Sdinak 
255*5051Swyllys 	kstype = KMF_KEYSTORE_OPENSSL;
256*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
257*5051Swyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
258*5051Swyllys 	numattr++;
259*5051Swyllys 
260*5051Swyllys 	if (dir != NULL) {
261*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
262*5051Swyllys 		    KMF_DIRPATH_ATTR, dir, strlen(dir));
263*5051Swyllys 		numattr++;
264*5051Swyllys 	}
26517Sdinak 
266*5051Swyllys 	if (certfile != NULL) {
267*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
268*5051Swyllys 		    KMF_CERT_FILENAME_ATTR, certfile, strlen(certfile));
269*5051Swyllys 		numattr++;
270*5051Swyllys 	}
271*5051Swyllys 
272*5051Swyllys 	if (keyfile != NULL) {
273*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
274*5051Swyllys 		    KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile));
275*5051Swyllys 		numattr++;
276*5051Swyllys 	}
27717Sdinak 
278*5051Swyllys 	(void) get_pk12_password(&p12cred);
279*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
280*5051Swyllys 	    KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL));
281*5051Swyllys 	numattr++;
28217Sdinak 
283*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
284*5051Swyllys 	    KMF_OUTPUT_FILENAME_ATTR, outfile, strlen(outfile));
285*5051Swyllys 	numattr++;
28617Sdinak 
287*5051Swyllys 	rv = kmf_export_pk12(kmfhandle, numattr, attrlist);
288*5051Swyllys 
289*5051Swyllys 	if (p12cred.cred)
290*5051Swyllys 		free(p12cred.cred);
29117Sdinak 
2923089Swyllys 	return (rv);
29317Sdinak }
29417Sdinak 
2953089Swyllys static KMF_RETURN
2963089Swyllys pk_export_nss_objects(KMF_HANDLE_T kmfhandle, char *token_spec,
2973089Swyllys 	int oclass, char *certlabel, char *issuer, char *subject,
2983089Swyllys 	KMF_BIGINT *serial, KMF_ENCODE_FORMAT kfmt, char *dir,
2993089Swyllys 	char *prefix, char *filename)
30017Sdinak {
3013089Swyllys 	KMF_RETURN rv = KMF_OK;
3023089Swyllys 	KMF_X509_DER_CERT kmfcert;
303*5051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
304*5051Swyllys 	KMF_ATTRIBUTE attrlist[16];
305*5051Swyllys 	int numattr = 0;
3063089Swyllys 
3073089Swyllys 	rv = configure_nss(kmfhandle, dir, prefix);
3083089Swyllys 	if (rv != KMF_OK)
3093089Swyllys 		return (rv);
3103089Swyllys 
3113089Swyllys 	/* If searching for public objects or certificates, find certs now */
3123089Swyllys 	if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) {
313*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
314*5051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
315*5051Swyllys 		    sizeof (kstype));
316*5051Swyllys 		numattr++;
317*5051Swyllys 
318*5051Swyllys 		if (certlabel != NULL) {
319*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
320*5051Swyllys 			    KMF_CERT_LABEL_ATTR, certlabel,
321*5051Swyllys 			    strlen(certlabel));
322*5051Swyllys 			numattr++;
323*5051Swyllys 		}
32417Sdinak 
325*5051Swyllys 		if (issuer != NULL) {
326*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
327*5051Swyllys 			    KMF_ISSUER_NAME_ATTR, issuer,
328*5051Swyllys 			    strlen(issuer));
329*5051Swyllys 			numattr++;
330*5051Swyllys 		}
331*5051Swyllys 
332*5051Swyllys 		if (subject != NULL) {
333*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
334*5051Swyllys 			    KMF_SUBJECT_NAME_ATTR, subject,
335*5051Swyllys 			    strlen(subject));
336*5051Swyllys 			numattr++;
337*5051Swyllys 		}
338*5051Swyllys 
339*5051Swyllys 		if (serial != NULL) {
340*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
341*5051Swyllys 			    KMF_BIGINT_ATTR, serial,
342*5051Swyllys 			    sizeof (KMF_BIGINT));
343*5051Swyllys 			numattr++;
344*5051Swyllys 		}
34517Sdinak 
346*5051Swyllys 		if (token_spec != NULL) {
347*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
348*5051Swyllys 			    KMF_TOKEN_LABEL_ATTR, token_spec,
349*5051Swyllys 			    strlen(token_spec));
350*5051Swyllys 			numattr++;
351*5051Swyllys 		}
352*5051Swyllys 
353*5051Swyllys 		rv = pk_find_export_cert(kmfhandle, attrlist, numattr,
354*5051Swyllys 		    &kmfcert);
3553089Swyllys 		if (rv == KMF_OK) {
356*5051Swyllys 			kstype = KMF_KEYSTORE_OPENSSL;
357*5051Swyllys 			numattr = 0;
358*5051Swyllys 
359*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
360*5051Swyllys 			    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
361*5051Swyllys 			numattr++;
362*5051Swyllys 
363*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
364*5051Swyllys 			    KMF_CERT_DATA_ATTR, &kmfcert.certificate,
365*5051Swyllys 			    sizeof (KMF_DATA));
366*5051Swyllys 			numattr++;
36717Sdinak 
368*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
369*5051Swyllys 			    KMF_CERT_FILENAME_ATTR, filename,
370*5051Swyllys 			    strlen(filename));
371*5051Swyllys 			numattr++;
3723089Swyllys 
373*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
374*5051Swyllys 			    KMF_ENCODE_FORMAT_ATTR, &kfmt, sizeof (kfmt));
375*5051Swyllys 			numattr++;
376*5051Swyllys 
377*5051Swyllys 			rv = kmf_store_cert(kmfhandle, numattr, attrlist);
378*5051Swyllys 
379*5051Swyllys 			kmf_free_kmf_cert(kmfhandle, &kmfcert);
3803089Swyllys 		}
3813089Swyllys 	}
3823089Swyllys 	return (rv);
38317Sdinak }
38417Sdinak 
3853089Swyllys static KMF_RETURN
3863089Swyllys pk_export_pk12_pk11(KMF_HANDLE_T kmfhandle, char *token_spec,
3873089Swyllys 	char *certlabel, char *issuer, char *subject,
3883089Swyllys 	KMF_BIGINT *serial, KMF_CREDENTIAL *tokencred, char *filename)
38917Sdinak {
3903089Swyllys 	KMF_RETURN rv = KMF_OK;
391*5051Swyllys 	KMF_KEYSTORE_TYPE kstype;
392*5051Swyllys 	KMF_CREDENTIAL p12cred = { NULL, 0};
393*5051Swyllys 	KMF_ATTRIBUTE attrlist[16];
394*5051Swyllys 	int numattr = 0;
39517Sdinak 
3963089Swyllys 	rv = select_token(kmfhandle, token_spec, TRUE);
3973089Swyllys 	if (rv != KMF_OK) {
39817Sdinak 		return (rv);
39917Sdinak 	}
40017Sdinak 
401*5051Swyllys 	kstype = KMF_KEYSTORE_PK11TOKEN;
402*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
403*5051Swyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
404*5051Swyllys 	numattr++;
405*5051Swyllys 
406*5051Swyllys 	if (certlabel != NULL) {
407*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
408*5051Swyllys 		    KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel));
409*5051Swyllys 		numattr++;
410*5051Swyllys 	}
411*5051Swyllys 
412*5051Swyllys 	if (issuer != NULL) {
413*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
414*5051Swyllys 		    KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer));
415*5051Swyllys 		numattr++;
416*5051Swyllys 	}
417*5051Swyllys 
418*5051Swyllys 	if (subject != NULL) {
419*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
420*5051Swyllys 		    KMF_SUBJECT_NAME_ATTR, subject, strlen(subject));
421*5051Swyllys 		numattr++;
422*5051Swyllys 	}
423*5051Swyllys 
424*5051Swyllys 	if (serial != NULL) {
425*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
426*5051Swyllys 		    KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT));
427*5051Swyllys 		numattr++;
428*5051Swyllys 	}
429*5051Swyllys 
430*5051Swyllys 	if (tokencred != NULL) {
431*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
432*5051Swyllys 		    KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL));
433*5051Swyllys 		numattr++;
434*5051Swyllys 	}
435*5051Swyllys 
436*5051Swyllys 	(void) get_pk12_password(&p12cred);
437*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
438*5051Swyllys 	    KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL));
439*5051Swyllys 	numattr++;
440*5051Swyllys 
441*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
442*5051Swyllys 	    KMF_OUTPUT_FILENAME_ATTR, filename, strlen(filename));
443*5051Swyllys 	numattr++;
444*5051Swyllys 
445*5051Swyllys 	rv = kmf_export_pk12(kmfhandle, numattr, attrlist);
446*5051Swyllys 
447*5051Swyllys 	if (p12cred.cred)
448*5051Swyllys 		free(p12cred.cred);
449*5051Swyllys 
450*5051Swyllys 	return (rv);
451*5051Swyllys }
452*5051Swyllys 
453*5051Swyllys static KMF_RETURN
454*5051Swyllys pk_export_pk11_keys(KMF_HANDLE_T kmfhandle, char *token,
455*5051Swyllys 	KMF_CREDENTIAL *cred, KMF_ENCODE_FORMAT format,
456*5051Swyllys 	char *label, char *filename)
457*5051Swyllys {
458*5051Swyllys 	KMF_RETURN rv = KMF_OK;
459*5051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
460*5051Swyllys 	int numattr = 0;
461*5051Swyllys 	uint32_t numkeys = 1;
462*5051Swyllys 	KMF_ATTRIBUTE attrlist[16];
463*5051Swyllys 	KMF_KEY_HANDLE key;
464*5051Swyllys 	KMF_KEY_CLASS keyclass = KMF_SYMMETRIC;
465*5051Swyllys 	boolean_t is_token = B_TRUE;
466*5051Swyllys 
467*5051Swyllys 	if (EMPTYSTRING(label)) {
468*5051Swyllys 		cryptoerror(LOG_STDERR, gettext("A label "
469*5051Swyllys 		    "must be specified to export a key."));
470*5051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
471*5051Swyllys 	}
472*5051Swyllys 
473*5051Swyllys 	rv = select_token(kmfhandle, token, TRUE);
474*5051Swyllys 	if (rv != KMF_OK) {
475*5051Swyllys 		return (rv);
476*5051Swyllys 	}
477*5051Swyllys 
478*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
479*5051Swyllys 	    &kstype, sizeof (kstype));
480*5051Swyllys 	numattr++;
48117Sdinak 
482*5051Swyllys 	if (cred != NULL) {
483*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
484*5051Swyllys 		    cred, sizeof (KMF_CREDENTIAL));
485*5051Swyllys 		numattr++;
486*5051Swyllys 	}
487*5051Swyllys 
488*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR,
489*5051Swyllys 	    label, strlen(label));
490*5051Swyllys 	numattr++;
491*5051Swyllys 
492*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
493*5051Swyllys 	    &numkeys, sizeof (numkeys));
494*5051Swyllys 	numattr++;
495*5051Swyllys 
496*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
497*5051Swyllys 	    &key, sizeof (key));
498*5051Swyllys 	numattr++;
499*5051Swyllys 
500*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_BOOL_ATTR,
501*5051Swyllys 	    &is_token, sizeof (is_token));
502*5051Swyllys 	numattr++;
503*5051Swyllys 
504*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR,
505*5051Swyllys 	    &format, sizeof (format));
506*5051Swyllys 	numattr++;
507*5051Swyllys 
508*5051Swyllys 	rv = kmf_find_key(kmfhandle, numattr, attrlist);
509*5051Swyllys 	if (rv == KMF_OK && key.keyclass == KMF_SYMMETRIC) {
510*5051Swyllys 		KMF_RAW_SYM_KEY rkey;
511*5051Swyllys 
512*5051Swyllys 		(void) memset(&rkey, 0, sizeof (KMF_RAW_SYM_KEY));
513*5051Swyllys 		rv = kmf_get_sym_key_value(kmfhandle, &key, &rkey);
514*5051Swyllys 		if (rv == KMF_OK) {
515*5051Swyllys 			int fd, n, total = 0;
51617Sdinak 
517*5051Swyllys 			fd = open(filename, O_CREAT | O_RDWR |O_TRUNC, 0600);
518*5051Swyllys 			if (fd == -1) {
519*5051Swyllys 				rv = KMF_ERR_OPEN_FILE;
520*5051Swyllys 				goto done;
521*5051Swyllys 			}
522*5051Swyllys 			do {
523*5051Swyllys 				n = write(fd, rkey.keydata.val + total,
524*5051Swyllys 				    rkey.keydata.len - total);
525*5051Swyllys 				if (n < 0) {
526*5051Swyllys 					if (errno == EINTR)
527*5051Swyllys 						continue;
528*5051Swyllys 					close(fd);
529*5051Swyllys 					rv = KMF_ERR_WRITE_FILE;
530*5051Swyllys 					goto done;
531*5051Swyllys 				}
532*5051Swyllys 				total += n;
53317Sdinak 
534*5051Swyllys 			} while (total < rkey.keydata.len);
535*5051Swyllys 			close(fd);
536*5051Swyllys 		}
537*5051Swyllys done:
538*5051Swyllys 		kmf_free_bigint(&rkey.keydata);
539*5051Swyllys 		kmf_free_kmf_key(kmfhandle, &key);
540*5051Swyllys 	} else if (rv == KMF_OK) {
541*5051Swyllys 		KMF_KEYSTORE_TYPE sslks = KMF_KEYSTORE_OPENSSL;
542*5051Swyllys 		printf(gettext("Found %d asymmetric keys\n"), numkeys);
543*5051Swyllys 
544*5051Swyllys 		numattr = 0;
545*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
546*5051Swyllys 		    &sslks, sizeof (sslks));
547*5051Swyllys 		numattr++;
548*5051Swyllys 
549*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR,
550*5051Swyllys 		    key.keyp, sizeof (KMF_RAW_KEY_DATA));
551*5051Swyllys 		numattr++;
552*5051Swyllys 
553*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR,
554*5051Swyllys 		    &format, sizeof (format));
555*5051Swyllys 		numattr++;
556*5051Swyllys 
557*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR,
558*5051Swyllys 		    filename, strlen(filename));
559*5051Swyllys 		numattr++;
560*5051Swyllys 
561*5051Swyllys 		rv = kmf_store_key(kmfhandle, numattr, attrlist);
562*5051Swyllys 		kmf_free_kmf_key(kmfhandle, &key);
563*5051Swyllys 	}
56417Sdinak 
5653089Swyllys 	return (rv);
56617Sdinak }
56717Sdinak 
5683089Swyllys static KMF_RETURN
5693089Swyllys pk_export_pk11_objects(KMF_HANDLE_T kmfhandle, char *token_spec,
5703089Swyllys 	char *certlabel, char *issuer, char *subject,
5713089Swyllys 	KMF_BIGINT *serial, KMF_ENCODE_FORMAT kfmt,
5723089Swyllys 	char *filename)
57317Sdinak {
5743089Swyllys 	KMF_RETURN rv = KMF_OK;
5753089Swyllys 	KMF_X509_DER_CERT kmfcert;
576*5051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
577*5051Swyllys 	int numattr = 0;
578*5051Swyllys 	KMF_ATTRIBUTE attrlist[16];
57917Sdinak 
5803089Swyllys 	rv = select_token(kmfhandle, token_spec, TRUE);
58117Sdinak 
5823089Swyllys 	if (rv != KMF_OK) {
58317Sdinak 		return (rv);
58417Sdinak 	}
58517Sdinak 
586*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
587*5051Swyllys 	    &kstype, sizeof (kstype));
588*5051Swyllys 	numattr++;
589*5051Swyllys 
590*5051Swyllys 	if (certlabel != NULL) {
591*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
592*5051Swyllys 		    KMF_CERT_LABEL_ATTR, certlabel,
593*5051Swyllys 		    strlen(certlabel));
594*5051Swyllys 		numattr++;
595*5051Swyllys 	}
59617Sdinak 
597*5051Swyllys 	if (issuer != NULL) {
598*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
599*5051Swyllys 		    KMF_ISSUER_NAME_ATTR, issuer,
600*5051Swyllys 		    strlen(issuer));
601*5051Swyllys 		numattr++;
602*5051Swyllys 	}
603*5051Swyllys 
604*5051Swyllys 	if (subject != NULL) {
605*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
606*5051Swyllys 		    KMF_SUBJECT_NAME_ATTR, subject,
607*5051Swyllys 		    strlen(subject));
608*5051Swyllys 		numattr++;
609*5051Swyllys 	}
610*5051Swyllys 
611*5051Swyllys 	if (serial != NULL) {
612*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
613*5051Swyllys 		    KMF_BIGINT_ATTR, serial,
614*5051Swyllys 		    sizeof (KMF_BIGINT));
615*5051Swyllys 		numattr++;
616*5051Swyllys 	}
617*5051Swyllys 
618*5051Swyllys 	rv = pk_find_export_cert(kmfhandle, attrlist, numattr, &kmfcert);
61917Sdinak 
6203089Swyllys 	if (rv == KMF_OK) {
621*5051Swyllys 		kstype = KMF_KEYSTORE_OPENSSL;
622*5051Swyllys 		numattr = 0;
623*5051Swyllys 
624*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
625*5051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
626*5051Swyllys 		numattr++;
627*5051Swyllys 
628*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
629*5051Swyllys 		    KMF_CERT_DATA_ATTR, &kmfcert.certificate,
630*5051Swyllys 		    sizeof (KMF_DATA));
631*5051Swyllys 		numattr++;
63217Sdinak 
633*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
634*5051Swyllys 		    KMF_CERT_FILENAME_ATTR, filename, strlen(filename));
635*5051Swyllys 		numattr++;
63617Sdinak 
637*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
638*5051Swyllys 		    KMF_ENCODE_FORMAT_ATTR, &kfmt, sizeof (kfmt));
639*5051Swyllys 		numattr++;
640*5051Swyllys 
641*5051Swyllys 		rv = kmf_store_cert(kmfhandle, numattr, attrlist);
642*5051Swyllys 
643*5051Swyllys 		kmf_free_kmf_cert(kmfhandle, &kmfcert);
64417Sdinak 	}
6453089Swyllys 	return (rv);
64617Sdinak }
64717Sdinak 
64817Sdinak /*
6493089Swyllys  * Export objects from one keystore to a file.
65017Sdinak  */
65117Sdinak int
65217Sdinak pk_export(int argc, char *argv[])
65317Sdinak {
654864Sdinak 	int		opt;
655864Sdinak 	extern int	optind_av;
656864Sdinak 	extern char	*optarg_av;
657864Sdinak 	char		*token_spec = NULL;
65817Sdinak 	char		*filename = NULL;
6593089Swyllys 	char		*dir = NULL;
6603089Swyllys 	char		*prefix = NULL;
6613089Swyllys 	char		*certlabel = NULL;
6623089Swyllys 	char		*subject = NULL;
6633089Swyllys 	char		*issuer = NULL;
6643089Swyllys 	char		*infile = NULL;
6653089Swyllys 	char		*keyfile = NULL;
6663089Swyllys 	char		*certfile = NULL;
6673089Swyllys 	char		*serstr = NULL;
6683089Swyllys 	KMF_KEYSTORE_TYPE	kstype = 0;
6693089Swyllys 	KMF_ENCODE_FORMAT	kfmt = KMF_FORMAT_PKCS12;
6703089Swyllys 	KMF_RETURN		rv = KMF_OK;
6713089Swyllys 	int		oclass = PK_CERT_OBJ;
6723089Swyllys 	KMF_BIGINT	serial = { NULL, 0 };
6733089Swyllys 	KMF_HANDLE_T	kmfhandle = NULL;
6743089Swyllys 	KMF_CREDENTIAL	tokencred = {NULL, 0};
67517Sdinak 
676864Sdinak 	/* Parse command line options.  Do NOT i18n/l10n. */
6773089Swyllys 	while ((opt = getopt_av(argc, argv,
678*5051Swyllys 	    "k:(keystore)y:(objtype)T:(token)"
679*5051Swyllys 	    "d:(dir)p:(prefix)"
680*5051Swyllys 	    "l:(label)n:(nickname)s:(subject)"
681*5051Swyllys 	    "i:(issuer)S:(serial)"
682*5051Swyllys 	    "K:(keyfile)c:(certfile)"
683*5051Swyllys 	    "F:(outformat)"
684*5051Swyllys 	    "I:(infile)o:(outfile)")) != EOF) {
6853089Swyllys 		if (EMPTYSTRING(optarg_av))
6863089Swyllys 			return (PK_ERR_USAGE);
687864Sdinak 		switch (opt) {
6883089Swyllys 		case 'k':
6893089Swyllys 			kstype = KS2Int(optarg_av);
6903089Swyllys 			if (kstype == 0)
6913089Swyllys 				return (PK_ERR_USAGE);
6923089Swyllys 			break;
6933089Swyllys 		case 'y':
6943089Swyllys 			oclass = OT2Int(optarg_av);
6953089Swyllys 			if (oclass == -1)
6963089Swyllys 				return (PK_ERR_USAGE);
6973089Swyllys 			break;
698864Sdinak 		case 'T':	/* token specifier */
699864Sdinak 			if (token_spec)
700864Sdinak 				return (PK_ERR_USAGE);
701864Sdinak 			token_spec = optarg_av;
702864Sdinak 			break;
7033089Swyllys 		case 'd':
7043089Swyllys 			if (dir)
7053089Swyllys 				return (PK_ERR_USAGE);
7063089Swyllys 			dir = optarg_av;
7073089Swyllys 			break;
7083089Swyllys 		case 'p':
7093089Swyllys 			if (prefix)
7103089Swyllys 				return (PK_ERR_USAGE);
7113089Swyllys 			prefix = optarg_av;
7123089Swyllys 			break;
7133089Swyllys 		case 'n':
7143089Swyllys 		case 'l':
7153089Swyllys 			if (certlabel)
7163089Swyllys 				return (PK_ERR_USAGE);
7173089Swyllys 			certlabel = optarg_av;
7183089Swyllys 			break;
7193089Swyllys 		case 's':
7203089Swyllys 			if (subject)
7213089Swyllys 				return (PK_ERR_USAGE);
7223089Swyllys 			subject = optarg_av;
7233089Swyllys 			break;
7243089Swyllys 		case 'i':
7253089Swyllys 			if (issuer)
7263089Swyllys 				return (PK_ERR_USAGE);
7273089Swyllys 			issuer = optarg_av;
7283089Swyllys 			break;
7293089Swyllys 		case 'S':
7303089Swyllys 			serstr = optarg_av;
7313089Swyllys 			break;
7323089Swyllys 		case 'F':
7333089Swyllys 			kfmt = Str2Format(optarg_av);
7343089Swyllys 			if (kfmt == KMF_FORMAT_UNDEF)
7353089Swyllys 				return (PK_ERR_USAGE);
7363089Swyllys 			break;
7373089Swyllys 		case 'I':	/* output file name */
7383089Swyllys 			if (infile)
7393089Swyllys 				return (PK_ERR_USAGE);
7403089Swyllys 			infile = optarg_av;
7413089Swyllys 			break;
742864Sdinak 		case 'o':	/* output file name */
743864Sdinak 			if (filename)
744864Sdinak 				return (PK_ERR_USAGE);
745864Sdinak 			filename = optarg_av;
746864Sdinak 			break;
7473089Swyllys 		case 'c':	/* input cert file name */
7483089Swyllys 			if (certfile)
7493089Swyllys 				return (PK_ERR_USAGE);
7503089Swyllys 			certfile = optarg_av;
7513089Swyllys 			break;
7523089Swyllys 		case 'K':	/* input key file name */
7533089Swyllys 			if (keyfile)
7543089Swyllys 				return (PK_ERR_USAGE);
7553089Swyllys 			keyfile = optarg_av;
7563089Swyllys 			break;
757864Sdinak 		default:
758864Sdinak 			return (PK_ERR_USAGE);
759864Sdinak 			break;
760864Sdinak 		}
761864Sdinak 	}
76217Sdinak 
7633089Swyllys 	/* Assume keystore = PKCS#11 if not specified */
7643089Swyllys 	if (kstype == 0)
7653089Swyllys 		kstype = KMF_KEYSTORE_PK11TOKEN;
766864Sdinak 
767864Sdinak 	/* Filename arg is required. */
7683089Swyllys 	if (EMPTYSTRING(filename)) {
7693089Swyllys 		cryptoerror(LOG_STDERR, gettext("You must specify "
770*5051Swyllys 		    "an 'outfile' parameter when exporting.\n"));
77117Sdinak 		return (PK_ERR_USAGE);
7723089Swyllys 	}
77317Sdinak 
774864Sdinak 	/* No additional args allowed. */
775864Sdinak 	argc -= optind_av;
776864Sdinak 	argv += optind_av;
777864Sdinak 	if (argc)
778864Sdinak 		return (PK_ERR_USAGE);
7793089Swyllys 
7803089Swyllys 	/* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
7813089Swyllys 	if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
782*5051Swyllys 	    kstype != KMF_KEYSTORE_PK11TOKEN) {
7833089Swyllys 
7843089Swyllys 		(void) fprintf(stderr, gettext("The objtype parameter "
785*5051Swyllys 		    "is only relevant if keystore=pkcs11\n"));
7863089Swyllys 		return (PK_ERR_USAGE);
7873089Swyllys 	}
7883089Swyllys 
7893089Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec))
7903089Swyllys 		token_spec = PK_DEFAULT_PK11TOKEN;
7913089Swyllys 	else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec))
7923089Swyllys 		token_spec = DEFAULT_NSS_TOKEN;
7933089Swyllys 
7943089Swyllys 	if (kstype == KMF_KEYSTORE_OPENSSL) {
7953089Swyllys 		if (kfmt != KMF_FORMAT_PKCS12) {
7963089Swyllys 			cryptoerror(LOG_STDERR, gettext("PKCS12 "
797*5051Swyllys 			    "is the only export format "
798*5051Swyllys 			    "supported for the 'file' "
799*5051Swyllys 			    "keystore.\n"));
8003089Swyllys 			return (PK_ERR_USAGE);
8013089Swyllys 		}
8023089Swyllys 		if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) {
8033089Swyllys 			cryptoerror(LOG_STDERR, gettext("A cert file"
804*5051Swyllys 			    "and a key file must be specified "
805*5051Swyllys 			    "when exporting to PKCS12 from the "
806*5051Swyllys 			    "'file' keystore.\n"));
8073089Swyllys 			return (PK_ERR_USAGE);
8083089Swyllys 		}
8093089Swyllys 	}
81017Sdinak 
81117Sdinak 	/* Check if the file exists and might be overwritten. */
81217Sdinak 	if (access(filename, F_OK) == 0) {
8133089Swyllys 		cryptoerror(LOG_STDERR,
814*5051Swyllys 		    gettext("Warning: file \"%s\" exists, "
815*5051Swyllys 		    "will be overwritten."), filename);
81617Sdinak 		if (yesno(gettext("Continue with export? "),
81717Sdinak 		    gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) {
81817Sdinak 			return (0);
81917Sdinak 		}
8203089Swyllys 	} else {
8213089Swyllys 		rv = verify_file(filename);
8223089Swyllys 		if (rv != KMF_OK) {
8233089Swyllys 			cryptoerror(LOG_STDERR, gettext("The file (%s) "
824*5051Swyllys 			    "cannot be created.\n"), filename);
8253089Swyllys 			return (PK_ERR_USAGE);
8263089Swyllys 		}
82717Sdinak 	}
82817Sdinak 
8293089Swyllys 	if (serstr != NULL) {
8303089Swyllys 		uchar_t *bytes = NULL;
8313089Swyllys 		size_t bytelen;
83217Sdinak 
833*5051Swyllys 		rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen);
8343089Swyllys 		if (rv != KMF_OK || bytes == NULL) {
8353089Swyllys 			(void) fprintf(stderr, gettext("serial number "
836*5051Swyllys 			    "must be specified as a hex number "
837*5051Swyllys 			    "(ex: 0x0102030405ffeeddee)\n"));
8383089Swyllys 			return (PK_ERR_USAGE);
8393089Swyllys 		}
8403089Swyllys 		serial.val = bytes;
8413089Swyllys 		serial.len = bytelen;
84217Sdinak 	}
84317Sdinak 
8443089Swyllys 	if ((kstype == KMF_KEYSTORE_PK11TOKEN ||
845*5051Swyllys 	    kstype == KMF_KEYSTORE_NSS) &&
846*5051Swyllys 	    (oclass & (PK_KEY_OBJ | PK_PRIVATE_OBJ) ||
847*5051Swyllys 	    kfmt == KMF_FORMAT_PKCS12)) {
8483089Swyllys 			(void) get_token_password(kstype, token_spec,
849*5051Swyllys 			    &tokencred);
85017Sdinak 	}
85117Sdinak 
852*5051Swyllys 	if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
8533089Swyllys 		cryptoerror(LOG_STDERR, gettext("Error initializing "
854*5051Swyllys 		    "KMF: 0x%02x\n"), rv);
8553089Swyllys 		return (rv);
85617Sdinak 	}
85717Sdinak 
8583089Swyllys 	switch (kstype) {
8593089Swyllys 		case KMF_KEYSTORE_PK11TOKEN:
8603089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
861*5051Swyllys 				rv = pk_export_pk12_pk11(kmfhandle,
862*5051Swyllys 				    token_spec, certlabel,
863*5051Swyllys 				    issuer, subject,
864*5051Swyllys 				    &serial, &tokencred,
865*5051Swyllys 				    filename);
866*5051Swyllys 			else if ((oclass & PK_KEY_OBJ) ||
867*5051Swyllys 			    kfmt == KMF_FORMAT_RAWKEY)
868*5051Swyllys 				rv = pk_export_pk11_keys(kmfhandle,
869*5051Swyllys 				    token_spec, &tokencred, kfmt,
870*5051Swyllys 				    certlabel, filename);
8713089Swyllys 			else
8723089Swyllys 				rv = pk_export_pk11_objects(kmfhandle,
873*5051Swyllys 				    token_spec, certlabel,
874*5051Swyllys 				    issuer, subject, &serial, kfmt,
875*5051Swyllys 				    filename);
8763089Swyllys 			break;
8773089Swyllys 		case KMF_KEYSTORE_NSS:
8783089Swyllys 			if (dir == NULL)
8793089Swyllys 				dir = PK_DEFAULT_DIRECTORY;
8803089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
8813089Swyllys 				rv = pk_export_pk12_nss(kmfhandle,
882*5051Swyllys 				    token_spec, dir, prefix,
883*5051Swyllys 				    certlabel, issuer,
884*5051Swyllys 				    subject, &serial,
885*5051Swyllys 				    &tokencred, filename);
8863089Swyllys 			else
8873089Swyllys 				rv = pk_export_nss_objects(kmfhandle,
888*5051Swyllys 				    token_spec,
889*5051Swyllys 				    oclass, certlabel, issuer, subject,
890*5051Swyllys 				    &serial, kfmt, dir, prefix, filename);
8913089Swyllys 			break;
8923089Swyllys 		case KMF_KEYSTORE_OPENSSL:
8933089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
8943089Swyllys 				rv = pk_export_pk12_files(kmfhandle,
895*5051Swyllys 				    certfile, keyfile, dir,
896*5051Swyllys 				    filename);
8973089Swyllys 			else
8983089Swyllys 				rv = pk_export_file_objects(kmfhandle, oclass,
899*5051Swyllys 				    issuer, subject, &serial,
900*5051Swyllys 				    dir, infile, filename);
9013089Swyllys 			break;
9023089Swyllys 		default:
9033089Swyllys 			rv = PK_ERR_USAGE;
9043089Swyllys 			break;
90517Sdinak 	}
90617Sdinak 
9073089Swyllys 	if (rv != KMF_OK) {
9083089Swyllys 		display_error(kmfhandle, rv,
909*5051Swyllys 		    gettext("Error exporting objects"));
9103089Swyllys 	}
91117Sdinak 
9123089Swyllys 	if (serial.val != NULL)
9133089Swyllys 		free(serial.val);
91417Sdinak 
915*5051Swyllys 	(void) kmf_finalize(kmfhandle);
9163089Swyllys 
9173089Swyllys 	return (rv);
91817Sdinak }
919