117Sdinak /*
217Sdinak  * CDDL HEADER START
317Sdinak  *
417Sdinak  * The contents of this file are subject to the terms of the
5*3089Swyllys  * Common Development and Distribution License (the "License").
6*3089Swyllys  * 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
2017Sdinak  */
2117Sdinak /*
22*3089Swyllys  * 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 import operation for this tool.
3017Sdinak  * The basic flow of the process is to decrypt the PKCS#12
3117Sdinak  * input file if it has a password, parse the elements in
3217Sdinak  * the file, find the soft token, log into it, import the
3317Sdinak  * PKCS#11 objects into the soft token, and log out.
3417Sdinak  */
3517Sdinak 
3617Sdinak #include <stdio.h>
3717Sdinak #include <stdlib.h>
3817Sdinak #include <string.h>
39*3089Swyllys #include <ctype.h>
4017Sdinak #include <errno.h>
4117Sdinak #include <fcntl.h>
4217Sdinak #include <sys/types.h>
4317Sdinak #include <sys/stat.h>
4417Sdinak #include "common.h"
45*3089Swyllys 
46*3089Swyllys #include <kmfapi.h>
4717Sdinak 
48*3089Swyllys static KMF_RETURN
49*3089Swyllys pk_import_pk12_files(KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *cred,
50*3089Swyllys 	char *outfile, char *certfile, char *keyfile,
51*3089Swyllys 	char *dir, char *keydir, KMF_ENCODE_FORMAT outformat)
5217Sdinak {
53*3089Swyllys 	KMF_RETURN rv = KMF_OK;
54*3089Swyllys 	KMF_DATA *certs = NULL;
55*3089Swyllys 	KMF_RAW_KEY_DATA *keys = NULL;
56*3089Swyllys 	int ncerts = 0;
57*3089Swyllys 	int nkeys = 0;
58*3089Swyllys 	int i;
5917Sdinak 
60*3089Swyllys 	rv = KMF_ImportPK12(kmfhandle, outfile, cred,
61*3089Swyllys 		&certs, &ncerts, &keys, &nkeys);
6217Sdinak 
63*3089Swyllys 	if (rv == KMF_OK) {
64*3089Swyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
65*3089Swyllys 			"key(s) in %s\n"), ncerts, nkeys, outfile);
6617Sdinak 	}
6717Sdinak 
68*3089Swyllys 	if (rv == KMF_OK && ncerts > 0) {
69*3089Swyllys 		KMF_STORECERT_PARAMS params;
70*3089Swyllys 		char newcertfile[MAXPATHLEN];
71*3089Swyllys 
72*3089Swyllys 		(void) memset(&params, 0, sizeof (KMF_STORECERT_PARAMS));
73*3089Swyllys 		params.kstype = KMF_KEYSTORE_OPENSSL;
74*3089Swyllys 		params.sslparms.dirpath = dir;
75*3089Swyllys 		params.sslparms.format = outformat;
76*3089Swyllys 
77*3089Swyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
78*3089Swyllys 			/*
79*3089Swyllys 			 * If storing more than 1 cert, gotta change
80*3089Swyllys 			 * the name so we don't overwrite the previous one.
81*3089Swyllys 			 * Just append a _# to the name.
82*3089Swyllys 			 */
83*3089Swyllys 			if (i > 0) {
84*3089Swyllys 				(void) snprintf(newcertfile,
85*3089Swyllys 					sizeof (newcertfile),
86*3089Swyllys 					"%s_%d", certfile, i);
87*3089Swyllys 				params.sslparms.certfile = newcertfile;
88*3089Swyllys 			} else {
89*3089Swyllys 				params.sslparms.certfile = certfile;
90*3089Swyllys 			}
91*3089Swyllys 			rv = KMF_StoreCert(kmfhandle, &params, &certs[i]);
92*3089Swyllys 		}
93*3089Swyllys 	}
94*3089Swyllys 	if (rv == KMF_OK && nkeys > 0) {
95*3089Swyllys 		KMF_STOREKEY_PARAMS skparms;
96*3089Swyllys 		char newkeyfile[MAXPATHLEN];
97*3089Swyllys 
98*3089Swyllys 		(void) memset(&skparms, 0, sizeof (skparms));
9917Sdinak 
100*3089Swyllys 		/* The order of certificates and keys should match */
101*3089Swyllys 		for (i = 0; rv == KMF_OK && i < nkeys; i++) {
102*3089Swyllys 			skparms.kstype = KMF_KEYSTORE_OPENSSL;
103*3089Swyllys 			skparms.sslparms.dirpath = keydir;
104*3089Swyllys 			skparms.sslparms.format = outformat;
105*3089Swyllys 			skparms.cred = *cred;
106*3089Swyllys 			skparms.certificate = &certs[i];
107*3089Swyllys 
108*3089Swyllys 			if (i > 0) {
109*3089Swyllys 				(void) snprintf(newkeyfile,
110*3089Swyllys 					sizeof (newkeyfile),
111*3089Swyllys 					"%s_%d", keyfile, i);
112*3089Swyllys 				skparms.sslparms.keyfile = newkeyfile;
113*3089Swyllys 			} else {
114*3089Swyllys 				skparms.sslparms.keyfile = keyfile;
115*3089Swyllys 			}
11617Sdinak 
117*3089Swyllys 			rv = KMF_StorePrivateKey(kmfhandle, &skparms,
118*3089Swyllys 				&keys[i]);
119*3089Swyllys 		}
120*3089Swyllys 	}
121*3089Swyllys 	/*
122*3089Swyllys 	 * Cleanup memory.
123*3089Swyllys 	 */
124*3089Swyllys 	if (certs) {
125*3089Swyllys 		for (i = 0; i < ncerts; i++)
126*3089Swyllys 			KMF_FreeData(&certs[i]);
127*3089Swyllys 		free(certs);
128*3089Swyllys 	}
129*3089Swyllys 	if (keys) {
130*3089Swyllys 		for (i = 0; i < nkeys; i++)
131*3089Swyllys 			KMF_FreeRawKey(&keys[i]);
132*3089Swyllys 		free(keys);
13317Sdinak 	}
13417Sdinak 
13517Sdinak 
136*3089Swyllys 	return (rv);
13717Sdinak }
13817Sdinak 
139*3089Swyllys 
140*3089Swyllys static KMF_RETURN
141*3089Swyllys pk_import_pk12_nss(
142*3089Swyllys 	KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *kmfcred,
143*3089Swyllys 	KMF_CREDENTIAL *tokencred,
144*3089Swyllys 	char *token_spec, char *dir, char *prefix,
145*3089Swyllys 	char *nickname, char *trustflags, char *filename)
14617Sdinak {
147*3089Swyllys 	KMF_RETURN rv = KMF_OK;
148*3089Swyllys 	KMF_DATA *certs = NULL;
149*3089Swyllys 	KMF_RAW_KEY_DATA *keys = NULL;
150*3089Swyllys 	int ncerts = 0;
151*3089Swyllys 	int nkeys = 0;
152*3089Swyllys 	int i;
153*3089Swyllys 
154*3089Swyllys 	rv = configure_nss(kmfhandle, dir, prefix);
155*3089Swyllys 	if (rv != KMF_OK)
156*3089Swyllys 		return (rv);
157*3089Swyllys 
158*3089Swyllys 	rv = KMF_ImportPK12(kmfhandle, filename, kmfcred,
159*3089Swyllys 		&certs, &ncerts, &keys, &nkeys);
160*3089Swyllys 
161*3089Swyllys 	if (rv == KMF_OK)
162*3089Swyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
163*3089Swyllys 			"key(s) in %s\n"), ncerts, nkeys, filename);
16417Sdinak 
165*3089Swyllys 	if (rv == KMF_OK) {
166*3089Swyllys 		KMF_STORECERT_PARAMS params;
16717Sdinak 
168*3089Swyllys 		(void) memset(&params, 0, sizeof (KMF_STORECERT_PARAMS));
169*3089Swyllys 		params.kstype = KMF_KEYSTORE_NSS;
170*3089Swyllys 		params.nssparms.slotlabel = token_spec;
171*3089Swyllys 		params.nssparms.trustflag = trustflags;
17217Sdinak 
173*3089Swyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
174*3089Swyllys 			if (i == 0)
175*3089Swyllys 				params.certLabel = nickname;
176*3089Swyllys 			else
177*3089Swyllys 				params.certLabel = NULL;
17817Sdinak 
179*3089Swyllys 			rv = KMF_StoreCert(kmfhandle, &params, &certs[i]);
180*3089Swyllys 		}
181*3089Swyllys 		if (rv != KMF_OK) {
182*3089Swyllys 			display_error(kmfhandle, rv,
183*3089Swyllys 				gettext("Error storing certificate "
184*3089Swyllys 					"in PKCS11 token"));
185*3089Swyllys 		}
18617Sdinak 	}
18717Sdinak 
188*3089Swyllys 	if (rv == KMF_OK) {
189*3089Swyllys 		KMF_STOREKEY_PARAMS skparms;
190*3089Swyllys 
191*3089Swyllys 		/* The order of certificates and keys should match */
192*3089Swyllys 		for (i = 0; i < nkeys; i++) {
193*3089Swyllys 			(void) memset(&skparms, 0,
194*3089Swyllys 				sizeof (KMF_STOREKEY_PARAMS));
195*3089Swyllys 			skparms.kstype = KMF_KEYSTORE_NSS;
196*3089Swyllys 			skparms.cred = *tokencred;
197*3089Swyllys 			skparms.label = nickname;
198*3089Swyllys 			skparms.certificate = &certs[i];
199*3089Swyllys 			skparms.nssparms.slotlabel = token_spec;
200*3089Swyllys 
201*3089Swyllys 			rv = KMF_StorePrivateKey(kmfhandle, &skparms, &keys[i]);
202*3089Swyllys 		}
203*3089Swyllys 	}
204*3089Swyllys 
205*3089Swyllys 	/*
206*3089Swyllys 	 * Cleanup memory.
207*3089Swyllys 	 */
208*3089Swyllys 	if (certs) {
209*3089Swyllys 		for (i = 0; i < ncerts; i++)
210*3089Swyllys 			KMF_FreeData(&certs[i]);
211*3089Swyllys 		free(certs);
212*3089Swyllys 	}
213*3089Swyllys 	if (keys) {
214*3089Swyllys 		for (i = 0; i < nkeys; i++)
215*3089Swyllys 			KMF_FreeRawKey(&keys[i]);
216*3089Swyllys 		free(keys);
21717Sdinak 	}
21817Sdinak 
219*3089Swyllys 	return (rv);
220*3089Swyllys }
22117Sdinak 
222*3089Swyllys static KMF_RETURN
223*3089Swyllys pk_import_cert(
224*3089Swyllys 	KMF_HANDLE_T kmfhandle,
225*3089Swyllys 	KMF_KEYSTORE_TYPE kstype,
226*3089Swyllys 	char *label, char *token_spec, char *filename,
227*3089Swyllys 	char *dir, char *prefix, char *trustflags)
228*3089Swyllys {
229*3089Swyllys 	KMF_RETURN rv = KMF_OK;
230*3089Swyllys 	KMF_IMPORTCERT_PARAMS params;
23117Sdinak 
232*3089Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
233*3089Swyllys 		rv = select_token(kmfhandle, token_spec, FALSE);
23417Sdinak 
235*3089Swyllys 		if (rv != KMF_OK) {
23617Sdinak 			return (rv);
23717Sdinak 		}
238*3089Swyllys 	}
23917Sdinak 
240*3089Swyllys 	(void) memset(&params, 0, sizeof (params));
241*3089Swyllys 	params.kstype = kstype;
242*3089Swyllys 	params.certfile = filename;
243*3089Swyllys 	params.certLabel = label;
24417Sdinak 
245*3089Swyllys 	if (kstype == KMF_KEYSTORE_NSS) {
246*3089Swyllys 		rv = configure_nss(kmfhandle, dir, prefix);
247*3089Swyllys 		if (rv != KMF_OK)
24817Sdinak 			return (rv);
249*3089Swyllys 		params.nssparms.trustflag = trustflags;
250*3089Swyllys 		params.nssparms.slotlabel = token_spec;
25117Sdinak 	}
25217Sdinak 
253*3089Swyllys 	rv = KMF_ImportCert(kmfhandle, &params);
254*3089Swyllys 
255*3089Swyllys 	return (rv);
256*3089Swyllys }
257*3089Swyllys 
258*3089Swyllys static KMF_RETURN
259*3089Swyllys pk_import_file_crl(void *kmfhandle,
260*3089Swyllys 	char *infile,
261*3089Swyllys 	char *outfile,
262*3089Swyllys 	char *outdir,
263*3089Swyllys 	KMF_ENCODE_FORMAT outfmt)
264*3089Swyllys {
265*3089Swyllys 	KMF_IMPORTCRL_PARAMS 	icrl_params;
266*3089Swyllys 	KMF_OPENSSL_PARAMS sslparams;
267*3089Swyllys 
268*3089Swyllys 	sslparams.crlfile = infile;
269*3089Swyllys 	sslparams.dirpath = outdir;
270*3089Swyllys 	sslparams.outcrlfile = outfile;
271*3089Swyllys 	sslparams.format = outfmt;
272*3089Swyllys 	sslparams.crl_check = B_FALSE;
273*3089Swyllys 
274*3089Swyllys 	icrl_params.kstype = KMF_KEYSTORE_OPENSSL;
275*3089Swyllys 	icrl_params.sslparms = sslparams;
276*3089Swyllys 
277*3089Swyllys 	return (KMF_ImportCRL(kmfhandle, &icrl_params));
278*3089Swyllys 
279*3089Swyllys }
280*3089Swyllys 
281*3089Swyllys static KMF_RETURN
282*3089Swyllys pk_import_nss_crl(void *kmfhandle,
283*3089Swyllys 	boolean_t verify_crl_flag,
284*3089Swyllys 	char *infile,
285*3089Swyllys 	char *outdir,
286*3089Swyllys 	char *prefix)
287*3089Swyllys {
288*3089Swyllys 	KMF_IMPORTCRL_PARAMS 	icrl_params;
289*3089Swyllys 	KMF_RETURN rv;
290*3089Swyllys 
291*3089Swyllys 	rv = configure_nss(kmfhandle, outdir, prefix);
292*3089Swyllys 	if (rv != KMF_OK)
293*3089Swyllys 		return (rv);
294*3089Swyllys 
295*3089Swyllys 	icrl_params.kstype = KMF_KEYSTORE_NSS;
296*3089Swyllys 	icrl_params.nssparms.slotlabel = NULL;
297*3089Swyllys 	icrl_params.nssparms.crlfile = infile;
298*3089Swyllys 	icrl_params.nssparms.crl_check = verify_crl_flag;
299*3089Swyllys 
300*3089Swyllys 	return (KMF_ImportCRL(kmfhandle, &icrl_params));
301*3089Swyllys 
302*3089Swyllys }
303*3089Swyllys 
304*3089Swyllys static KMF_RETURN
305*3089Swyllys pk_import_pk12_pk11(
306*3089Swyllys 	KMF_HANDLE_T kmfhandle,
307*3089Swyllys 	KMF_CREDENTIAL *p12cred,
308*3089Swyllys 	KMF_CREDENTIAL *tokencred,
309*3089Swyllys 	char *label, char *token_spec,
310*3089Swyllys 	char *filename)
311*3089Swyllys {
312*3089Swyllys 	KMF_RETURN rv = KMF_OK;
313*3089Swyllys 	KMF_DATA *certs = NULL;
314*3089Swyllys 	KMF_RAW_KEY_DATA *keys = NULL;
315*3089Swyllys 	int ncerts = 0;
316*3089Swyllys 	int nkeys = 0;
317*3089Swyllys 	int i;
318*3089Swyllys 
319*3089Swyllys 	rv = select_token(kmfhandle, token_spec, FALSE);
320*3089Swyllys 
321*3089Swyllys 	if (rv != KMF_OK) {
32217Sdinak 		return (rv);
32317Sdinak 	}
32417Sdinak 
325*3089Swyllys 	rv = KMF_ImportPK12(kmfhandle, filename, p12cred,
326*3089Swyllys 		&certs, &ncerts, &keys, &nkeys);
327*3089Swyllys 
328*3089Swyllys 	if (rv == KMF_OK) {
329*3089Swyllys 		KMF_STOREKEY_PARAMS skparms;
330*3089Swyllys 
331*3089Swyllys 		/* The order of certificates and keys should match */
332*3089Swyllys 		for (i = 0; i < nkeys; i++) {
333*3089Swyllys 			(void) memset(&skparms, 0,
334*3089Swyllys 				sizeof (KMF_STOREKEY_PARAMS));
335*3089Swyllys 			skparms.kstype = KMF_KEYSTORE_PK11TOKEN;
336*3089Swyllys 			skparms.certificate = &certs[i];
337*3089Swyllys 			if (tokencred != NULL)
338*3089Swyllys 				skparms.cred = *tokencred;
339*3089Swyllys 			if (i == 0)
340*3089Swyllys 				skparms.label = label;
341*3089Swyllys 			else
342*3089Swyllys 				skparms.label = NULL;
343*3089Swyllys 
344*3089Swyllys 			rv = KMF_StorePrivateKey(kmfhandle, &skparms,
345*3089Swyllys 				&keys[i]);
346*3089Swyllys 		}
347*3089Swyllys 	}
348*3089Swyllys 
349*3089Swyllys 	if (rv == KMF_OK) {
350*3089Swyllys 		KMF_STORECERT_PARAMS params;
351*3089Swyllys 
352*3089Swyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
353*3089Swyllys 			"key(s) in %s\n"), ncerts, nkeys, filename);
354*3089Swyllys 		(void) memset(&params, 0, sizeof (KMF_STORECERT_PARAMS));
355*3089Swyllys 
356*3089Swyllys 		params.kstype = KMF_KEYSTORE_PK11TOKEN;
357*3089Swyllys 
358*3089Swyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
359*3089Swyllys 			if (i == 0)
360*3089Swyllys 				params.certLabel = label;
361*3089Swyllys 			else
362*3089Swyllys 				params.certLabel = NULL;
363*3089Swyllys 
364*3089Swyllys 			rv = KMF_StoreCert(kmfhandle, &params, &certs[i]);
365*3089Swyllys 		}
366*3089Swyllys 	}
367*3089Swyllys 
368*3089Swyllys 	/*
369*3089Swyllys 	 * Cleanup memory.
370*3089Swyllys 	 */
371*3089Swyllys 	if (certs) {
372*3089Swyllys 		for (i = 0; i < ncerts; i++)
373*3089Swyllys 			KMF_FreeData(&certs[i]);
374*3089Swyllys 		free(certs);
375*3089Swyllys 	}
376*3089Swyllys 	if (keys) {
377*3089Swyllys 		for (i = 0; i < nkeys; i++)
378*3089Swyllys 			KMF_FreeRawKey(&keys[i]);
379*3089Swyllys 		free(keys);
380*3089Swyllys 	}
381*3089Swyllys 
382*3089Swyllys 	return (rv);
38317Sdinak }
38417Sdinak 
38517Sdinak /*
386*3089Swyllys  * Import objects from into KMF repositories.
38717Sdinak  */
38817Sdinak int
38917Sdinak pk_import(int argc, char *argv[])
39017Sdinak {
391864Sdinak 	int		opt;
392864Sdinak 	extern int	optind_av;
393864Sdinak 	extern char	*optarg_av;
394864Sdinak 	char		*token_spec = NULL;
39517Sdinak 	char		*filename = NULL;
396*3089Swyllys 	char		*keyfile = NULL;
397*3089Swyllys 	char		*certfile = NULL;
398*3089Swyllys 	char		*crlfile = NULL;
399*3089Swyllys 	char		*certlabel = NULL;
400*3089Swyllys 	char		*dir = NULL;
401*3089Swyllys 	char		*keydir = NULL;
402*3089Swyllys 	char		*prefix = NULL;
403*3089Swyllys 	char		*trustflags = NULL;
404*3089Swyllys 	char		*verify_crl = NULL;
405*3089Swyllys 	boolean_t	verify_crl_flag = B_FALSE;
406*3089Swyllys 	int		oclass = 0;
407*3089Swyllys 	KMF_KEYSTORE_TYPE	kstype = 0;
408*3089Swyllys 	KMF_ENCODE_FORMAT	kfmt = 0;
409*3089Swyllys 	KMF_ENCODE_FORMAT	okfmt = KMF_FORMAT_ASN1;
410*3089Swyllys 	KMF_RETURN		rv = KMF_OK;
411*3089Swyllys 	KMF_CREDENTIAL	pk12cred = { NULL, 0 };
412*3089Swyllys 	KMF_CREDENTIAL	tokencred = { NULL, 0 };
413*3089Swyllys 	KMF_HANDLE_T	kmfhandle = NULL;
41417Sdinak 
415864Sdinak 	/* Parse command line options.  Do NOT i18n/l10n. */
416*3089Swyllys 	while ((opt = getopt_av(argc, argv,
417*3089Swyllys 		"T:(token)i:(infile)"
418*3089Swyllys 		"k:(keystore)y:(objtype)"
419*3089Swyllys 		"d:(dir)p:(prefix)"
420*3089Swyllys 		"n:(certlabel)N:(label)"
421*3089Swyllys 		"K:(outkey)c:(outcert)"
422*3089Swyllys 		"v:(verifycrl)l:(outcrl)"
423*3089Swyllys 		"t:(trust)D:(keydir)F:(outformat)")) != EOF) {
424*3089Swyllys 		if (EMPTYSTRING(optarg_av))
425*3089Swyllys 			return (PK_ERR_USAGE);
426864Sdinak 		switch (opt) {
427864Sdinak 		case 'T':	/* token specifier */
428864Sdinak 			if (token_spec)
429864Sdinak 				return (PK_ERR_USAGE);
430864Sdinak 			token_spec = optarg_av;
431864Sdinak 			break;
432*3089Swyllys 		case 'c':	/* output cert file name */
433*3089Swyllys 			if (certfile)
434*3089Swyllys 				return (PK_ERR_USAGE);
435*3089Swyllys 			certfile = optarg_av;
436*3089Swyllys 			break;
437*3089Swyllys 		case 'l':	/* output CRL file name */
438*3089Swyllys 			if (crlfile)
439*3089Swyllys 				return (PK_ERR_USAGE);
440*3089Swyllys 			crlfile = optarg_av;
441*3089Swyllys 			break;
442*3089Swyllys 		case 'K':	/* output key file name */
443*3089Swyllys 			if (keyfile)
444*3089Swyllys 				return (PK_ERR_USAGE);
445*3089Swyllys 			keyfile = optarg_av;
446*3089Swyllys 			break;
447864Sdinak 		case 'i':	/* input file name */
448864Sdinak 			if (filename)
449864Sdinak 				return (PK_ERR_USAGE);
450864Sdinak 			filename = optarg_av;
451864Sdinak 			break;
452*3089Swyllys 		case 'k':
453*3089Swyllys 			kstype = KS2Int(optarg_av);
454*3089Swyllys 			if (kstype == 0)
455*3089Swyllys 				return (PK_ERR_USAGE);
456*3089Swyllys 			break;
457*3089Swyllys 		case 'y':
458*3089Swyllys 			oclass = OT2Int(optarg_av);
459*3089Swyllys 			if (oclass == -1)
460*3089Swyllys 				return (PK_ERR_USAGE);
461*3089Swyllys 			break;
462*3089Swyllys 		case 'd':
463*3089Swyllys 			dir = optarg_av;
464*3089Swyllys 			break;
465*3089Swyllys 		case 'D':
466*3089Swyllys 			keydir = optarg_av;
467*3089Swyllys 			break;
468*3089Swyllys 		case 'p':
469*3089Swyllys 			if (prefix)
470*3089Swyllys 				return (PK_ERR_USAGE);
471*3089Swyllys 			prefix = optarg_av;
472*3089Swyllys 			break;
473*3089Swyllys 		case 'n':
474*3089Swyllys 		case 'N':
475*3089Swyllys 			if (certlabel)
476*3089Swyllys 				return (PK_ERR_USAGE);
477*3089Swyllys 			certlabel = optarg_av;
478*3089Swyllys 			break;
479*3089Swyllys 		case 'F':
480*3089Swyllys 			okfmt = Str2Format(optarg_av);
481*3089Swyllys 			if (okfmt == KMF_FORMAT_UNDEF)
482*3089Swyllys 				return (PK_ERR_USAGE);
483*3089Swyllys 			break;
484*3089Swyllys 		case 't':
485*3089Swyllys 			if (trustflags)
486*3089Swyllys 				return (PK_ERR_USAGE);
487*3089Swyllys 			trustflags = optarg_av;
488*3089Swyllys 			break;
489*3089Swyllys 		case 'v':
490*3089Swyllys 			verify_crl = optarg_av;
491*3089Swyllys 			if (tolower(verify_crl[0]) == 'y')
492*3089Swyllys 				verify_crl_flag = B_TRUE;
493*3089Swyllys 			else if (tolower(verify_crl[0]) == 'n')
494*3089Swyllys 				verify_crl_flag = B_FALSE;
495*3089Swyllys 			else
496*3089Swyllys 				return (PK_ERR_USAGE);
497*3089Swyllys 			break;
498864Sdinak 		default:
499864Sdinak 			return (PK_ERR_USAGE);
500864Sdinak 			break;
501864Sdinak 		}
502864Sdinak 	}
50317Sdinak 
504*3089Swyllys 	/* Assume keystore = PKCS#11 if not specified */
505*3089Swyllys 	if (kstype == 0)
506*3089Swyllys 		kstype = KMF_KEYSTORE_PK11TOKEN;
507864Sdinak 
508864Sdinak 	/* Filename arg is required. */
509*3089Swyllys 	if (EMPTYSTRING(filename)) {
510*3089Swyllys 		cryptoerror(LOG_STDERR, gettext("The 'infile' parameter"
511*3089Swyllys 			"is required for the import operation.\n"));
51217Sdinak 		return (PK_ERR_USAGE);
513*3089Swyllys 	}
51417Sdinak 
515864Sdinak 	/* No additional args allowed. */
516864Sdinak 	argc -= optind_av;
517864Sdinak 	argv += optind_av;
518864Sdinak 	if (argc)
519864Sdinak 		return (PK_ERR_USAGE);
52017Sdinak 
521*3089Swyllys 	/* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
522*3089Swyllys 	if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
523*3089Swyllys 		kstype != KMF_KEYSTORE_PK11TOKEN) {
524*3089Swyllys 
525*3089Swyllys 		(void) fprintf(stderr, gettext("The objtype parameter "
526*3089Swyllys 			"is only relevant if keystore=pkcs11\n"));
527*3089Swyllys 		return (PK_ERR_USAGE);
52817Sdinak 	}
52917Sdinak 
530*3089Swyllys 	/*
531*3089Swyllys 	 * You must specify a certlabel (cert label) when importing
532*3089Swyllys 	 * into NSS or PKCS#11.
533*3089Swyllys 	 */
534*3089Swyllys 	if (kstype == KMF_KEYSTORE_NSS &&
535*3089Swyllys 		(oclass != PK_CRL_OBJ) && EMPTYSTRING(certlabel)) {
536*3089Swyllys 		cryptoerror(LOG_STDERR, gettext("The 'label' argument "
537*3089Swyllys 			"is required for this operation\n"));
538*3089Swyllys 		return (PK_ERR_USAGE);
53917Sdinak 	}
54017Sdinak 
541*3089Swyllys 	/*
542*3089Swyllys 	 * PKCS11 only imports PKCS#12 files or PEM/DER Cert files.
543*3089Swyllys 	 */
544*3089Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
545*3089Swyllys 		/* we do not import private keys except in PKCS12 bundles */
546*3089Swyllys 		if (oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)) {
547*3089Swyllys 			cryptoerror(LOG_STDERR, gettext(
548*3089Swyllys 				"The PKCS11 keystore only imports PKCS12 "
549*3089Swyllys 				"files or raw certificate data files "
550*3089Swyllys 				" or CRL file.\n"));
551*3089Swyllys 			return (PK_ERR_USAGE);
552*3089Swyllys 		}
55317Sdinak 	}
55417Sdinak 
555*3089Swyllys 	if ((rv = KMF_GetFileFormat(filename, &kfmt)) != KMF_OK) {
556*3089Swyllys 		cryptoerror(LOG_STDERR,
557*3089Swyllys 			gettext("File format not recognized."));
558*3089Swyllys 		return (rv);
55917Sdinak 	}
560*3089Swyllys 	if (oclass == 0 && (kfmt == KMF_FORMAT_ASN1 ||
561*3089Swyllys 		kfmt == KMF_FORMAT_PEM))
562*3089Swyllys 		oclass = PK_CERT_OBJ;
56317Sdinak 
564*3089Swyllys 	if (kstype == KMF_KEYSTORE_NSS) {
565*3089Swyllys 		if (oclass == PK_CRL_OBJ &&
566*3089Swyllys 			(kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
567*3089Swyllys 			cryptoerror(LOG_STDERR, gettext(
568*3089Swyllys 				"CRL data can only be imported as DER or "
569*3089Swyllys 				"PEM format"));
570*3089Swyllys 			return (PK_ERR_USAGE);
571*3089Swyllys 		}
572*3089Swyllys 
573*3089Swyllys 		if (oclass == PK_CERT_OBJ &&
574*3089Swyllys 			(kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
575*3089Swyllys 			cryptoerror(LOG_STDERR, gettext(
576*3089Swyllys 				"Certificates can only be imported as DER or "
577*3089Swyllys 				"PEM format"));
578*3089Swyllys 			return (PK_ERR_USAGE);
579*3089Swyllys 		}
580*3089Swyllys 
581*3089Swyllys 		/* we do not import private keys except in PKCS12 bundles */
582*3089Swyllys 		if (oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)) {
583*3089Swyllys 			cryptoerror(LOG_STDERR, gettext(
584*3089Swyllys 				"Private key data can only be imported as part "
585*3089Swyllys 				"of a PKCS12 file.\n"));
586*3089Swyllys 			return (PK_ERR_USAGE);
587*3089Swyllys 		}
58817Sdinak 	}
58917Sdinak 
590*3089Swyllys 	if (kstype == KMF_KEYSTORE_OPENSSL && oclass != PK_CRL_OBJ) {
591*3089Swyllys 		if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) {
59217Sdinak 			cryptoerror(LOG_STDERR, gettext(
593*3089Swyllys 				"The 'outkey' and 'outcert' parameters "
594*3089Swyllys 				"are required for the import operation "
595*3089Swyllys 				"when the 'file' keystore is used.\n"));
596*3089Swyllys 			return (PK_ERR_USAGE);
59717Sdinak 		}
59817Sdinak 	}
59917Sdinak 
600*3089Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec))
601*3089Swyllys 		token_spec = PK_DEFAULT_PK11TOKEN;
602*3089Swyllys 	else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec))
603*3089Swyllys 		token_spec = DEFAULT_NSS_TOKEN;
604*3089Swyllys 
605*3089Swyllys 	if (kfmt == KMF_FORMAT_PKCS12) {
606*3089Swyllys 		(void) get_pk12_password(&pk12cred);
607*3089Swyllys 
608*3089Swyllys 		if (kstype == KMF_KEYSTORE_PK11TOKEN ||
609*3089Swyllys 			kstype == KMF_KEYSTORE_NSS)
610*3089Swyllys 			(void) get_token_password(kstype, token_spec,
611*3089Swyllys 				&tokencred);
612*3089Swyllys 	}
613*3089Swyllys 
614*3089Swyllys 	if ((rv = KMF_Initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
615*3089Swyllys 		cryptoerror(LOG_STDERR, gettext("Error initializing "
616*3089Swyllys 				"KMF: 0x%02x\n"), rv);
617*3089Swyllys 		goto end;
618*3089Swyllys 	}
61917Sdinak 
620*3089Swyllys 	switch (kstype) {
621*3089Swyllys 		case KMF_KEYSTORE_PK11TOKEN:
622*3089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
623*3089Swyllys 				rv = pk_import_pk12_pk11(
624*3089Swyllys 					kmfhandle,
625*3089Swyllys 					&pk12cred,
626*3089Swyllys 					&tokencred,
627*3089Swyllys 					certlabel,
628*3089Swyllys 					token_spec,
629*3089Swyllys 					filename);
630*3089Swyllys 			else if (oclass == PK_CERT_OBJ)
631*3089Swyllys 				rv = pk_import_cert(
632*3089Swyllys 					kmfhandle,
633*3089Swyllys 					kstype,
634*3089Swyllys 					certlabel,
635*3089Swyllys 					token_spec,
636*3089Swyllys 					filename,
637*3089Swyllys 					NULL, NULL, NULL);
638*3089Swyllys 			else if (oclass == PK_CRL_OBJ)
639*3089Swyllys 				rv = pk_import_file_crl(
640*3089Swyllys 					kmfhandle,
641*3089Swyllys 					filename,
642*3089Swyllys 					crlfile,
643*3089Swyllys 					dir,
644*3089Swyllys 					okfmt);
645*3089Swyllys 			break;
646*3089Swyllys 		case KMF_KEYSTORE_NSS:
647*3089Swyllys 			if (dir == NULL)
648*3089Swyllys 				dir = PK_DEFAULT_DIRECTORY;
649*3089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
650*3089Swyllys 				rv = pk_import_pk12_nss(
651*3089Swyllys 					kmfhandle, &pk12cred,
652*3089Swyllys 					&tokencred,
653*3089Swyllys 					token_spec, dir, prefix,
654*3089Swyllys 					certlabel, trustflags, filename);
655*3089Swyllys 			else if (oclass == PK_CERT_OBJ) {
656*3089Swyllys 				rv = pk_import_cert(
657*3089Swyllys 					kmfhandle, kstype,
658*3089Swyllys 					certlabel, token_spec,
659*3089Swyllys 					filename, dir, prefix, trustflags);
660*3089Swyllys 			} else if (oclass == PK_CRL_OBJ) {
661*3089Swyllys 				rv = pk_import_nss_crl(
662*3089Swyllys 					kmfhandle,
663*3089Swyllys 					verify_crl_flag,
664*3089Swyllys 					filename,
665*3089Swyllys 					dir,
666*3089Swyllys 					prefix);
667*3089Swyllys 			}
668*3089Swyllys 			break;
669*3089Swyllys 		case KMF_KEYSTORE_OPENSSL:
670*3089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
671*3089Swyllys 				rv = pk_import_pk12_files(
672*3089Swyllys 					kmfhandle, &pk12cred,
673*3089Swyllys 					filename, certfile, keyfile,
674*3089Swyllys 					dir, keydir, okfmt);
675*3089Swyllys 			else if (oclass == PK_CRL_OBJ) {
676*3089Swyllys 				rv = pk_import_file_crl(
677*3089Swyllys 					kmfhandle,
678*3089Swyllys 					filename,
679*3089Swyllys 					crlfile,
680*3089Swyllys 					dir,
681*3089Swyllys 					okfmt);
682*3089Swyllys 			} else
683*3089Swyllys 				/*
684*3089Swyllys 				 * It doesn't make sense to import anything
685*3089Swyllys 				 * else for the files plugin.
686*3089Swyllys 				 */
687*3089Swyllys 				return (PK_ERR_USAGE);
688*3089Swyllys 			break;
689*3089Swyllys 		default:
690*3089Swyllys 			rv = PK_ERR_USAGE;
691*3089Swyllys 			break;
692*3089Swyllys 	}
69317Sdinak 
694*3089Swyllys end:
695*3089Swyllys 	if (rv != KMF_OK)
696*3089Swyllys 		display_error(kmfhandle, rv,
697*3089Swyllys 			gettext("Error importing objects"));
698*3089Swyllys 
699*3089Swyllys 	if (tokencred.cred != NULL)
700*3089Swyllys 		free(tokencred.cred);
701*3089Swyllys 
702*3089Swyllys 	if (pk12cred.cred != NULL)
703*3089Swyllys 		free(pk12cred.cred);
704*3089Swyllys 
705*3089Swyllys 	(void) KMF_Finalize(kmfhandle);
706*3089Swyllys 
707*3089Swyllys 	if (rv != KMF_OK)
708*3089Swyllys 		return (PK_ERR_USAGE);
709*3089Swyllys 
71017Sdinak 	return (0);
71117Sdinak }
712