17711facfSdinak /*
27711facfSdinak  * CDDL HEADER START
37711facfSdinak  *
47711facfSdinak  * The contents of this file are subject to the terms of the
5*99ebb4caSwyllys  * Common Development and Distribution License (the "License").
6*99ebb4caSwyllys  * You may not use this file except in compliance with the License.
77711facfSdinak  *
87711facfSdinak  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97711facfSdinak  * or http://www.opensolaris.org/os/licensing.
107711facfSdinak  * See the License for the specific language governing permissions
117711facfSdinak  * and limitations under the License.
127711facfSdinak  *
137711facfSdinak  * When distributing Covered Code, include this CDDL HEADER in each
147711facfSdinak  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157711facfSdinak  * If applicable, add the following below this CDDL HEADER, with the
167711facfSdinak  * fields enclosed by brackets "[]" replaced with your own identifying
177711facfSdinak  * information: Portions Copyright [yyyy] [name of copyright owner]
187711facfSdinak  *
197711facfSdinak  * CDDL HEADER END
207711facfSdinak  */
217711facfSdinak /*
22*99ebb4caSwyllys  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
237711facfSdinak  * Use is subject to license terms.
247711facfSdinak  */
257711facfSdinak 
267711facfSdinak #pragma ident	"%Z%%M%	%I%	%E% SMI"
277711facfSdinak 
287711facfSdinak /*
297711facfSdinak  * This file implements the import operation for this tool.
307711facfSdinak  * The basic flow of the process is to decrypt the PKCS#12
317711facfSdinak  * input file if it has a password, parse the elements in
327711facfSdinak  * the file, find the soft token, log into it, import the
337711facfSdinak  * PKCS#11 objects into the soft token, and log out.
347711facfSdinak  */
357711facfSdinak 
367711facfSdinak #include <stdio.h>
377711facfSdinak #include <stdlib.h>
387711facfSdinak #include <string.h>
39*99ebb4caSwyllys #include <ctype.h>
407711facfSdinak #include <errno.h>
417711facfSdinak #include <fcntl.h>
427711facfSdinak #include <sys/types.h>
437711facfSdinak #include <sys/stat.h>
447711facfSdinak #include "common.h"
457711facfSdinak 
46*99ebb4caSwyllys #include <kmfapi.h>
47*99ebb4caSwyllys 
48*99ebb4caSwyllys static KMF_RETURN
49*99ebb4caSwyllys pk_import_pk12_files(KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *cred,
50*99ebb4caSwyllys 	char *outfile, char *certfile, char *keyfile,
51*99ebb4caSwyllys 	char *dir, char *keydir, KMF_ENCODE_FORMAT outformat)
527711facfSdinak {
53*99ebb4caSwyllys 	KMF_RETURN rv = KMF_OK;
54*99ebb4caSwyllys 	KMF_DATA *certs = NULL;
55*99ebb4caSwyllys 	KMF_RAW_KEY_DATA *keys = NULL;
56*99ebb4caSwyllys 	int ncerts = 0;
57*99ebb4caSwyllys 	int nkeys = 0;
58*99ebb4caSwyllys 	int i;
59*99ebb4caSwyllys 
60*99ebb4caSwyllys 	rv = KMF_ImportPK12(kmfhandle, outfile, cred,
61*99ebb4caSwyllys 		&certs, &ncerts, &keys, &nkeys);
62*99ebb4caSwyllys 
63*99ebb4caSwyllys 	if (rv == KMF_OK) {
64*99ebb4caSwyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
65*99ebb4caSwyllys 			"key(s) in %s\n"), ncerts, nkeys, outfile);
66*99ebb4caSwyllys 	}
67*99ebb4caSwyllys 
68*99ebb4caSwyllys 	if (rv == KMF_OK && ncerts > 0) {
69*99ebb4caSwyllys 		KMF_STORECERT_PARAMS params;
70*99ebb4caSwyllys 		char newcertfile[MAXPATHLEN];
71*99ebb4caSwyllys 
72*99ebb4caSwyllys 		(void) memset(&params, 0, sizeof (KMF_STORECERT_PARAMS));
73*99ebb4caSwyllys 		params.kstype = KMF_KEYSTORE_OPENSSL;
74*99ebb4caSwyllys 		params.sslparms.dirpath = dir;
75*99ebb4caSwyllys 		params.sslparms.format = outformat;
76*99ebb4caSwyllys 
77*99ebb4caSwyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
78*99ebb4caSwyllys 			/*
79*99ebb4caSwyllys 			 * If storing more than 1 cert, gotta change
80*99ebb4caSwyllys 			 * the name so we don't overwrite the previous one.
81*99ebb4caSwyllys 			 * Just append a _# to the name.
82*99ebb4caSwyllys 			 */
83*99ebb4caSwyllys 			if (i > 0) {
84*99ebb4caSwyllys 				(void) snprintf(newcertfile,
85*99ebb4caSwyllys 					sizeof (newcertfile),
86*99ebb4caSwyllys 					"%s_%d", certfile, i);
87*99ebb4caSwyllys 				params.sslparms.certfile = newcertfile;
88*99ebb4caSwyllys 			} else {
89*99ebb4caSwyllys 				params.sslparms.certfile = certfile;
90*99ebb4caSwyllys 			}
91*99ebb4caSwyllys 			rv = KMF_StoreCert(kmfhandle, &params, &certs[i]);
92*99ebb4caSwyllys 		}
937711facfSdinak 	}
94*99ebb4caSwyllys 	if (rv == KMF_OK && nkeys > 0) {
95*99ebb4caSwyllys 		KMF_STOREKEY_PARAMS skparms;
96*99ebb4caSwyllys 		char newkeyfile[MAXPATHLEN];
97*99ebb4caSwyllys 
98*99ebb4caSwyllys 		(void) memset(&skparms, 0, sizeof (skparms));
99*99ebb4caSwyllys 
100*99ebb4caSwyllys 		/* The order of certificates and keys should match */
101*99ebb4caSwyllys 		for (i = 0; rv == KMF_OK && i < nkeys; i++) {
102*99ebb4caSwyllys 			skparms.kstype = KMF_KEYSTORE_OPENSSL;
103*99ebb4caSwyllys 			skparms.sslparms.dirpath = keydir;
104*99ebb4caSwyllys 			skparms.sslparms.format = outformat;
105*99ebb4caSwyllys 			skparms.cred = *cred;
106*99ebb4caSwyllys 			skparms.certificate = &certs[i];
107*99ebb4caSwyllys 
108*99ebb4caSwyllys 			if (i > 0) {
109*99ebb4caSwyllys 				(void) snprintf(newkeyfile,
110*99ebb4caSwyllys 					sizeof (newkeyfile),
111*99ebb4caSwyllys 					"%s_%d", keyfile, i);
112*99ebb4caSwyllys 				skparms.sslparms.keyfile = newkeyfile;
113*99ebb4caSwyllys 			} else {
114*99ebb4caSwyllys 				skparms.sslparms.keyfile = keyfile;
115*99ebb4caSwyllys 			}
116*99ebb4caSwyllys 
117*99ebb4caSwyllys 			rv = KMF_StorePrivateKey(kmfhandle, &skparms,
118*99ebb4caSwyllys 				&keys[i]);
119*99ebb4caSwyllys 		}
1207711facfSdinak 	}
121*99ebb4caSwyllys 	/*
122*99ebb4caSwyllys 	 * Cleanup memory.
123*99ebb4caSwyllys 	 */
124*99ebb4caSwyllys 	if (certs) {
125*99ebb4caSwyllys 		for (i = 0; i < ncerts; i++)
126*99ebb4caSwyllys 			KMF_FreeData(&certs[i]);
127*99ebb4caSwyllys 		free(certs);
128*99ebb4caSwyllys 	}
129*99ebb4caSwyllys 	if (keys) {
130*99ebb4caSwyllys 		for (i = 0; i < nkeys; i++)
131*99ebb4caSwyllys 			KMF_FreeRawKey(&keys[i]);
132*99ebb4caSwyllys 		free(keys);
1337711facfSdinak 	}
1347711facfSdinak 
1357711facfSdinak 
136*99ebb4caSwyllys 	return (rv);
1377711facfSdinak }
1387711facfSdinak 
139*99ebb4caSwyllys 
140*99ebb4caSwyllys static KMF_RETURN
141*99ebb4caSwyllys pk_import_pk12_nss(
142*99ebb4caSwyllys 	KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *kmfcred,
143*99ebb4caSwyllys 	KMF_CREDENTIAL *tokencred,
144*99ebb4caSwyllys 	char *token_spec, char *dir, char *prefix,
145*99ebb4caSwyllys 	char *nickname, char *trustflags, char *filename)
1467711facfSdinak {
147*99ebb4caSwyllys 	KMF_RETURN rv = KMF_OK;
148*99ebb4caSwyllys 	KMF_DATA *certs = NULL;
149*99ebb4caSwyllys 	KMF_RAW_KEY_DATA *keys = NULL;
150*99ebb4caSwyllys 	int ncerts = 0;
151*99ebb4caSwyllys 	int nkeys = 0;
152*99ebb4caSwyllys 	int i;
153*99ebb4caSwyllys 
154*99ebb4caSwyllys 	rv = configure_nss(kmfhandle, dir, prefix);
155*99ebb4caSwyllys 	if (rv != KMF_OK)
156*99ebb4caSwyllys 		return (rv);
1577711facfSdinak 
158*99ebb4caSwyllys 	rv = KMF_ImportPK12(kmfhandle, filename, kmfcred,
159*99ebb4caSwyllys 		&certs, &ncerts, &keys, &nkeys);
1607711facfSdinak 
161*99ebb4caSwyllys 	if (rv == KMF_OK)
162*99ebb4caSwyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
163*99ebb4caSwyllys 			"key(s) in %s\n"), ncerts, nkeys, filename);
1647711facfSdinak 
165*99ebb4caSwyllys 	if (rv == KMF_OK) {
166*99ebb4caSwyllys 		KMF_STORECERT_PARAMS params;
1677711facfSdinak 
168*99ebb4caSwyllys 		(void) memset(&params, 0, sizeof (KMF_STORECERT_PARAMS));
169*99ebb4caSwyllys 		params.kstype = KMF_KEYSTORE_NSS;
170*99ebb4caSwyllys 		params.nssparms.slotlabel = token_spec;
171*99ebb4caSwyllys 		params.nssparms.trustflag = trustflags;
1727711facfSdinak 
173*99ebb4caSwyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
174*99ebb4caSwyllys 			if (i == 0)
175*99ebb4caSwyllys 				params.certLabel = nickname;
176*99ebb4caSwyllys 			else
177*99ebb4caSwyllys 				params.certLabel = NULL;
1787711facfSdinak 
179*99ebb4caSwyllys 			rv = KMF_StoreCert(kmfhandle, &params, &certs[i]);
1807711facfSdinak 		}
181*99ebb4caSwyllys 		if (rv != KMF_OK) {
182*99ebb4caSwyllys 			display_error(kmfhandle, rv,
183*99ebb4caSwyllys 				gettext("Error storing certificate "
184*99ebb4caSwyllys 					"in PKCS11 token"));
1857711facfSdinak 		}
1867711facfSdinak 	}
1877711facfSdinak 
188*99ebb4caSwyllys 	if (rv == KMF_OK) {
189*99ebb4caSwyllys 		KMF_STOREKEY_PARAMS skparms;
1907711facfSdinak 
191*99ebb4caSwyllys 		/* The order of certificates and keys should match */
192*99ebb4caSwyllys 		for (i = 0; i < nkeys; i++) {
193*99ebb4caSwyllys 			(void) memset(&skparms, 0,
194*99ebb4caSwyllys 				sizeof (KMF_STOREKEY_PARAMS));
195*99ebb4caSwyllys 			skparms.kstype = KMF_KEYSTORE_NSS;
196*99ebb4caSwyllys 			skparms.cred = *tokencred;
197*99ebb4caSwyllys 			skparms.label = nickname;
198*99ebb4caSwyllys 			skparms.certificate = &certs[i];
199*99ebb4caSwyllys 			skparms.nssparms.slotlabel = token_spec;
2007711facfSdinak 
201*99ebb4caSwyllys 			rv = KMF_StorePrivateKey(kmfhandle, &skparms, &keys[i]);
202*99ebb4caSwyllys 		}
2037711facfSdinak 	}
2047711facfSdinak 
205*99ebb4caSwyllys 	/*
206*99ebb4caSwyllys 	 * Cleanup memory.
207*99ebb4caSwyllys 	 */
208*99ebb4caSwyllys 	if (certs) {
209*99ebb4caSwyllys 		for (i = 0; i < ncerts; i++)
210*99ebb4caSwyllys 			KMF_FreeData(&certs[i]);
211*99ebb4caSwyllys 		free(certs);
2127711facfSdinak 	}
213*99ebb4caSwyllys 	if (keys) {
214*99ebb4caSwyllys 		for (i = 0; i < nkeys; i++)
215*99ebb4caSwyllys 			KMF_FreeRawKey(&keys[i]);
216*99ebb4caSwyllys 		free(keys);
2177711facfSdinak 	}
2187711facfSdinak 
219*99ebb4caSwyllys 	return (rv);
220*99ebb4caSwyllys }
2217711facfSdinak 
222*99ebb4caSwyllys static KMF_RETURN
223*99ebb4caSwyllys pk_import_cert(
224*99ebb4caSwyllys 	KMF_HANDLE_T kmfhandle,
225*99ebb4caSwyllys 	KMF_KEYSTORE_TYPE kstype,
226*99ebb4caSwyllys 	char *label, char *token_spec, char *filename,
227*99ebb4caSwyllys 	char *dir, char *prefix, char *trustflags)
228*99ebb4caSwyllys {
229*99ebb4caSwyllys 	KMF_RETURN rv = KMF_OK;
230*99ebb4caSwyllys 	KMF_IMPORTCERT_PARAMS params;
2317711facfSdinak 
232*99ebb4caSwyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
233*99ebb4caSwyllys 		rv = select_token(kmfhandle, token_spec, FALSE);
2347711facfSdinak 
235*99ebb4caSwyllys 		if (rv != KMF_OK) {
236*99ebb4caSwyllys 			return (rv);
237*99ebb4caSwyllys 		}
2387711facfSdinak 	}
2397711facfSdinak 
240*99ebb4caSwyllys 	(void) memset(&params, 0, sizeof (params));
241*99ebb4caSwyllys 	params.kstype = kstype;
242*99ebb4caSwyllys 	params.certfile = filename;
243*99ebb4caSwyllys 	params.certLabel = label;
2447711facfSdinak 
245*99ebb4caSwyllys 	if (kstype == KMF_KEYSTORE_NSS) {
246*99ebb4caSwyllys 		rv = configure_nss(kmfhandle, dir, prefix);
247*99ebb4caSwyllys 		if (rv != KMF_OK)
248*99ebb4caSwyllys 			return (rv);
249*99ebb4caSwyllys 		params.nssparms.trustflag = trustflags;
250*99ebb4caSwyllys 		params.nssparms.slotlabel = token_spec;
2517711facfSdinak 	}
2527711facfSdinak 
253*99ebb4caSwyllys 	rv = KMF_ImportCert(kmfhandle, &params);
2547711facfSdinak 
255*99ebb4caSwyllys 	return (rv);
2567711facfSdinak }
2577711facfSdinak 
258*99ebb4caSwyllys static KMF_RETURN
259*99ebb4caSwyllys pk_import_file_crl(void *kmfhandle,
260*99ebb4caSwyllys 	char *infile,
261*99ebb4caSwyllys 	char *outfile,
262*99ebb4caSwyllys 	char *outdir,
263*99ebb4caSwyllys 	KMF_ENCODE_FORMAT outfmt)
2647711facfSdinak {
265*99ebb4caSwyllys 	KMF_IMPORTCRL_PARAMS 	icrl_params;
266*99ebb4caSwyllys 	KMF_OPENSSL_PARAMS sslparams;
2677711facfSdinak 
268*99ebb4caSwyllys 	sslparams.crlfile = infile;
269*99ebb4caSwyllys 	sslparams.dirpath = outdir;
270*99ebb4caSwyllys 	sslparams.outcrlfile = outfile;
271*99ebb4caSwyllys 	sslparams.format = outfmt;
272*99ebb4caSwyllys 	sslparams.crl_check = B_FALSE;
2737711facfSdinak 
274*99ebb4caSwyllys 	icrl_params.kstype = KMF_KEYSTORE_OPENSSL;
275*99ebb4caSwyllys 	icrl_params.sslparms = sslparams;
2767711facfSdinak 
277*99ebb4caSwyllys 	return (KMF_ImportCRL(kmfhandle, &icrl_params));
2787711facfSdinak 
279*99ebb4caSwyllys }
2807711facfSdinak 
281*99ebb4caSwyllys static KMF_RETURN
282*99ebb4caSwyllys pk_import_nss_crl(void *kmfhandle,
283*99ebb4caSwyllys 	boolean_t verify_crl_flag,
284*99ebb4caSwyllys 	char *infile,
285*99ebb4caSwyllys 	char *outdir,
286*99ebb4caSwyllys 	char *prefix)
287*99ebb4caSwyllys {
288*99ebb4caSwyllys 	KMF_IMPORTCRL_PARAMS 	icrl_params;
289*99ebb4caSwyllys 	KMF_RETURN rv;
290*99ebb4caSwyllys 
291*99ebb4caSwyllys 	rv = configure_nss(kmfhandle, outdir, prefix);
292*99ebb4caSwyllys 	if (rv != KMF_OK)
2937711facfSdinak 		return (rv);
2947711facfSdinak 
295*99ebb4caSwyllys 	icrl_params.kstype = KMF_KEYSTORE_NSS;
296*99ebb4caSwyllys 	icrl_params.nssparms.slotlabel = NULL;
297*99ebb4caSwyllys 	icrl_params.nssparms.crlfile = infile;
298*99ebb4caSwyllys 	icrl_params.nssparms.crl_check = verify_crl_flag;
2997711facfSdinak 
300*99ebb4caSwyllys 	return (KMF_ImportCRL(kmfhandle, &icrl_params));
3017711facfSdinak 
3027711facfSdinak }
3037711facfSdinak 
304*99ebb4caSwyllys static KMF_RETURN
305*99ebb4caSwyllys pk_import_pk12_pk11(
306*99ebb4caSwyllys 	KMF_HANDLE_T kmfhandle,
307*99ebb4caSwyllys 	KMF_CREDENTIAL *p12cred,
308*99ebb4caSwyllys 	KMF_CREDENTIAL *tokencred,
309*99ebb4caSwyllys 	char *label, char *token_spec,
310*99ebb4caSwyllys 	char *filename)
3117711facfSdinak {
312*99ebb4caSwyllys 	KMF_RETURN rv = KMF_OK;
313*99ebb4caSwyllys 	KMF_DATA *certs = NULL;
314*99ebb4caSwyllys 	KMF_RAW_KEY_DATA *keys = NULL;
315*99ebb4caSwyllys 	int ncerts = 0;
316*99ebb4caSwyllys 	int nkeys = 0;
317*99ebb4caSwyllys 	int i;
3187711facfSdinak 
319*99ebb4caSwyllys 	rv = select_token(kmfhandle, token_spec, FALSE);
3207711facfSdinak 
321*99ebb4caSwyllys 	if (rv != KMF_OK) {
322*99ebb4caSwyllys 		return (rv);
3237711facfSdinak 	}
3247711facfSdinak 
325*99ebb4caSwyllys 	rv = KMF_ImportPK12(kmfhandle, filename, p12cred,
326*99ebb4caSwyllys 		&certs, &ncerts, &keys, &nkeys);
3277711facfSdinak 
328*99ebb4caSwyllys 	if (rv == KMF_OK) {
329*99ebb4caSwyllys 		KMF_STOREKEY_PARAMS skparms;
3307711facfSdinak 
331*99ebb4caSwyllys 		/* The order of certificates and keys should match */
332*99ebb4caSwyllys 		for (i = 0; i < nkeys; i++) {
333*99ebb4caSwyllys 			(void) memset(&skparms, 0,
334*99ebb4caSwyllys 				sizeof (KMF_STOREKEY_PARAMS));
335*99ebb4caSwyllys 			skparms.kstype = KMF_KEYSTORE_PK11TOKEN;
336*99ebb4caSwyllys 			skparms.certificate = &certs[i];
337*99ebb4caSwyllys 			if (tokencred != NULL)
338*99ebb4caSwyllys 				skparms.cred = *tokencred;
339*99ebb4caSwyllys 			if (i == 0)
340*99ebb4caSwyllys 				skparms.label = label;
341*99ebb4caSwyllys 			else
342*99ebb4caSwyllys 				skparms.label = NULL;
3437711facfSdinak 
344*99ebb4caSwyllys 			rv = KMF_StorePrivateKey(kmfhandle, &skparms,
345*99ebb4caSwyllys 				&keys[i]);
346*99ebb4caSwyllys 		}
3477711facfSdinak 	}
3487711facfSdinak 
349*99ebb4caSwyllys 	if (rv == KMF_OK) {
350*99ebb4caSwyllys 		KMF_STORECERT_PARAMS params;
3517711facfSdinak 
352*99ebb4caSwyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
353*99ebb4caSwyllys 			"key(s) in %s\n"), ncerts, nkeys, filename);
354*99ebb4caSwyllys 		(void) memset(&params, 0, sizeof (KMF_STORECERT_PARAMS));
3557711facfSdinak 
356*99ebb4caSwyllys 		params.kstype = KMF_KEYSTORE_PK11TOKEN;
3577711facfSdinak 
358*99ebb4caSwyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
359*99ebb4caSwyllys 			if (i == 0)
360*99ebb4caSwyllys 				params.certLabel = label;
361*99ebb4caSwyllys 			else
362*99ebb4caSwyllys 				params.certLabel = NULL;
3637711facfSdinak 
364*99ebb4caSwyllys 			rv = KMF_StoreCert(kmfhandle, &params, &certs[i]);
365*99ebb4caSwyllys 		}
3667711facfSdinak 	}
3677711facfSdinak 
368*99ebb4caSwyllys 	/*
369*99ebb4caSwyllys 	 * Cleanup memory.
370*99ebb4caSwyllys 	 */
371*99ebb4caSwyllys 	if (certs) {
372*99ebb4caSwyllys 		for (i = 0; i < ncerts; i++)
373*99ebb4caSwyllys 			KMF_FreeData(&certs[i]);
374*99ebb4caSwyllys 		free(certs);
375*99ebb4caSwyllys 	}
376*99ebb4caSwyllys 	if (keys) {
377*99ebb4caSwyllys 		for (i = 0; i < nkeys; i++)
378*99ebb4caSwyllys 			KMF_FreeRawKey(&keys[i]);
379*99ebb4caSwyllys 		free(keys);
3807711facfSdinak 	}
3817711facfSdinak 
382*99ebb4caSwyllys 	return (rv);
3837711facfSdinak }
3847711facfSdinak 
3857711facfSdinak /*
386*99ebb4caSwyllys  * Import objects from into KMF repositories.
3877711facfSdinak  */
3887711facfSdinak int
3897711facfSdinak pk_import(int argc, char *argv[])
3907711facfSdinak {
39149e21299Sdinak 	int		opt;
39249e21299Sdinak 	extern int	optind_av;
39349e21299Sdinak 	extern char	*optarg_av;
39449e21299Sdinak 	char		*token_spec = NULL;
3957711facfSdinak 	char		*filename = NULL;
396*99ebb4caSwyllys 	char		*keyfile = NULL;
397*99ebb4caSwyllys 	char		*certfile = NULL;
398*99ebb4caSwyllys 	char		*crlfile = NULL;
399*99ebb4caSwyllys 	char		*certlabel = NULL;
400*99ebb4caSwyllys 	char		*dir = NULL;
401*99ebb4caSwyllys 	char		*keydir = NULL;
402*99ebb4caSwyllys 	char		*prefix = NULL;
403*99ebb4caSwyllys 	char		*trustflags = NULL;
404*99ebb4caSwyllys 	char		*verify_crl = NULL;
405*99ebb4caSwyllys 	boolean_t	verify_crl_flag = B_FALSE;
406*99ebb4caSwyllys 	int		oclass = 0;
407*99ebb4caSwyllys 	KMF_KEYSTORE_TYPE	kstype = 0;
408*99ebb4caSwyllys 	KMF_ENCODE_FORMAT	kfmt = 0;
409*99ebb4caSwyllys 	KMF_ENCODE_FORMAT	okfmt = KMF_FORMAT_ASN1;
410*99ebb4caSwyllys 	KMF_RETURN		rv = KMF_OK;
411*99ebb4caSwyllys 	KMF_CREDENTIAL	pk12cred = { NULL, 0 };
412*99ebb4caSwyllys 	KMF_CREDENTIAL	tokencred = { NULL, 0 };
413*99ebb4caSwyllys 	KMF_HANDLE_T	kmfhandle = NULL;
4147711facfSdinak 
41549e21299Sdinak 	/* Parse command line options.  Do NOT i18n/l10n. */
416*99ebb4caSwyllys 	while ((opt = getopt_av(argc, argv,
417*99ebb4caSwyllys 		"T:(token)i:(infile)"
418*99ebb4caSwyllys 		"k:(keystore)y:(objtype)"
419*99ebb4caSwyllys 		"d:(dir)p:(prefix)"
420*99ebb4caSwyllys 		"n:(certlabel)N:(label)"
421*99ebb4caSwyllys 		"K:(outkey)c:(outcert)"
422*99ebb4caSwyllys 		"v:(verifycrl)l:(outcrl)"
423*99ebb4caSwyllys 		"t:(trust)D:(keydir)F:(outformat)")) != EOF) {
424*99ebb4caSwyllys 		if (EMPTYSTRING(optarg_av))
425*99ebb4caSwyllys 			return (PK_ERR_USAGE);
42649e21299Sdinak 		switch (opt) {
42749e21299Sdinak 		case 'T':	/* token specifier */
42849e21299Sdinak 			if (token_spec)
42949e21299Sdinak 				return (PK_ERR_USAGE);
43049e21299Sdinak 			token_spec = optarg_av;
43149e21299Sdinak 			break;
432*99ebb4caSwyllys 		case 'c':	/* output cert file name */
433*99ebb4caSwyllys 			if (certfile)
434*99ebb4caSwyllys 				return (PK_ERR_USAGE);
435*99ebb4caSwyllys 			certfile = optarg_av;
436*99ebb4caSwyllys 			break;
437*99ebb4caSwyllys 		case 'l':	/* output CRL file name */
438*99ebb4caSwyllys 			if (crlfile)
439*99ebb4caSwyllys 				return (PK_ERR_USAGE);
440*99ebb4caSwyllys 			crlfile = optarg_av;
441*99ebb4caSwyllys 			break;
442*99ebb4caSwyllys 		case 'K':	/* output key file name */
443*99ebb4caSwyllys 			if (keyfile)
444*99ebb4caSwyllys 				return (PK_ERR_USAGE);
445*99ebb4caSwyllys 			keyfile = optarg_av;
446*99ebb4caSwyllys 			break;
44749e21299Sdinak 		case 'i':	/* input file name */
44849e21299Sdinak 			if (filename)
44949e21299Sdinak 				return (PK_ERR_USAGE);
45049e21299Sdinak 			filename = optarg_av;
45149e21299Sdinak 			break;
452*99ebb4caSwyllys 		case 'k':
453*99ebb4caSwyllys 			kstype = KS2Int(optarg_av);
454*99ebb4caSwyllys 			if (kstype == 0)
455*99ebb4caSwyllys 				return (PK_ERR_USAGE);
456*99ebb4caSwyllys 			break;
457*99ebb4caSwyllys 		case 'y':
458*99ebb4caSwyllys 			oclass = OT2Int(optarg_av);
459*99ebb4caSwyllys 			if (oclass == -1)
460*99ebb4caSwyllys 				return (PK_ERR_USAGE);
461*99ebb4caSwyllys 			break;
462*99ebb4caSwyllys 		case 'd':
463*99ebb4caSwyllys 			dir = optarg_av;
464*99ebb4caSwyllys 			break;
465*99ebb4caSwyllys 		case 'D':
466*99ebb4caSwyllys 			keydir = optarg_av;
467*99ebb4caSwyllys 			break;
468*99ebb4caSwyllys 		case 'p':
469*99ebb4caSwyllys 			if (prefix)
470*99ebb4caSwyllys 				return (PK_ERR_USAGE);
471*99ebb4caSwyllys 			prefix = optarg_av;
472*99ebb4caSwyllys 			break;
473*99ebb4caSwyllys 		case 'n':
474*99ebb4caSwyllys 		case 'N':
475*99ebb4caSwyllys 			if (certlabel)
476*99ebb4caSwyllys 				return (PK_ERR_USAGE);
477*99ebb4caSwyllys 			certlabel = optarg_av;
478*99ebb4caSwyllys 			break;
479*99ebb4caSwyllys 		case 'F':
480*99ebb4caSwyllys 			okfmt = Str2Format(optarg_av);
481*99ebb4caSwyllys 			if (okfmt == KMF_FORMAT_UNDEF)
482*99ebb4caSwyllys 				return (PK_ERR_USAGE);
483*99ebb4caSwyllys 			break;
484*99ebb4caSwyllys 		case 't':
485*99ebb4caSwyllys 			if (trustflags)
486*99ebb4caSwyllys 				return (PK_ERR_USAGE);
487*99ebb4caSwyllys 			trustflags = optarg_av;
488*99ebb4caSwyllys 			break;
489*99ebb4caSwyllys 		case 'v':
490*99ebb4caSwyllys 			verify_crl = optarg_av;
491*99ebb4caSwyllys 			if (tolower(verify_crl[0]) == 'y')
492*99ebb4caSwyllys 				verify_crl_flag = B_TRUE;
493*99ebb4caSwyllys 			else if (tolower(verify_crl[0]) == 'n')
494*99ebb4caSwyllys 				verify_crl_flag = B_FALSE;
495*99ebb4caSwyllys 			else
496*99ebb4caSwyllys 				return (PK_ERR_USAGE);
497*99ebb4caSwyllys 			break;
49849e21299Sdinak 		default:
49949e21299Sdinak 			return (PK_ERR_USAGE);
50049e21299Sdinak 			break;
50149e21299Sdinak 		}
50249e21299Sdinak 	}
50349e21299Sdinak 
504*99ebb4caSwyllys 	/* Assume keystore = PKCS#11 if not specified */
505*99ebb4caSwyllys 	if (kstype == 0)
506*99ebb4caSwyllys 		kstype = KMF_KEYSTORE_PK11TOKEN;
5077711facfSdinak 
50849e21299Sdinak 	/* Filename arg is required. */
509*99ebb4caSwyllys 	if (EMPTYSTRING(filename)) {
510*99ebb4caSwyllys 		cryptoerror(LOG_STDERR, gettext("The 'infile' parameter"
511*99ebb4caSwyllys 			"is required for the import operation.\n"));
5127711facfSdinak 		return (PK_ERR_USAGE);
513*99ebb4caSwyllys 	}
5147711facfSdinak 
51549e21299Sdinak 	/* No additional args allowed. */
51649e21299Sdinak 	argc -= optind_av;
51749e21299Sdinak 	argv += optind_av;
51849e21299Sdinak 	if (argc)
51949e21299Sdinak 		return (PK_ERR_USAGE);
5207711facfSdinak 
521*99ebb4caSwyllys 	/* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
522*99ebb4caSwyllys 	if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
523*99ebb4caSwyllys 		kstype != KMF_KEYSTORE_PK11TOKEN) {
5247711facfSdinak 
525*99ebb4caSwyllys 		(void) fprintf(stderr, gettext("The objtype parameter "
526*99ebb4caSwyllys 			"is only relevant if keystore=pkcs11\n"));
527*99ebb4caSwyllys 		return (PK_ERR_USAGE);
528*99ebb4caSwyllys 	}
5297711facfSdinak 
530*99ebb4caSwyllys 	/*
531*99ebb4caSwyllys 	 * You must specify a certlabel (cert label) when importing
532*99ebb4caSwyllys 	 * into NSS or PKCS#11.
533*99ebb4caSwyllys 	 */
534*99ebb4caSwyllys 	if (kstype == KMF_KEYSTORE_NSS &&
535*99ebb4caSwyllys 		(oclass != PK_CRL_OBJ) && EMPTYSTRING(certlabel)) {
536*99ebb4caSwyllys 		cryptoerror(LOG_STDERR, gettext("The 'label' argument "
537*99ebb4caSwyllys 			"is required for this operation\n"));
538*99ebb4caSwyllys 		return (PK_ERR_USAGE);
5397711facfSdinak 	}
5407711facfSdinak 
541*99ebb4caSwyllys 	/*
542*99ebb4caSwyllys 	 * PKCS11 only imports PKCS#12 files or PEM/DER Cert files.
543*99ebb4caSwyllys 	 */
544*99ebb4caSwyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
545*99ebb4caSwyllys 		/* we do not import private keys except in PKCS12 bundles */
546*99ebb4caSwyllys 		if (oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)) {
547*99ebb4caSwyllys 			cryptoerror(LOG_STDERR, gettext(
548*99ebb4caSwyllys 				"The PKCS11 keystore only imports PKCS12 "
549*99ebb4caSwyllys 				"files or raw certificate data files "
550*99ebb4caSwyllys 				" or CRL file.\n"));
551*99ebb4caSwyllys 			return (PK_ERR_USAGE);
552*99ebb4caSwyllys 		}
5537711facfSdinak 	}
5547711facfSdinak 
555*99ebb4caSwyllys 	if ((rv = KMF_GetFileFormat(filename, &kfmt)) != KMF_OK) {
5567711facfSdinak 		cryptoerror(LOG_STDERR,
557*99ebb4caSwyllys 			gettext("File format not recognized."));
558*99ebb4caSwyllys 		return (rv);
5597711facfSdinak 	}
560*99ebb4caSwyllys 	if (oclass == 0 && (kfmt == KMF_FORMAT_ASN1 ||
561*99ebb4caSwyllys 		kfmt == KMF_FORMAT_PEM))
562*99ebb4caSwyllys 		oclass = PK_CERT_OBJ;
5637711facfSdinak 
564*99ebb4caSwyllys 	if (kstype == KMF_KEYSTORE_NSS) {
565*99ebb4caSwyllys 		if (oclass == PK_CRL_OBJ &&
566*99ebb4caSwyllys 			(kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
567*99ebb4caSwyllys 			cryptoerror(LOG_STDERR, gettext(
568*99ebb4caSwyllys 				"CRL data can only be imported as DER or "
569*99ebb4caSwyllys 				"PEM format"));
570*99ebb4caSwyllys 			return (PK_ERR_USAGE);
571*99ebb4caSwyllys 		}
5727711facfSdinak 
573*99ebb4caSwyllys 		if (oclass == PK_CERT_OBJ &&
574*99ebb4caSwyllys 			(kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
575*99ebb4caSwyllys 			cryptoerror(LOG_STDERR, gettext(
576*99ebb4caSwyllys 				"Certificates can only be imported as DER or "
577*99ebb4caSwyllys 				"PEM format"));
578*99ebb4caSwyllys 			return (PK_ERR_USAGE);
579*99ebb4caSwyllys 		}
5807711facfSdinak 
581*99ebb4caSwyllys 		/* we do not import private keys except in PKCS12 bundles */
582*99ebb4caSwyllys 		if (oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)) {
583*99ebb4caSwyllys 			cryptoerror(LOG_STDERR, gettext(
584*99ebb4caSwyllys 				"Private key data can only be imported as part "
585*99ebb4caSwyllys 				"of a PKCS12 file.\n"));
586*99ebb4caSwyllys 			return (PK_ERR_USAGE);
587*99ebb4caSwyllys 		}
5887711facfSdinak 	}
5897711facfSdinak 
590*99ebb4caSwyllys 	if (kstype == KMF_KEYSTORE_OPENSSL && oclass != PK_CRL_OBJ) {
591*99ebb4caSwyllys 		if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) {
5927711facfSdinak 			cryptoerror(LOG_STDERR, gettext(
593*99ebb4caSwyllys 				"The 'outkey' and 'outcert' parameters "
594*99ebb4caSwyllys 				"are required for the import operation "
595*99ebb4caSwyllys 				"when the 'file' keystore is used.\n"));
596*99ebb4caSwyllys 			return (PK_ERR_USAGE);
5977711facfSdinak 		}
598*99ebb4caSwyllys 	}
5997711facfSdinak 
600*99ebb4caSwyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec))
601*99ebb4caSwyllys 		token_spec = PK_DEFAULT_PK11TOKEN;
602*99ebb4caSwyllys 	else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec))
603*99ebb4caSwyllys 		token_spec = DEFAULT_NSS_TOKEN;
604*99ebb4caSwyllys 
605*99ebb4caSwyllys 	if (kfmt == KMF_FORMAT_PKCS12) {
606*99ebb4caSwyllys 		(void) get_pk12_password(&pk12cred);
607*99ebb4caSwyllys 
608*99ebb4caSwyllys 		if (kstype == KMF_KEYSTORE_PK11TOKEN ||
609*99ebb4caSwyllys 			kstype == KMF_KEYSTORE_NSS)
610*99ebb4caSwyllys 			(void) get_token_password(kstype, token_spec,
611*99ebb4caSwyllys 				&tokencred);
612*99ebb4caSwyllys 	}
613*99ebb4caSwyllys 
614*99ebb4caSwyllys 	if ((rv = KMF_Initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
615*99ebb4caSwyllys 		cryptoerror(LOG_STDERR, gettext("Error initializing "
616*99ebb4caSwyllys 				"KMF: 0x%02x\n"), rv);
617*99ebb4caSwyllys 		goto end;
618*99ebb4caSwyllys 	}
619*99ebb4caSwyllys 
620*99ebb4caSwyllys 	switch (kstype) {
621*99ebb4caSwyllys 		case KMF_KEYSTORE_PK11TOKEN:
622*99ebb4caSwyllys 			if (kfmt == KMF_FORMAT_PKCS12)
623*99ebb4caSwyllys 				rv = pk_import_pk12_pk11(
624*99ebb4caSwyllys 					kmfhandle,
625*99ebb4caSwyllys 					&pk12cred,
626*99ebb4caSwyllys 					&tokencred,
627*99ebb4caSwyllys 					certlabel,
628*99ebb4caSwyllys 					token_spec,
629*99ebb4caSwyllys 					filename);
630*99ebb4caSwyllys 			else if (oclass == PK_CERT_OBJ)
631*99ebb4caSwyllys 				rv = pk_import_cert(
632*99ebb4caSwyllys 					kmfhandle,
633*99ebb4caSwyllys 					kstype,
634*99ebb4caSwyllys 					certlabel,
635*99ebb4caSwyllys 					token_spec,
636*99ebb4caSwyllys 					filename,
637*99ebb4caSwyllys 					NULL, NULL, NULL);
638*99ebb4caSwyllys 			else if (oclass == PK_CRL_OBJ)
639*99ebb4caSwyllys 				rv = pk_import_file_crl(
640*99ebb4caSwyllys 					kmfhandle,
641*99ebb4caSwyllys 					filename,
642*99ebb4caSwyllys 					crlfile,
643*99ebb4caSwyllys 					dir,
644*99ebb4caSwyllys 					okfmt);
6457711facfSdinak 			break;
646*99ebb4caSwyllys 		case KMF_KEYSTORE_NSS:
647*99ebb4caSwyllys 			if (dir == NULL)
648*99ebb4caSwyllys 				dir = PK_DEFAULT_DIRECTORY;
649*99ebb4caSwyllys 			if (kfmt == KMF_FORMAT_PKCS12)
650*99ebb4caSwyllys 				rv = pk_import_pk12_nss(
651*99ebb4caSwyllys 					kmfhandle, &pk12cred,
652*99ebb4caSwyllys 					&tokencred,
653*99ebb4caSwyllys 					token_spec, dir, prefix,
654*99ebb4caSwyllys 					certlabel, trustflags, filename);
655*99ebb4caSwyllys 			else if (oclass == PK_CERT_OBJ) {
656*99ebb4caSwyllys 				rv = pk_import_cert(
657*99ebb4caSwyllys 					kmfhandle, kstype,
658*99ebb4caSwyllys 					certlabel, token_spec,
659*99ebb4caSwyllys 					filename, dir, prefix, trustflags);
660*99ebb4caSwyllys 			} else if (oclass == PK_CRL_OBJ) {
661*99ebb4caSwyllys 				rv = pk_import_nss_crl(
662*99ebb4caSwyllys 					kmfhandle,
663*99ebb4caSwyllys 					verify_crl_flag,
664*99ebb4caSwyllys 					filename,
665*99ebb4caSwyllys 					dir,
666*99ebb4caSwyllys 					prefix);
667*99ebb4caSwyllys 			}
668*99ebb4caSwyllys 			break;
669*99ebb4caSwyllys 		case KMF_KEYSTORE_OPENSSL:
670*99ebb4caSwyllys 			if (kfmt == KMF_FORMAT_PKCS12)
671*99ebb4caSwyllys 				rv = pk_import_pk12_files(
672*99ebb4caSwyllys 					kmfhandle, &pk12cred,
673*99ebb4caSwyllys 					filename, certfile, keyfile,
674*99ebb4caSwyllys 					dir, keydir, okfmt);
675*99ebb4caSwyllys 			else if (oclass == PK_CRL_OBJ) {
676*99ebb4caSwyllys 				rv = pk_import_file_crl(
677*99ebb4caSwyllys 					kmfhandle,
678*99ebb4caSwyllys 					filename,
679*99ebb4caSwyllys 					crlfile,
680*99ebb4caSwyllys 					dir,
681*99ebb4caSwyllys 					okfmt);
682*99ebb4caSwyllys 			} else
683*99ebb4caSwyllys 				/*
684*99ebb4caSwyllys 				 * It doesn't make sense to import anything
685*99ebb4caSwyllys 				 * else for the files plugin.
686*99ebb4caSwyllys 				 */
687*99ebb4caSwyllys 				return (PK_ERR_USAGE);
688*99ebb4caSwyllys 			break;
689*99ebb4caSwyllys 		default:
690*99ebb4caSwyllys 			rv = PK_ERR_USAGE;
691*99ebb4caSwyllys 			break;
692*99ebb4caSwyllys 	}
6937711facfSdinak 
694*99ebb4caSwyllys end:
695*99ebb4caSwyllys 	if (rv != KMF_OK)
696*99ebb4caSwyllys 		display_error(kmfhandle, rv,
697*99ebb4caSwyllys 			gettext("Error importing objects"));
6987711facfSdinak 
699*99ebb4caSwyllys 	if (tokencred.cred != NULL)
700*99ebb4caSwyllys 		free(tokencred.cred);
7017711facfSdinak 
702*99ebb4caSwyllys 	if (pk12cred.cred != NULL)
703*99ebb4caSwyllys 		free(pk12cred.cred);
7047711facfSdinak 
705*99ebb4caSwyllys 	(void) KMF_Finalize(kmfhandle);
706*99ebb4caSwyllys 
707*99ebb4caSwyllys 	if (rv != KMF_OK)
708*99ebb4caSwyllys 		return (PK_ERR_USAGE);
7097711facfSdinak 
7107711facfSdinak 	return (0);
7117711facfSdinak }
712