xref: /titanic_50/usr/src/cmd/cmd-crypto/pktool/import.c (revision c77a61a72b5ecdc507d6cf104142edd371a16c84)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*
29  * This file implements the import operation for this tool.
30  * The basic flow of the process is to decrypt the PKCS#12
31  * input file if it has a password, parse the elements in
32  * the file, find the soft token, log into it, import the
33  * PKCS#11 objects into the soft token, and log out.
34  */
35 
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <ctype.h>
40 #include <errno.h>
41 #include <fcntl.h>
42 #include <sys/types.h>
43 #include <sys/stat.h>
44 #include "common.h"
45 
46 #include <kmfapi.h>
47 
48 static KMF_RETURN
49 pk_import_pk12_files(KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *cred,
50 	char *outfile, char *certfile, char *keyfile,
51 	char *dir, char *keydir, KMF_ENCODE_FORMAT outformat)
52 {
53 	KMF_RETURN rv = KMF_OK;
54 	KMF_DATA *certs = NULL;
55 	KMF_RAW_KEY_DATA *keys = NULL;
56 	int ncerts = 0;
57 	int nkeys = 0;
58 	int i;
59 
60 	rv = KMF_ImportPK12(kmfhandle, outfile, cred,
61 		&certs, &ncerts, &keys, &nkeys);
62 
63 	if (rv == KMF_OK) {
64 		(void) printf(gettext("Found %d certificate(s) and %d "
65 			"key(s) in %s\n"), ncerts, nkeys, outfile);
66 	}
67 
68 	if (rv == KMF_OK && ncerts > 0) {
69 		KMF_STORECERT_PARAMS params;
70 		char newcertfile[MAXPATHLEN];
71 
72 		(void) memset(&params, 0, sizeof (KMF_STORECERT_PARAMS));
73 		params.kstype = KMF_KEYSTORE_OPENSSL;
74 		params.sslparms.dirpath = dir;
75 		params.sslparms.format = outformat;
76 
77 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
78 			/*
79 			 * If storing more than 1 cert, gotta change
80 			 * the name so we don't overwrite the previous one.
81 			 * Just append a _# to the name.
82 			 */
83 			if (i > 0) {
84 				(void) snprintf(newcertfile,
85 					sizeof (newcertfile),
86 					"%s_%d", certfile, i);
87 				params.sslparms.certfile = newcertfile;
88 			} else {
89 				params.sslparms.certfile = certfile;
90 			}
91 			rv = KMF_StoreCert(kmfhandle, &params, &certs[i]);
92 		}
93 	}
94 	if (rv == KMF_OK && nkeys > 0) {
95 		KMF_STOREKEY_PARAMS skparms;
96 		char newkeyfile[MAXPATHLEN];
97 
98 		(void) memset(&skparms, 0, sizeof (skparms));
99 
100 		/* The order of certificates and keys should match */
101 		for (i = 0; rv == KMF_OK && i < nkeys; i++) {
102 			skparms.kstype = KMF_KEYSTORE_OPENSSL;
103 			skparms.sslparms.dirpath = keydir;
104 			skparms.sslparms.format = outformat;
105 			skparms.cred = *cred;
106 			skparms.certificate = &certs[i];
107 
108 			if (i > 0) {
109 				(void) snprintf(newkeyfile,
110 					sizeof (newkeyfile),
111 					"%s_%d", keyfile, i);
112 				skparms.sslparms.keyfile = newkeyfile;
113 			} else {
114 				skparms.sslparms.keyfile = keyfile;
115 			}
116 
117 			rv = KMF_StorePrivateKey(kmfhandle, &skparms,
118 				&keys[i]);
119 		}
120 	}
121 	/*
122 	 * Cleanup memory.
123 	 */
124 	if (certs) {
125 		for (i = 0; i < ncerts; i++)
126 			KMF_FreeData(&certs[i]);
127 		free(certs);
128 	}
129 	if (keys) {
130 		for (i = 0; i < nkeys; i++)
131 			KMF_FreeRawKey(&keys[i]);
132 		free(keys);
133 	}
134 
135 
136 	return (rv);
137 }
138 
139 
140 static KMF_RETURN
141 pk_import_pk12_nss(
142 	KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *kmfcred,
143 	KMF_CREDENTIAL *tokencred,
144 	char *token_spec, char *dir, char *prefix,
145 	char *nickname, char *trustflags, char *filename)
146 {
147 	KMF_RETURN rv = KMF_OK;
148 	KMF_DATA *certs = NULL;
149 	KMF_RAW_KEY_DATA *keys = NULL;
150 	int ncerts = 0;
151 	int nkeys = 0;
152 	int i;
153 
154 	rv = configure_nss(kmfhandle, dir, prefix);
155 	if (rv != KMF_OK)
156 		return (rv);
157 
158 	rv = KMF_ImportPK12(kmfhandle, filename, kmfcred,
159 		&certs, &ncerts, &keys, &nkeys);
160 
161 	if (rv == KMF_OK)
162 		(void) printf(gettext("Found %d certificate(s) and %d "
163 			"key(s) in %s\n"), ncerts, nkeys, filename);
164 
165 	if (rv == KMF_OK) {
166 		KMF_STORECERT_PARAMS params;
167 
168 		(void) memset(&params, 0, sizeof (KMF_STORECERT_PARAMS));
169 		params.kstype = KMF_KEYSTORE_NSS;
170 		params.nssparms.slotlabel = token_spec;
171 		params.nssparms.trustflag = trustflags;
172 
173 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
174 			if (i == 0)
175 				params.certLabel = nickname;
176 			else
177 				params.certLabel = NULL;
178 
179 			rv = KMF_StoreCert(kmfhandle, &params, &certs[i]);
180 		}
181 		if (rv != KMF_OK) {
182 			display_error(kmfhandle, rv,
183 				gettext("Error storing certificate "
184 					"in PKCS11 token"));
185 		}
186 	}
187 
188 	if (rv == KMF_OK) {
189 		KMF_STOREKEY_PARAMS skparms;
190 
191 		/* The order of certificates and keys should match */
192 		for (i = 0; i < nkeys; i++) {
193 			(void) memset(&skparms, 0,
194 				sizeof (KMF_STOREKEY_PARAMS));
195 			skparms.kstype = KMF_KEYSTORE_NSS;
196 			skparms.cred = *tokencred;
197 			skparms.label = nickname;
198 			skparms.certificate = &certs[i];
199 			skparms.nssparms.slotlabel = token_spec;
200 
201 			rv = KMF_StorePrivateKey(kmfhandle, &skparms, &keys[i]);
202 		}
203 	}
204 
205 	/*
206 	 * Cleanup memory.
207 	 */
208 	if (certs) {
209 		for (i = 0; i < ncerts; i++)
210 			KMF_FreeData(&certs[i]);
211 		free(certs);
212 	}
213 	if (keys) {
214 		for (i = 0; i < nkeys; i++)
215 			KMF_FreeRawKey(&keys[i]);
216 		free(keys);
217 	}
218 
219 	return (rv);
220 }
221 
222 static KMF_RETURN
223 pk_import_cert(
224 	KMF_HANDLE_T kmfhandle,
225 	KMF_KEYSTORE_TYPE kstype,
226 	char *label, char *token_spec, char *filename,
227 	char *dir, char *prefix, char *trustflags)
228 {
229 	KMF_RETURN rv = KMF_OK;
230 	KMF_IMPORTCERT_PARAMS params;
231 
232 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
233 		rv = select_token(kmfhandle, token_spec, FALSE);
234 
235 		if (rv != KMF_OK) {
236 			return (rv);
237 		}
238 	}
239 
240 	(void) memset(&params, 0, sizeof (params));
241 	params.kstype = kstype;
242 	params.certfile = filename;
243 	params.certLabel = label;
244 
245 	if (kstype == KMF_KEYSTORE_NSS) {
246 		rv = configure_nss(kmfhandle, dir, prefix);
247 		if (rv != KMF_OK)
248 			return (rv);
249 		params.nssparms.trustflag = trustflags;
250 		params.nssparms.slotlabel = token_spec;
251 	}
252 
253 	rv = KMF_ImportCert(kmfhandle, &params);
254 
255 	return (rv);
256 }
257 
258 static KMF_RETURN
259 pk_import_file_crl(void *kmfhandle,
260 	char *infile,
261 	char *outfile,
262 	char *outdir,
263 	KMF_ENCODE_FORMAT outfmt)
264 {
265 	KMF_IMPORTCRL_PARAMS 	icrl_params;
266 	KMF_OPENSSL_PARAMS sslparams;
267 
268 	sslparams.crlfile = infile;
269 	sslparams.dirpath = outdir;
270 	sslparams.outcrlfile = outfile;
271 	sslparams.format = outfmt;
272 	sslparams.crl_check = B_FALSE;
273 
274 	icrl_params.kstype = KMF_KEYSTORE_OPENSSL;
275 	icrl_params.sslparms = sslparams;
276 
277 	return (KMF_ImportCRL(kmfhandle, &icrl_params));
278 
279 }
280 
281 static KMF_RETURN
282 pk_import_nss_crl(void *kmfhandle,
283 	boolean_t verify_crl_flag,
284 	char *infile,
285 	char *outdir,
286 	char *prefix)
287 {
288 	KMF_IMPORTCRL_PARAMS 	icrl_params;
289 	KMF_RETURN rv;
290 
291 	rv = configure_nss(kmfhandle, outdir, prefix);
292 	if (rv != KMF_OK)
293 		return (rv);
294 
295 	icrl_params.kstype = KMF_KEYSTORE_NSS;
296 	icrl_params.nssparms.slotlabel = NULL;
297 	icrl_params.nssparms.crlfile = infile;
298 	icrl_params.nssparms.crl_check = verify_crl_flag;
299 
300 	return (KMF_ImportCRL(kmfhandle, &icrl_params));
301 
302 }
303 
304 static KMF_RETURN
305 pk_import_pk12_pk11(
306 	KMF_HANDLE_T kmfhandle,
307 	KMF_CREDENTIAL *p12cred,
308 	KMF_CREDENTIAL *tokencred,
309 	char *label, char *token_spec,
310 	char *filename)
311 {
312 	KMF_RETURN rv = KMF_OK;
313 	KMF_DATA *certs = NULL;
314 	KMF_RAW_KEY_DATA *keys = NULL;
315 	int ncerts = 0;
316 	int nkeys = 0;
317 	int i;
318 
319 	rv = select_token(kmfhandle, token_spec, FALSE);
320 
321 	if (rv != KMF_OK) {
322 		return (rv);
323 	}
324 
325 	rv = KMF_ImportPK12(kmfhandle, filename, p12cred,
326 		&certs, &ncerts, &keys, &nkeys);
327 
328 	if (rv == KMF_OK) {
329 		KMF_STOREKEY_PARAMS skparms;
330 
331 		/* The order of certificates and keys should match */
332 		for (i = 0; i < nkeys; i++) {
333 			(void) memset(&skparms, 0,
334 				sizeof (KMF_STOREKEY_PARAMS));
335 			skparms.kstype = KMF_KEYSTORE_PK11TOKEN;
336 			skparms.certificate = &certs[i];
337 			if (tokencred != NULL)
338 				skparms.cred = *tokencred;
339 			if (i == 0)
340 				skparms.label = label;
341 			else
342 				skparms.label = NULL;
343 
344 			rv = KMF_StorePrivateKey(kmfhandle, &skparms,
345 				&keys[i]);
346 		}
347 	}
348 
349 	if (rv == KMF_OK) {
350 		KMF_STORECERT_PARAMS params;
351 
352 		(void) printf(gettext("Found %d certificate(s) and %d "
353 			"key(s) in %s\n"), ncerts, nkeys, filename);
354 		(void) memset(&params, 0, sizeof (KMF_STORECERT_PARAMS));
355 
356 		params.kstype = KMF_KEYSTORE_PK11TOKEN;
357 
358 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
359 			if (i == 0)
360 				params.certLabel = label;
361 			else
362 				params.certLabel = NULL;
363 
364 			rv = KMF_StoreCert(kmfhandle, &params, &certs[i]);
365 		}
366 	}
367 
368 	/*
369 	 * Cleanup memory.
370 	 */
371 	if (certs) {
372 		for (i = 0; i < ncerts; i++)
373 			KMF_FreeData(&certs[i]);
374 		free(certs);
375 	}
376 	if (keys) {
377 		for (i = 0; i < nkeys; i++)
378 			KMF_FreeRawKey(&keys[i]);
379 		free(keys);
380 	}
381 
382 	return (rv);
383 }
384 
385 /*
386  * Import objects from into KMF repositories.
387  */
388 int
389 pk_import(int argc, char *argv[])
390 {
391 	int		opt;
392 	extern int	optind_av;
393 	extern char	*optarg_av;
394 	char		*token_spec = NULL;
395 	char		*filename = NULL;
396 	char		*keyfile = NULL;
397 	char		*certfile = NULL;
398 	char		*crlfile = NULL;
399 	char		*certlabel = NULL;
400 	char		*dir = NULL;
401 	char		*keydir = NULL;
402 	char		*prefix = NULL;
403 	char		*trustflags = NULL;
404 	char		*verify_crl = NULL;
405 	boolean_t	verify_crl_flag = B_FALSE;
406 	int		oclass = 0;
407 	KMF_KEYSTORE_TYPE	kstype = 0;
408 	KMF_ENCODE_FORMAT	kfmt = 0;
409 	KMF_ENCODE_FORMAT	okfmt = KMF_FORMAT_ASN1;
410 	KMF_RETURN		rv = KMF_OK;
411 	KMF_CREDENTIAL	pk12cred = { NULL, 0 };
412 	KMF_CREDENTIAL	tokencred = { NULL, 0 };
413 	KMF_HANDLE_T	kmfhandle = NULL;
414 
415 	/* Parse command line options.  Do NOT i18n/l10n. */
416 	while ((opt = getopt_av(argc, argv,
417 		"T:(token)i:(infile)"
418 		"k:(keystore)y:(objtype)"
419 		"d:(dir)p:(prefix)"
420 		"n:(certlabel)N:(label)"
421 		"K:(outkey)c:(outcert)"
422 		"v:(verifycrl)l:(outcrl)"
423 		"t:(trust)D:(keydir)F:(outformat)")) != EOF) {
424 		if (EMPTYSTRING(optarg_av))
425 			return (PK_ERR_USAGE);
426 		switch (opt) {
427 		case 'T':	/* token specifier */
428 			if (token_spec)
429 				return (PK_ERR_USAGE);
430 			token_spec = optarg_av;
431 			break;
432 		case 'c':	/* output cert file name */
433 			if (certfile)
434 				return (PK_ERR_USAGE);
435 			certfile = optarg_av;
436 			break;
437 		case 'l':	/* output CRL file name */
438 			if (crlfile)
439 				return (PK_ERR_USAGE);
440 			crlfile = optarg_av;
441 			break;
442 		case 'K':	/* output key file name */
443 			if (keyfile)
444 				return (PK_ERR_USAGE);
445 			keyfile = optarg_av;
446 			break;
447 		case 'i':	/* input file name */
448 			if (filename)
449 				return (PK_ERR_USAGE);
450 			filename = optarg_av;
451 			break;
452 		case 'k':
453 			kstype = KS2Int(optarg_av);
454 			if (kstype == 0)
455 				return (PK_ERR_USAGE);
456 			break;
457 		case 'y':
458 			oclass = OT2Int(optarg_av);
459 			if (oclass == -1)
460 				return (PK_ERR_USAGE);
461 			break;
462 		case 'd':
463 			dir = optarg_av;
464 			break;
465 		case 'D':
466 			keydir = optarg_av;
467 			break;
468 		case 'p':
469 			if (prefix)
470 				return (PK_ERR_USAGE);
471 			prefix = optarg_av;
472 			break;
473 		case 'n':
474 		case 'N':
475 			if (certlabel)
476 				return (PK_ERR_USAGE);
477 			certlabel = optarg_av;
478 			break;
479 		case 'F':
480 			okfmt = Str2Format(optarg_av);
481 			if (okfmt == KMF_FORMAT_UNDEF)
482 				return (PK_ERR_USAGE);
483 			break;
484 		case 't':
485 			if (trustflags)
486 				return (PK_ERR_USAGE);
487 			trustflags = optarg_av;
488 			break;
489 		case 'v':
490 			verify_crl = optarg_av;
491 			if (tolower(verify_crl[0]) == 'y')
492 				verify_crl_flag = B_TRUE;
493 			else if (tolower(verify_crl[0]) == 'n')
494 				verify_crl_flag = B_FALSE;
495 			else
496 				return (PK_ERR_USAGE);
497 			break;
498 		default:
499 			return (PK_ERR_USAGE);
500 			break;
501 		}
502 	}
503 
504 	/* Assume keystore = PKCS#11 if not specified */
505 	if (kstype == 0)
506 		kstype = KMF_KEYSTORE_PK11TOKEN;
507 
508 	/* Filename arg is required. */
509 	if (EMPTYSTRING(filename)) {
510 		cryptoerror(LOG_STDERR, gettext("The 'infile' parameter"
511 			"is required for the import operation.\n"));
512 		return (PK_ERR_USAGE);
513 	}
514 
515 	/* No additional args allowed. */
516 	argc -= optind_av;
517 	argv += optind_av;
518 	if (argc)
519 		return (PK_ERR_USAGE);
520 
521 	/* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
522 	if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
523 		kstype != KMF_KEYSTORE_PK11TOKEN) {
524 
525 		(void) fprintf(stderr, gettext("The objtype parameter "
526 			"is only relevant if keystore=pkcs11\n"));
527 		return (PK_ERR_USAGE);
528 	}
529 
530 	/*
531 	 * You must specify a certlabel (cert label) when importing
532 	 * into NSS or PKCS#11.
533 	 */
534 	if (kstype == KMF_KEYSTORE_NSS &&
535 		(oclass != PK_CRL_OBJ) && EMPTYSTRING(certlabel)) {
536 		cryptoerror(LOG_STDERR, gettext("The 'label' argument "
537 			"is required for this operation\n"));
538 		return (PK_ERR_USAGE);
539 	}
540 
541 	/*
542 	 * PKCS11 only imports PKCS#12 files or PEM/DER Cert files.
543 	 */
544 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
545 		/* we do not import private keys except in PKCS12 bundles */
546 		if (oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)) {
547 			cryptoerror(LOG_STDERR, gettext(
548 				"The PKCS11 keystore only imports PKCS12 "
549 				"files or raw certificate data files "
550 				" or CRL file.\n"));
551 			return (PK_ERR_USAGE);
552 		}
553 	}
554 
555 	if ((rv = KMF_GetFileFormat(filename, &kfmt)) != KMF_OK) {
556 		cryptoerror(LOG_STDERR,
557 			gettext("File format not recognized."));
558 		return (rv);
559 	}
560 	if (oclass == 0 && (kfmt == KMF_FORMAT_ASN1 ||
561 		kfmt == KMF_FORMAT_PEM))
562 		oclass = PK_CERT_OBJ;
563 
564 	if (kstype == KMF_KEYSTORE_NSS) {
565 		if (oclass == PK_CRL_OBJ &&
566 			(kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
567 			cryptoerror(LOG_STDERR, gettext(
568 				"CRL data can only be imported as DER or "
569 				"PEM format"));
570 			return (PK_ERR_USAGE);
571 		}
572 
573 		if (oclass == PK_CERT_OBJ &&
574 			(kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
575 			cryptoerror(LOG_STDERR, gettext(
576 				"Certificates can only be imported as DER or "
577 				"PEM format"));
578 			return (PK_ERR_USAGE);
579 		}
580 
581 		/* we do not import private keys except in PKCS12 bundles */
582 		if (oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)) {
583 			cryptoerror(LOG_STDERR, gettext(
584 				"Private key data can only be imported as part "
585 				"of a PKCS12 file.\n"));
586 			return (PK_ERR_USAGE);
587 		}
588 	}
589 
590 	if (kstype == KMF_KEYSTORE_OPENSSL && oclass != PK_CRL_OBJ) {
591 		if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) {
592 			cryptoerror(LOG_STDERR, gettext(
593 				"The 'outkey' and 'outcert' parameters "
594 				"are required for the import operation "
595 				"when the 'file' keystore is used.\n"));
596 			return (PK_ERR_USAGE);
597 		}
598 	}
599 
600 	if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec))
601 		token_spec = PK_DEFAULT_PK11TOKEN;
602 	else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec))
603 		token_spec = DEFAULT_NSS_TOKEN;
604 
605 	if (kfmt == KMF_FORMAT_PKCS12) {
606 		(void) get_pk12_password(&pk12cred);
607 
608 		if (kstype == KMF_KEYSTORE_PK11TOKEN ||
609 			kstype == KMF_KEYSTORE_NSS)
610 			(void) get_token_password(kstype, token_spec,
611 				&tokencred);
612 	}
613 
614 	if ((rv = KMF_Initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
615 		cryptoerror(LOG_STDERR, gettext("Error initializing "
616 				"KMF: 0x%02x\n"), rv);
617 		goto end;
618 	}
619 
620 	switch (kstype) {
621 		case KMF_KEYSTORE_PK11TOKEN:
622 			if (kfmt == KMF_FORMAT_PKCS12)
623 				rv = pk_import_pk12_pk11(
624 					kmfhandle,
625 					&pk12cred,
626 					&tokencred,
627 					certlabel,
628 					token_spec,
629 					filename);
630 			else if (oclass == PK_CERT_OBJ)
631 				rv = pk_import_cert(
632 					kmfhandle,
633 					kstype,
634 					certlabel,
635 					token_spec,
636 					filename,
637 					NULL, NULL, NULL);
638 			else if (oclass == PK_CRL_OBJ)
639 				rv = pk_import_file_crl(
640 					kmfhandle,
641 					filename,
642 					crlfile,
643 					dir,
644 					okfmt);
645 			break;
646 		case KMF_KEYSTORE_NSS:
647 			if (dir == NULL)
648 				dir = PK_DEFAULT_DIRECTORY;
649 			if (kfmt == KMF_FORMAT_PKCS12)
650 				rv = pk_import_pk12_nss(
651 					kmfhandle, &pk12cred,
652 					&tokencred,
653 					token_spec, dir, prefix,
654 					certlabel, trustflags, filename);
655 			else if (oclass == PK_CERT_OBJ) {
656 				rv = pk_import_cert(
657 					kmfhandle, kstype,
658 					certlabel, token_spec,
659 					filename, dir, prefix, trustflags);
660 			} else if (oclass == PK_CRL_OBJ) {
661 				rv = pk_import_nss_crl(
662 					kmfhandle,
663 					verify_crl_flag,
664 					filename,
665 					dir,
666 					prefix);
667 			}
668 			break;
669 		case KMF_KEYSTORE_OPENSSL:
670 			if (kfmt == KMF_FORMAT_PKCS12)
671 				rv = pk_import_pk12_files(
672 					kmfhandle, &pk12cred,
673 					filename, certfile, keyfile,
674 					dir, keydir, okfmt);
675 			else if (oclass == PK_CRL_OBJ) {
676 				rv = pk_import_file_crl(
677 					kmfhandle,
678 					filename,
679 					crlfile,
680 					dir,
681 					okfmt);
682 			} else
683 				/*
684 				 * It doesn't make sense to import anything
685 				 * else for the files plugin.
686 				 */
687 				return (PK_ERR_USAGE);
688 			break;
689 		default:
690 			rv = PK_ERR_USAGE;
691 			break;
692 	}
693 
694 end:
695 	if (rv != KMF_OK)
696 		display_error(kmfhandle, rv,
697 			gettext("Error importing objects"));
698 
699 	if (tokencred.cred != NULL)
700 		free(tokencred.cred);
701 
702 	if (pk12cred.cred != NULL)
703 		free(pk12cred.cred);
704 
705 	(void) KMF_Finalize(kmfhandle);
706 
707 	if (rv != KMF_OK)
708 		return (PK_ERR_USAGE);
709 
710 	return (0);
711 }
712