xref: /onnv-gate/usr/src/cmd/cmd-crypto/pktool/export.c (revision 3089:8ddeb2ace8aa)
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
20*3089Swyllys  *
21*3089Swyllys  *
221837Sdinak  * Copyright 2006 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>
41*3089Swyllys #include <fcntl.h>
4217Sdinak #include "common.h"
43*3089Swyllys 
44*3089Swyllys #include <kmfapi.h>
4517Sdinak 
46*3089Swyllys static KMF_RETURN
47*3089Swyllys pk_find_export_cert(KMF_HANDLE_T kmfhandle, KMF_FINDCERT_PARAMS *parms,
48*3089Swyllys 	KMF_X509_DER_CERT *cert)
4917Sdinak {
50*3089Swyllys 	KMF_RETURN rv = KMF_OK;
51*3089Swyllys 	uint32_t numcerts = 0;
5217Sdinak 
53*3089Swyllys 	numcerts = 0;
54*3089Swyllys 	(void) memset(cert, 0, sizeof (KMF_X509_DER_CERT));
55*3089Swyllys 	rv = KMF_FindCert(kmfhandle, parms, NULL, &numcerts);
56*3089Swyllys 	if (rv != KMF_OK) {
57*3089Swyllys 		return (rv);
5817Sdinak 	}
59*3089Swyllys 	if (numcerts == 0) {
60*3089Swyllys 		cryptoerror(LOG_STDERR,
61*3089Swyllys 			gettext("No matching certificates found."));
62*3089Swyllys 		return (KMF_ERR_CERT_NOT_FOUND);
6317Sdinak 
64*3089Swyllys 	} else if (numcerts == 1) {
65*3089Swyllys 		rv = KMF_FindCert(kmfhandle, parms, cert, &numcerts);
6617Sdinak 
67*3089Swyllys 	} else if (numcerts > 1) {
68*3089Swyllys 		cryptoerror(LOG_STDERR,
69*3089Swyllys 			gettext("%d certificates found, refine the "
70*3089Swyllys 			"search parameters to eliminate ambiguity\n"),
71*3089Swyllys 			numcerts);
72*3089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
73*3089Swyllys 	}
74*3089Swyllys 	return (rv);
75*3089Swyllys }
7617Sdinak 
77*3089Swyllys static KMF_RETURN
78*3089Swyllys pk_export_file_objects(KMF_HANDLE_T kmfhandle, int oclass,
79*3089Swyllys 	char *issuer, char *subject, KMF_BIGINT *serial,
80*3089Swyllys 	KMF_ENCODE_FORMAT ofmt,
81*3089Swyllys 	char *dir, char *infile, char *filename)
82*3089Swyllys {
83*3089Swyllys 	KMF_RETURN rv = KMF_OK;
84*3089Swyllys 	KMF_STORECERT_PARAMS scparms;
85*3089Swyllys 	KMF_X509_DER_CERT kmfcert;
8617Sdinak 
87*3089Swyllys 	/* If searching for public objects or certificates, find certs now */
88*3089Swyllys 	if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) {
89*3089Swyllys 		KMF_FINDCERT_PARAMS fcargs;
9017Sdinak 
91*3089Swyllys 		(void) memset(&fcargs, 0, sizeof (fcargs));
92*3089Swyllys 		fcargs.kstype = KMF_KEYSTORE_OPENSSL;
93*3089Swyllys 		fcargs.certLabel = NULL;
94*3089Swyllys 		fcargs.issuer = issuer;
95*3089Swyllys 		fcargs.subject = subject;
96*3089Swyllys 		fcargs.serial = serial;
97*3089Swyllys 		fcargs.sslparms.dirpath = dir;
98*3089Swyllys 		fcargs.sslparms.certfile = infile;
99*3089Swyllys 		fcargs.sslparms.format = ofmt;
10017Sdinak 
101*3089Swyllys 		rv = pk_find_export_cert(kmfhandle, &fcargs, &kmfcert);
102*3089Swyllys 		if (rv == KMF_OK) {
103*3089Swyllys 			(void) memset(&scparms, 0, sizeof (scparms));
104*3089Swyllys 			scparms.kstype = KMF_KEYSTORE_OPENSSL;
105*3089Swyllys 			scparms.sslparms.certfile = filename;
106*3089Swyllys 			rv = KMF_StoreCert(kmfhandle, &scparms,
107*3089Swyllys 				&kmfcert.certificate);
10817Sdinak 
109*3089Swyllys 			KMF_FreeKMFCert(kmfhandle, &kmfcert);
11017Sdinak 		}
11117Sdinak 	}
112*3089Swyllys 	return (rv);
113*3089Swyllys }
11417Sdinak 
115*3089Swyllys static KMF_RETURN
116*3089Swyllys pk_export_pk12_nss(KMF_HANDLE_T kmfhandle,
117*3089Swyllys 	char *token_spec, char *dir, char *prefix,
118*3089Swyllys 	char *certlabel, char *issuer, char *subject,
119*3089Swyllys 	KMF_BIGINT *serial, KMF_CREDENTIAL *tokencred,
120*3089Swyllys 	char *filename)
121*3089Swyllys {
122*3089Swyllys 	KMF_RETURN rv = KMF_OK;
123*3089Swyllys 	KMF_EXPORTP12_PARAMS p12parms;
12417Sdinak 
125*3089Swyllys 	rv = configure_nss(kmfhandle, dir, prefix);
126*3089Swyllys 	if (rv != KMF_OK)
127*3089Swyllys 		return (rv);
12817Sdinak 
129*3089Swyllys 	(void) memset(&p12parms, 0, sizeof (p12parms));
130*3089Swyllys 	if (token_spec == NULL)
131*3089Swyllys 		token_spec = DEFAULT_NSS_TOKEN;
13217Sdinak 
133*3089Swyllys 	p12parms.kstype = KMF_KEYSTORE_NSS;
134*3089Swyllys 	p12parms.certLabel = certlabel;
135*3089Swyllys 	p12parms.issuer = issuer;
136*3089Swyllys 	p12parms.subject = subject;
137*3089Swyllys 	p12parms.serial = serial;
138*3089Swyllys 	p12parms.idstr = NULL;
139*3089Swyllys 	if (tokencred != NULL)
140*3089Swyllys 		p12parms.cred = *tokencred;
141*3089Swyllys 	p12parms.nssparms.slotlabel = token_spec;
14217Sdinak 
143*3089Swyllys 	(void) get_pk12_password(&p12parms.p12cred);
14417Sdinak 
145*3089Swyllys 	rv = KMF_ExportPK12(kmfhandle, &p12parms, filename);
146*3089Swyllys 	if (p12parms.p12cred.cred)
147*3089Swyllys 		free(p12parms.p12cred.cred);
14817Sdinak 
149*3089Swyllys 	return (rv);
15017Sdinak }
15117Sdinak 
152*3089Swyllys static KMF_RETURN
153*3089Swyllys pk_export_pk12_files(KMF_HANDLE_T kmfhandle,
154*3089Swyllys 	char *certfile, char *keyfile, char *dir,
155*3089Swyllys 	char *outfile)
15617Sdinak {
157*3089Swyllys 	KMF_RETURN rv;
158*3089Swyllys 	KMF_EXPORTP12_PARAMS p12parms;
15917Sdinak 
160*3089Swyllys 	(void) memset(&p12parms, 0, sizeof (p12parms));
16117Sdinak 
162*3089Swyllys 	p12parms.kstype = KMF_KEYSTORE_OPENSSL;
163*3089Swyllys 	p12parms.certLabel = NULL;
164*3089Swyllys 	p12parms.issuer = NULL;
165*3089Swyllys 	p12parms.subject = NULL;
166*3089Swyllys 	p12parms.serial = 0;
167*3089Swyllys 	p12parms.idstr = NULL;
168*3089Swyllys 	p12parms.sslparms.dirpath = dir;
169*3089Swyllys 	p12parms.sslparms.certfile = certfile;
170*3089Swyllys 	p12parms.sslparms.keyfile = keyfile;
17117Sdinak 
172*3089Swyllys 	(void) get_pk12_password(&p12parms.p12cred);
17317Sdinak 
174*3089Swyllys 	rv = KMF_ExportPK12(kmfhandle, &p12parms, outfile);
17517Sdinak 
176*3089Swyllys 	if (p12parms.p12cred.cred)
177*3089Swyllys 		free(p12parms.p12cred.cred);
17817Sdinak 
179*3089Swyllys 	return (rv);
18017Sdinak }
18117Sdinak 
182*3089Swyllys static KMF_RETURN
183*3089Swyllys pk_export_nss_objects(KMF_HANDLE_T kmfhandle, char *token_spec,
184*3089Swyllys 	int oclass, char *certlabel, char *issuer, char *subject,
185*3089Swyllys 	KMF_BIGINT *serial, KMF_ENCODE_FORMAT kfmt, char *dir,
186*3089Swyllys 	char *prefix, char *filename)
18717Sdinak {
188*3089Swyllys 	KMF_RETURN rv = KMF_OK;
189*3089Swyllys 	KMF_STORECERT_PARAMS scparms;
190*3089Swyllys 	KMF_X509_DER_CERT kmfcert;
191*3089Swyllys 
192*3089Swyllys 	rv = configure_nss(kmfhandle, dir, prefix);
193*3089Swyllys 	if (rv != KMF_OK)
194*3089Swyllys 		return (rv);
195*3089Swyllys 
196*3089Swyllys 	/* If searching for public objects or certificates, find certs now */
197*3089Swyllys 	if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) {
198*3089Swyllys 		KMF_FINDCERT_PARAMS fcargs;
19917Sdinak 
200*3089Swyllys 		(void) memset(&fcargs, 0, sizeof (fcargs));
201*3089Swyllys 		fcargs.kstype = KMF_KEYSTORE_NSS;
202*3089Swyllys 		fcargs.certLabel = certlabel;
203*3089Swyllys 		fcargs.issuer = issuer;
204*3089Swyllys 		fcargs.subject = subject;
205*3089Swyllys 		fcargs.serial = serial;
206*3089Swyllys 		fcargs.nssparms.slotlabel = token_spec;
20717Sdinak 
208*3089Swyllys 		rv = pk_find_export_cert(kmfhandle, &fcargs, &kmfcert);
209*3089Swyllys 		if (rv == KMF_OK) {
210*3089Swyllys 			(void) memset(&scparms, 0, sizeof (scparms));
211*3089Swyllys 			scparms.kstype = KMF_KEYSTORE_OPENSSL;
212*3089Swyllys 			scparms.sslparms.certfile = filename;
213*3089Swyllys 			scparms.sslparms.format = kfmt;
21417Sdinak 
215*3089Swyllys 			rv = KMF_StoreCert(kmfhandle, &scparms,
216*3089Swyllys 				&kmfcert.certificate);
217*3089Swyllys 
218*3089Swyllys 			KMF_FreeKMFCert(kmfhandle, &kmfcert);
219*3089Swyllys 		}
220*3089Swyllys 	}
221*3089Swyllys 	return (rv);
22217Sdinak }
22317Sdinak 
224*3089Swyllys static KMF_RETURN
225*3089Swyllys pk_export_pk12_pk11(KMF_HANDLE_T kmfhandle, char *token_spec,
226*3089Swyllys 	char *certlabel, char *issuer, char *subject,
227*3089Swyllys 	KMF_BIGINT *serial, KMF_CREDENTIAL *tokencred, char *filename)
22817Sdinak {
229*3089Swyllys 	KMF_RETURN rv = KMF_OK;
230*3089Swyllys 	KMF_EXPORTP12_PARAMS p12parms;
23117Sdinak 
232*3089Swyllys 	rv = select_token(kmfhandle, token_spec, TRUE);
233*3089Swyllys 	if (rv != KMF_OK) {
23417Sdinak 		return (rv);
23517Sdinak 	}
23617Sdinak 
237*3089Swyllys 	(void) memset(&p12parms, 0, sizeof (p12parms));
23817Sdinak 
239*3089Swyllys 	p12parms.kstype = KMF_KEYSTORE_PK11TOKEN;
240*3089Swyllys 	p12parms.certLabel = certlabel;
241*3089Swyllys 	p12parms.issuer = issuer;
242*3089Swyllys 	p12parms.subject = subject;
243*3089Swyllys 	p12parms.serial = serial;
244*3089Swyllys 	p12parms.idstr = NULL;
245*3089Swyllys 	if (tokencred != NULL)
246*3089Swyllys 		p12parms.cred = *tokencred;
247*3089Swyllys 	(void) get_pk12_password(&p12parms.p12cred);
24817Sdinak 
249*3089Swyllys 	rv = KMF_ExportPK12(kmfhandle, &p12parms, filename);
25017Sdinak 
251*3089Swyllys 	if (p12parms.p12cred.cred)
252*3089Swyllys 		free(p12parms.p12cred.cred);
25317Sdinak 
254*3089Swyllys 	return (rv);
25517Sdinak }
25617Sdinak 
257*3089Swyllys static KMF_RETURN
258*3089Swyllys pk_export_pk11_objects(KMF_HANDLE_T kmfhandle, char *token_spec,
259*3089Swyllys 	char *certlabel, char *issuer, char *subject,
260*3089Swyllys 	KMF_BIGINT *serial, KMF_ENCODE_FORMAT kfmt,
261*3089Swyllys 	char *filename)
26217Sdinak {
263*3089Swyllys 	KMF_RETURN rv = KMF_OK;
264*3089Swyllys 	KMF_FINDCERT_PARAMS fcparms;
265*3089Swyllys 	KMF_STORECERT_PARAMS scparms;
266*3089Swyllys 	KMF_X509_DER_CERT kmfcert;
26717Sdinak 
268*3089Swyllys 	rv = select_token(kmfhandle, token_spec, TRUE);
26917Sdinak 
270*3089Swyllys 	if (rv != KMF_OK) {
27117Sdinak 		return (rv);
27217Sdinak 	}
27317Sdinak 
274*3089Swyllys 	(void) memset(&fcparms, 0, sizeof (fcparms));
275*3089Swyllys 	fcparms.kstype = KMF_KEYSTORE_PK11TOKEN;
276*3089Swyllys 	fcparms.certLabel = certlabel;
277*3089Swyllys 	fcparms.issuer = issuer;
278*3089Swyllys 	fcparms.subject = subject;
279*3089Swyllys 	fcparms.serial = serial;
28017Sdinak 
281*3089Swyllys 	rv = pk_find_export_cert(kmfhandle, &fcparms, &kmfcert);
28217Sdinak 
283*3089Swyllys 	if (rv == KMF_OK) {
284*3089Swyllys 		(void) memset(&scparms, 0, sizeof (scparms));
285*3089Swyllys 		scparms.kstype = KMF_KEYSTORE_OPENSSL;
286*3089Swyllys 		scparms.sslparms.certfile = filename;
287*3089Swyllys 		scparms.sslparms.format = kfmt;
28817Sdinak 
289*3089Swyllys 		rv = KMF_StoreCert(kmfhandle, &scparms,
290*3089Swyllys 			&kmfcert.certificate);
29117Sdinak 
292*3089Swyllys 		KMF_FreeKMFCert(kmfhandle, &kmfcert);
29317Sdinak 	}
294*3089Swyllys 	return (rv);
29517Sdinak }
29617Sdinak 
29717Sdinak /*
298*3089Swyllys  * Export objects from one keystore to a file.
29917Sdinak  */
30017Sdinak int
30117Sdinak pk_export(int argc, char *argv[])
30217Sdinak {
303864Sdinak 	int		opt;
304864Sdinak 	extern int	optind_av;
305864Sdinak 	extern char	*optarg_av;
306864Sdinak 	char		*token_spec = NULL;
30717Sdinak 	char		*filename = NULL;
308*3089Swyllys 	char		*dir = NULL;
309*3089Swyllys 	char		*prefix = NULL;
310*3089Swyllys 	char		*certlabel = NULL;
311*3089Swyllys 	char		*subject = NULL;
312*3089Swyllys 	char		*issuer = NULL;
313*3089Swyllys 	char		*infile = NULL;
314*3089Swyllys 	char		*keyfile = NULL;
315*3089Swyllys 	char		*certfile = NULL;
316*3089Swyllys 	char		*serstr = NULL;
317*3089Swyllys 	KMF_KEYSTORE_TYPE	kstype = 0;
318*3089Swyllys 	KMF_ENCODE_FORMAT	kfmt = KMF_FORMAT_PKCS12;
319*3089Swyllys 	KMF_RETURN		rv = KMF_OK;
320*3089Swyllys 	int		oclass = PK_CERT_OBJ;
321*3089Swyllys 	KMF_BIGINT	serial = { NULL, 0 };
322*3089Swyllys 	KMF_HANDLE_T	kmfhandle = NULL;
323*3089Swyllys 	KMF_CREDENTIAL	tokencred = {NULL, 0};
32417Sdinak 
325864Sdinak 	/* Parse command line options.  Do NOT i18n/l10n. */
326*3089Swyllys 	while ((opt = getopt_av(argc, argv,
327*3089Swyllys 		"k:(keystore)y:(objtype)T:(token)"
328*3089Swyllys 		"d:(dir)p:(prefix)"
329*3089Swyllys 		"l:(label)n:(nickname)s:(subject)"
330*3089Swyllys 		"i:(issuer)S:(serial)"
331*3089Swyllys 		"K:(keyfile)c:(certfile)"
332*3089Swyllys 		"F:(outformat)"
333*3089Swyllys 		"I:(infile)o:(outfile)")) != EOF) {
334*3089Swyllys 		if (EMPTYSTRING(optarg_av))
335*3089Swyllys 			return (PK_ERR_USAGE);
336864Sdinak 		switch (opt) {
337*3089Swyllys 		case 'k':
338*3089Swyllys 			kstype = KS2Int(optarg_av);
339*3089Swyllys 			if (kstype == 0)
340*3089Swyllys 				return (PK_ERR_USAGE);
341*3089Swyllys 			break;
342*3089Swyllys 		case 'y':
343*3089Swyllys 			oclass = OT2Int(optarg_av);
344*3089Swyllys 			if (oclass == -1)
345*3089Swyllys 				return (PK_ERR_USAGE);
346*3089Swyllys 			break;
347864Sdinak 		case 'T':	/* token specifier */
348864Sdinak 			if (token_spec)
349864Sdinak 				return (PK_ERR_USAGE);
350864Sdinak 			token_spec = optarg_av;
351864Sdinak 			break;
352*3089Swyllys 		case 'd':
353*3089Swyllys 			if (dir)
354*3089Swyllys 				return (PK_ERR_USAGE);
355*3089Swyllys 			dir = optarg_av;
356*3089Swyllys 			break;
357*3089Swyllys 		case 'p':
358*3089Swyllys 			if (prefix)
359*3089Swyllys 				return (PK_ERR_USAGE);
360*3089Swyllys 			prefix = optarg_av;
361*3089Swyllys 			break;
362*3089Swyllys 		case 'n':
363*3089Swyllys 		case 'l':
364*3089Swyllys 			if (certlabel)
365*3089Swyllys 				return (PK_ERR_USAGE);
366*3089Swyllys 			certlabel = optarg_av;
367*3089Swyllys 			break;
368*3089Swyllys 		case 's':
369*3089Swyllys 			if (subject)
370*3089Swyllys 				return (PK_ERR_USAGE);
371*3089Swyllys 			subject = optarg_av;
372*3089Swyllys 			break;
373*3089Swyllys 		case 'i':
374*3089Swyllys 			if (issuer)
375*3089Swyllys 				return (PK_ERR_USAGE);
376*3089Swyllys 			issuer = optarg_av;
377*3089Swyllys 			break;
378*3089Swyllys 		case 'S':
379*3089Swyllys 			serstr = optarg_av;
380*3089Swyllys 			break;
381*3089Swyllys 		case 'F':
382*3089Swyllys 			kfmt = Str2Format(optarg_av);
383*3089Swyllys 			if (kfmt == KMF_FORMAT_UNDEF)
384*3089Swyllys 				return (PK_ERR_USAGE);
385*3089Swyllys 			break;
386*3089Swyllys 		case 'I':	/* output file name */
387*3089Swyllys 			if (infile)
388*3089Swyllys 				return (PK_ERR_USAGE);
389*3089Swyllys 			infile = optarg_av;
390*3089Swyllys 			break;
391864Sdinak 		case 'o':	/* output file name */
392864Sdinak 			if (filename)
393864Sdinak 				return (PK_ERR_USAGE);
394864Sdinak 			filename = optarg_av;
395864Sdinak 			break;
396*3089Swyllys 		case 'c':	/* input cert file name */
397*3089Swyllys 			if (certfile)
398*3089Swyllys 				return (PK_ERR_USAGE);
399*3089Swyllys 			certfile = optarg_av;
400*3089Swyllys 			break;
401*3089Swyllys 		case 'K':	/* input key file name */
402*3089Swyllys 			if (keyfile)
403*3089Swyllys 				return (PK_ERR_USAGE);
404*3089Swyllys 			keyfile = optarg_av;
405*3089Swyllys 			break;
406864Sdinak 		default:
407864Sdinak 			return (PK_ERR_USAGE);
408864Sdinak 			break;
409864Sdinak 		}
410864Sdinak 	}
41117Sdinak 
412*3089Swyllys 	/* Assume keystore = PKCS#11 if not specified */
413*3089Swyllys 	if (kstype == 0)
414*3089Swyllys 		kstype = KMF_KEYSTORE_PK11TOKEN;
415864Sdinak 
416864Sdinak 	/* Filename arg is required. */
417*3089Swyllys 	if (EMPTYSTRING(filename)) {
418*3089Swyllys 		cryptoerror(LOG_STDERR, gettext("You must specify "
419*3089Swyllys 			"an 'outfile' parameter when exporting.\n"));
42017Sdinak 		return (PK_ERR_USAGE);
421*3089Swyllys 	}
42217Sdinak 
423864Sdinak 	/* No additional args allowed. */
424864Sdinak 	argc -= optind_av;
425864Sdinak 	argv += optind_av;
426864Sdinak 	if (argc)
427864Sdinak 		return (PK_ERR_USAGE);
428*3089Swyllys 
429*3089Swyllys 	/* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
430*3089Swyllys 	if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
431*3089Swyllys 		kstype != KMF_KEYSTORE_PK11TOKEN) {
432*3089Swyllys 
433*3089Swyllys 		(void) fprintf(stderr, gettext("The objtype parameter "
434*3089Swyllys 			"is only relevant if keystore=pkcs11\n"));
435*3089Swyllys 		return (PK_ERR_USAGE);
436*3089Swyllys 	}
437*3089Swyllys 
438*3089Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec))
439*3089Swyllys 		token_spec = PK_DEFAULT_PK11TOKEN;
440*3089Swyllys 	else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec))
441*3089Swyllys 		token_spec = DEFAULT_NSS_TOKEN;
442*3089Swyllys 
443*3089Swyllys 	if (kstype == KMF_KEYSTORE_OPENSSL) {
444*3089Swyllys 		if (kfmt != KMF_FORMAT_PKCS12) {
445*3089Swyllys 			cryptoerror(LOG_STDERR, gettext("PKCS12 "
446*3089Swyllys 				"is the only export format "
447*3089Swyllys 				"supported for the 'file' "
448*3089Swyllys 				"keystore.\n"));
449*3089Swyllys 			return (PK_ERR_USAGE);
450*3089Swyllys 		}
451*3089Swyllys 		if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) {
452*3089Swyllys 			cryptoerror(LOG_STDERR, gettext("A cert file"
453*3089Swyllys 				"and a key file must be specified "
454*3089Swyllys 				"when exporting to PKCS12 from the "
455*3089Swyllys 				"'file' keystore.\n"));
456*3089Swyllys 			return (PK_ERR_USAGE);
457*3089Swyllys 		}
458*3089Swyllys 	}
45917Sdinak 
46017Sdinak 	/* Check if the file exists and might be overwritten. */
46117Sdinak 	if (access(filename, F_OK) == 0) {
462*3089Swyllys 		cryptoerror(LOG_STDERR,
463*3089Swyllys 			gettext("Warning: file \"%s\" exists, "
464*3089Swyllys 				"will be overwritten."), filename);
46517Sdinak 		if (yesno(gettext("Continue with export? "),
46617Sdinak 		    gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) {
46717Sdinak 			return (0);
46817Sdinak 		}
469*3089Swyllys 	} else {
470*3089Swyllys 		rv = verify_file(filename);
471*3089Swyllys 		if (rv != KMF_OK) {
472*3089Swyllys 			cryptoerror(LOG_STDERR, gettext("The file (%s) "
473*3089Swyllys 				"cannot be created.\n"), filename);
474*3089Swyllys 			return (PK_ERR_USAGE);
475*3089Swyllys 		}
47617Sdinak 	}
47717Sdinak 
478*3089Swyllys 	if (serstr != NULL) {
479*3089Swyllys 		uchar_t *bytes = NULL;
480*3089Swyllys 		size_t bytelen;
48117Sdinak 
482*3089Swyllys 		rv = KMF_HexString2Bytes((uchar_t *)serstr, &bytes, &bytelen);
483*3089Swyllys 		if (rv != KMF_OK || bytes == NULL) {
484*3089Swyllys 			(void) fprintf(stderr, gettext("serial number "
485*3089Swyllys 				"must be specified as a hex number "
486*3089Swyllys 				"(ex: 0x0102030405ffeeddee)\n"));
487*3089Swyllys 			return (PK_ERR_USAGE);
488*3089Swyllys 		}
489*3089Swyllys 		serial.val = bytes;
490*3089Swyllys 		serial.len = bytelen;
49117Sdinak 	}
49217Sdinak 
493*3089Swyllys 	if ((kstype == KMF_KEYSTORE_PK11TOKEN ||
494*3089Swyllys 		kstype == KMF_KEYSTORE_NSS) &&
495*3089Swyllys 		(oclass & (PK_KEY_OBJ | PK_PRIVATE_OBJ) ||
496*3089Swyllys 		kfmt == KMF_FORMAT_PKCS12)) {
497*3089Swyllys 			(void) get_token_password(kstype, token_spec,
498*3089Swyllys 				&tokencred);
49917Sdinak 	}
50017Sdinak 
501*3089Swyllys 	if ((rv = KMF_Initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
502*3089Swyllys 		cryptoerror(LOG_STDERR, gettext("Error initializing "
503*3089Swyllys 				"KMF: 0x%02x\n"), rv);
504*3089Swyllys 		return (rv);
50517Sdinak 	}
50617Sdinak 
507*3089Swyllys 	switch (kstype) {
508*3089Swyllys 		case KMF_KEYSTORE_PK11TOKEN:
509*3089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
510*3089Swyllys 				rv = pk_export_pk12_pk11(
511*3089Swyllys 					kmfhandle,
512*3089Swyllys 					token_spec,
513*3089Swyllys 					certlabel,
514*3089Swyllys 					issuer, subject,
515*3089Swyllys 					&serial, &tokencred,
516*3089Swyllys 					filename);
517*3089Swyllys 			else
518*3089Swyllys 				rv = pk_export_pk11_objects(kmfhandle,
519*3089Swyllys 					token_spec,
520*3089Swyllys 					certlabel,
521*3089Swyllys 					issuer, subject,
522*3089Swyllys 					&serial, kfmt,
523*3089Swyllys 					filename);
524*3089Swyllys 			break;
525*3089Swyllys 		case KMF_KEYSTORE_NSS:
526*3089Swyllys 			if (dir == NULL)
527*3089Swyllys 				dir = PK_DEFAULT_DIRECTORY;
528*3089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
529*3089Swyllys 				rv = pk_export_pk12_nss(kmfhandle,
530*3089Swyllys 					token_spec, dir, prefix,
531*3089Swyllys 					certlabel, issuer,
532*3089Swyllys 					subject, &serial,
533*3089Swyllys 					&tokencred, filename);
534*3089Swyllys 			else
535*3089Swyllys 				rv = pk_export_nss_objects(kmfhandle,
536*3089Swyllys 					token_spec,
537*3089Swyllys 					oclass, certlabel, issuer, subject,
538*3089Swyllys 					&serial, kfmt, dir, prefix, filename);
539*3089Swyllys 			break;
540*3089Swyllys 		case KMF_KEYSTORE_OPENSSL:
541*3089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
542*3089Swyllys 				rv = pk_export_pk12_files(kmfhandle,
543*3089Swyllys 					certfile, keyfile, dir,
544*3089Swyllys 					filename);
545*3089Swyllys 			else
546*3089Swyllys 				rv = pk_export_file_objects(kmfhandle, oclass,
547*3089Swyllys 					issuer, subject, &serial, kfmt,
548*3089Swyllys 					dir, infile, filename);
549*3089Swyllys 			break;
550*3089Swyllys 		default:
551*3089Swyllys 			rv = PK_ERR_USAGE;
552*3089Swyllys 			break;
55317Sdinak 	}
55417Sdinak 
555*3089Swyllys 	if (rv != KMF_OK) {
556*3089Swyllys 		display_error(kmfhandle, rv,
557*3089Swyllys 			gettext("Error exporting objects"));
558*3089Swyllys 	}
55917Sdinak 
560*3089Swyllys 	if (serial.val != NULL)
561*3089Swyllys 		free(serial.val);
56217Sdinak 
563*3089Swyllys 	(void) KMF_Finalize(kmfhandle);
564*3089Swyllys 
565*3089Swyllys 	return (rv);
56617Sdinak }
567