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 2007 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 token object delete operation for this tool.
30  * It loads the PKCS#11 modules, finds the object to delete, deletes it,
31  * and cleans up.  User must be R/W logged into the token.
32  */
33 
34 #include <stdio.h>
35 #include <string.h>
36 #include <cryptoutil.h>
37 #include <security/cryptoki.h>
38 #include "common.h"
39 #include <kmfapi.h>
40 
41 static KMF_RETURN
42 pk_destroy_keys(void *handle, KMF_KEY_HANDLE *keys,
43 	KMF_FINDKEY_PARAMS *fkparams, uint32_t numkeys)
44 {
45 	int i;
46 	KMF_RETURN rv = KMF_OK;
47 	KMF_DELETEKEY_PARAMS dkparams;
48 
49 	(void) memset(&dkparams, 0, sizeof (dkparams));
50 	dkparams.kstype = fkparams->kstype;
51 
52 	switch (fkparams->kstype) {
53 	case KMF_KEYSTORE_NSS:
54 		dkparams.nssparms = fkparams->nssparms;
55 		dkparams.cred = fkparams->cred;
56 		break;
57 	case KMF_KEYSTORE_OPENSSL:
58 		break;
59 	case KMF_KEYSTORE_PK11TOKEN:
60 		dkparams.cred = fkparams->cred;
61 		break;
62 	default:
63 		return (PK_ERR_USAGE);
64 	}
65 
66 	for (i = 0; rv == KMF_OK && i < numkeys; i++) {
67 		rv = KMF_DeleteKeyFromKeystore(handle, &dkparams, &keys[i]);
68 	}
69 	return (rv);
70 }
71 
72 static KMF_RETURN
73 pk_delete_keys(KMF_HANDLE_T kmfhandle, KMF_FINDKEY_PARAMS *parms, char *desc,
74 	int *keysdeleted)
75 {
76 	KMF_RETURN rv = KMF_OK;
77 	uint32_t numkeys = 0;
78 
79 	*keysdeleted = 0;
80 	numkeys = 0;
81 	rv = KMF_FindKey(kmfhandle, parms, NULL, &numkeys);
82 	if (rv == KMF_OK && numkeys > 0) {
83 		KMF_KEY_HANDLE *keys = NULL;
84 		char prompt[1024];
85 
86 		(void) snprintf(prompt, sizeof (prompt),
87 			gettext("%d %s key(s) found, do you want "
88 			"to delete them (y/N) ?"), numkeys,
89 			(desc != NULL ? desc : ""));
90 
91 		if (!yesno(prompt,
92 			gettext("Respond with yes or no.\n"),
93 			B_FALSE)) {
94 			return (KMF_OK);
95 		}
96 		keys = (KMF_KEY_HANDLE *)malloc(numkeys *
97 				sizeof (KMF_KEY_HANDLE));
98 		if (keys == NULL)
99 			return (KMF_ERR_MEMORY);
100 		(void) memset(keys, 0, numkeys *
101 			sizeof (KMF_KEY_HANDLE));
102 
103 		rv = KMF_FindKey(kmfhandle, parms, keys, &numkeys);
104 		if (rv == KMF_OK) {
105 			rv = pk_destroy_keys(kmfhandle, keys,
106 				parms, numkeys);
107 		}
108 
109 		free(keys);
110 	}
111 
112 	if (rv == KMF_ERR_KEY_NOT_FOUND) {
113 		rv = KMF_OK;
114 	}
115 
116 	*keysdeleted = numkeys;
117 	return (rv);
118 }
119 
120 static KMF_RETURN
121 pk_delete_certs(KMF_HANDLE_T kmfhandle, KMF_FINDCERT_PARAMS *fcparms,
122 	KMF_DELETECERT_PARAMS *dcparms)
123 {
124 	KMF_RETURN rv = KMF_OK;
125 	uint32_t numcerts = 0;
126 
127 	rv = KMF_FindCert(kmfhandle, fcparms, NULL, &numcerts);
128 	if (rv == KMF_OK && numcerts > 0) {
129 		char prompt[1024];
130 		(void) snprintf(prompt, sizeof (prompt),
131 			gettext("%d certificate(s) found, do you want "
132 			"to delete them (y/N) ?"), numcerts);
133 
134 		if (!yesno(prompt,
135 			gettext("Respond with yes or no.\n"),
136 			B_FALSE)) {
137 			return (KMF_OK);
138 		}
139 
140 		rv = KMF_DeleteCertFromKeystore(kmfhandle, dcparms);
141 
142 	} else if (rv == KMF_ERR_CERT_NOT_FOUND) {
143 		rv = KMF_OK;
144 	}
145 
146 	return (rv);
147 }
148 
149 static KMF_RETURN
150 delete_nss_keys(KMF_HANDLE_T kmfhandle, char *dir, char *prefix,
151 	char *token, int oclass, char *objlabel,
152 	KMF_CREDENTIAL *tokencred)
153 {
154 	KMF_RETURN rv = KMF_OK;
155 	KMF_FINDKEY_PARAMS parms;
156 	char *keytype = NULL;
157 	int nk, numkeys = 0;
158 
159 	rv = configure_nss(kmfhandle, dir, prefix);
160 	if (rv != KMF_OK)
161 		return (rv);
162 
163 	(void) memset(&parms, 0, sizeof (parms));
164 	parms.kstype = KMF_KEYSTORE_NSS;
165 	parms.findLabel = objlabel;
166 	parms.cred = *tokencred;
167 	parms.nssparms.slotlabel = token;
168 
169 	if (oclass & PK_PRIKEY_OBJ) {
170 		parms.keyclass = KMF_ASYM_PRI;
171 		keytype = "private";
172 		rv = pk_delete_keys(kmfhandle, &parms, keytype, &nk);
173 		numkeys += nk;
174 	}
175 	if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) {
176 		parms.keyclass = KMF_SYMMETRIC;
177 		keytype = "symmetric";
178 		rv = pk_delete_keys(kmfhandle, &parms, keytype, &nk);
179 		numkeys += nk;
180 	}
181 	if (rv == KMF_OK && (oclass & PK_PUBKEY_OBJ)) {
182 		parms.keyclass = KMF_ASYM_PUB;
183 		keytype = "public";
184 		rv = pk_delete_keys(kmfhandle, &parms, keytype, &nk);
185 		numkeys += nk;
186 	}
187 	if (rv == KMF_OK && numkeys == 0)
188 		rv = KMF_ERR_KEY_NOT_FOUND;
189 
190 	return (rv);
191 }
192 
193 
194 static KMF_RETURN
195 delete_nss_certs(KMF_HANDLE_T kmfhandle,
196 	char *dir, char *prefix,
197 	char *token, char *objlabel,
198 	KMF_BIGINT *serno, char *issuer, char *subject,
199 	KMF_CERT_VALIDITY find_criteria_flag)
200 {
201 	KMF_RETURN rv = KMF_OK;
202 	KMF_DELETECERT_PARAMS dcparms;
203 	KMF_FINDCERT_PARAMS fcargs;
204 
205 	rv = configure_nss(kmfhandle, dir, prefix);
206 	if (rv != KMF_OK)
207 		return (rv);
208 
209 	(void) memset(&dcparms, 0, sizeof (dcparms));
210 	dcparms.kstype = KMF_KEYSTORE_NSS;
211 	dcparms.certLabel = objlabel;
212 	dcparms.issuer = issuer;
213 	dcparms.subject = subject;
214 	dcparms.serial = serno;
215 	dcparms.find_cert_validity = find_criteria_flag;
216 	dcparms.nssparms.slotlabel = token;
217 
218 	(void) memset(&fcargs, 0, sizeof (fcargs));
219 	fcargs.kstype = KMF_KEYSTORE_NSS;
220 	fcargs.certLabel = objlabel;
221 	fcargs.issuer = issuer;
222 	fcargs.subject = subject;
223 	fcargs.serial = serno;
224 	fcargs.find_cert_validity = find_criteria_flag;
225 	fcargs.nssparms.slotlabel = token;
226 
227 	rv = pk_delete_certs(kmfhandle, &fcargs, &dcparms);
228 
229 	return (rv);
230 }
231 
232 static KMF_RETURN
233 delete_nss_crl(void *kmfhandle,
234 	char *dir, char *prefix, char *token,
235 	char *issuernickname, char *subject)
236 {
237 	KMF_RETURN rv = KMF_OK;
238 	KMF_DELETECRL_PARAMS dcrlparms;
239 
240 	rv = configure_nss(kmfhandle, dir, prefix);
241 	if (rv != KMF_OK)
242 		return (rv);
243 
244 	(void) memset(&dcrlparms, 0, sizeof (dcrlparms));
245 
246 	dcrlparms.kstype = KMF_KEYSTORE_NSS;
247 	dcrlparms.nssparms.slotlabel = token;
248 	dcrlparms.nssparms.crl_issuerName = issuernickname;
249 	dcrlparms.nssparms.crl_subjName = subject;
250 
251 	rv = KMF_DeleteCRL(kmfhandle, &dcrlparms);
252 
253 	return (rv);
254 }
255 
256 static KMF_RETURN
257 delete_pk11_keys(KMF_HANDLE_T kmfhandle,
258 	char *token, int oclass, char *objlabel,
259 	KMF_CREDENTIAL *tokencred)
260 {
261 	KMF_RETURN rv = KMF_OK;
262 	KMF_FINDKEY_PARAMS parms;
263 	int nk, numkeys = 0;
264 
265 	/*
266 	 * Symmetric keys and RSA/DSA private keys are always
267 	 * created with the "CKA_PRIVATE" field == TRUE, so
268 	 * make sure we search for them with it also set.
269 	 */
270 	if (oclass & (PK_SYMKEY_OBJ | PK_PRIKEY_OBJ))
271 		oclass |= PK_PRIVATE_OBJ;
272 
273 	rv = select_token(kmfhandle, token, FALSE);
274 	if (rv != KMF_OK) {
275 		return (rv);
276 	}
277 
278 	(void) memset(&parms, 0, sizeof (parms));
279 	parms.kstype = KMF_KEYSTORE_PK11TOKEN;
280 	parms.findLabel = (char *)objlabel;
281 	parms.keytype = 0;
282 	parms.pkcs11parms.private = ((oclass & PK_PRIVATE_OBJ) > 0);
283 	parms.pkcs11parms.token = 1;
284 	parms.cred.cred = tokencred->cred;
285 	parms.cred.credlen = tokencred->credlen;
286 
287 	if (oclass & PK_PRIKEY_OBJ) {
288 		parms.keyclass = KMF_ASYM_PRI;
289 		rv = pk_delete_keys(kmfhandle, &parms, "private", &nk);
290 		numkeys += nk;
291 	}
292 
293 	if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) {
294 		parms.keyclass = KMF_SYMMETRIC;
295 		rv = pk_delete_keys(kmfhandle, &parms, "symmetric", &nk);
296 		numkeys += nk;
297 	}
298 
299 	if (rv == KMF_OK && (oclass & PK_PUBKEY_OBJ)) {
300 		parms.keyclass = KMF_ASYM_PUB;
301 		rv = pk_delete_keys(kmfhandle, &parms, "public", &nk);
302 		numkeys += nk;
303 	}
304 	if (rv == KMF_OK && numkeys == 0)
305 		rv = KMF_ERR_KEY_NOT_FOUND;
306 
307 	return (rv);
308 }
309 
310 static KMF_RETURN
311 delete_pk11_certs(KMF_HANDLE_T kmfhandle,
312 	char *token, char *objlabel,
313 	KMF_BIGINT *serno, char *issuer, char *subject,
314 	KMF_CERT_VALIDITY find_criteria_flag)
315 {
316 	KMF_RETURN kmfrv;
317 	KMF_DELETECERT_PARAMS dparms;
318 	KMF_FINDCERT_PARAMS fcargs;
319 
320 	kmfrv = select_token(kmfhandle, token, FALSE);
321 
322 	if (kmfrv != KMF_OK) {
323 		return (kmfrv);
324 	}
325 
326 	(void) memset(&dparms, 0, sizeof (dparms));
327 	dparms.kstype = KMF_KEYSTORE_PK11TOKEN;
328 	dparms.certLabel = objlabel;
329 	dparms.issuer = issuer;
330 	dparms.subject = subject;
331 	dparms.serial = serno;
332 	dparms.find_cert_validity = find_criteria_flag;
333 
334 	fcargs = dparms;
335 	kmfrv = pk_delete_certs(kmfhandle, &fcargs, &dparms);
336 
337 	return (kmfrv);
338 }
339 
340 static KMF_RETURN
341 delete_file_certs(KMF_HANDLE_T kmfhandle,
342 	char *dir, char *filename, KMF_BIGINT *serial, char *issuer,
343 	char *subject, KMF_CERT_VALIDITY find_criteria_flag)
344 {
345 	KMF_RETURN rv;
346 	KMF_DELETECERT_PARAMS dparms;
347 	KMF_FINDCERT_PARAMS fcargs;
348 
349 	(void *)memset(&dparms, 0, sizeof (dparms));
350 	(void *)memset(&fcargs, 0, sizeof (fcargs));
351 	fcargs.kstype = KMF_KEYSTORE_OPENSSL;
352 	fcargs.certLabel = NULL;
353 	fcargs.issuer = issuer;
354 	fcargs.subject = subject;
355 	fcargs.serial = serial;
356 	fcargs.sslparms.dirpath = dir;
357 	fcargs.sslparms.certfile = filename;
358 	fcargs.find_cert_validity = find_criteria_flag;
359 
360 	/* For now, delete parameters and find parameters are the same */
361 	dparms = fcargs;
362 
363 	rv = pk_delete_certs(kmfhandle, &fcargs, &dparms);
364 
365 	return (rv);
366 }
367 
368 static KMF_RETURN
369 delete_file_keys(KMF_HANDLE_T kmfhandle, int oclass,
370 	char *dir, char *infile)
371 {
372 	KMF_RETURN rv = KMF_OK;
373 	KMF_FINDKEY_PARAMS parms;
374 	char *keytype = "";
375 	int nk, numkeys = 0;
376 
377 	(void) memset(&parms, 0, sizeof (parms));
378 	parms.kstype = KMF_KEYSTORE_OPENSSL;
379 	parms.sslparms.dirpath = dir;
380 	parms.sslparms.keyfile = infile;
381 
382 	if (oclass & (PK_PUBKEY_OBJ | PK_PRIKEY_OBJ)) {
383 		parms.keyclass = KMF_ASYM_PRI;
384 		keytype = "Asymmetric";
385 		rv = pk_delete_keys(kmfhandle, &parms, keytype, &nk);
386 		numkeys += nk;
387 	}
388 	if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) {
389 		parms.keyclass = KMF_SYMMETRIC;
390 		keytype = "symmetric";
391 		rv = pk_delete_keys(kmfhandle, &parms, keytype, &nk);
392 		numkeys += nk;
393 	}
394 	if (rv == KMF_OK && numkeys == 0)
395 		rv = KMF_ERR_KEY_NOT_FOUND;
396 
397 	return (rv);
398 }
399 
400 static KMF_RETURN
401 delete_file_crl(void *kmfhandle, char *dir, char *filename)
402 {
403 	KMF_RETURN rv;
404 	KMF_DELETECRL_PARAMS dcrlparms;
405 
406 	(void) memset(&dcrlparms, 0, sizeof (dcrlparms));
407 
408 	dcrlparms.kstype = KMF_KEYSTORE_OPENSSL;
409 	dcrlparms.sslparms.dirpath = dir;
410 	dcrlparms.sslparms.crlfile = filename;
411 
412 	rv = KMF_DeleteCRL(kmfhandle, &dcrlparms);
413 
414 	return (rv);
415 }
416 
417 /*
418  * Delete token objects.
419  */
420 int
421 pk_delete(int argc, char *argv[])
422 {
423 	int		opt;
424 	extern int	optind_av;
425 	extern char	*optarg_av;
426 	char		*token_spec = NULL;
427 	char		*subject = NULL;
428 	char		*issuer = NULL;
429 	char		*dir = NULL;
430 	char		*prefix = NULL;
431 	char		*infile = NULL;
432 	char		*object_label = NULL;
433 	char		*serstr = NULL;
434 
435 	int		oclass = 0;
436 	KMF_BIGINT	serial = { NULL, 0 };
437 	KMF_HANDLE_T	kmfhandle = NULL;
438 	KMF_KEYSTORE_TYPE	kstype = 0;
439 	KMF_RETURN	kmfrv;
440 	int		rv = 0;
441 	char			*find_criteria = NULL;
442 	KMF_CERT_VALIDITY	find_criteria_flag = KMF_ALL_CERTS;
443 	KMF_CREDENTIAL	tokencred = {NULL, 0};
444 
445 	/* Parse command line options.  Do NOT i18n/l10n. */
446 	while ((opt = getopt_av(argc, argv,
447 		"T:(token)y:(objtype)l:(label)"
448 		"k:(keystore)s:(subject)n:(nickname)"
449 		"d:(dir)p:(prefix)S:(serial)i:(issuer)"
450 		"c:(criteria)"
451 		"f:(infile)")) != EOF) {
452 
453 		if (EMPTYSTRING(optarg_av))
454 			return (PK_ERR_USAGE);
455 		switch (opt) {
456 		case 'T':	/* token specifier */
457 			if (token_spec)
458 				return (PK_ERR_USAGE);
459 			token_spec = optarg_av;
460 			break;
461 		case 'y':	/* object type:  public, private, both */
462 			if (oclass)
463 				return (PK_ERR_USAGE);
464 			oclass = OT2Int(optarg_av);
465 			if (oclass == -1)
466 				return (PK_ERR_USAGE);
467 			break;
468 		case 'l':	/* objects with specific label */
469 		case 'n':
470 			if (object_label)
471 				return (PK_ERR_USAGE);
472 			object_label = (char *)optarg_av;
473 			break;
474 		case 'k':
475 			kstype = KS2Int(optarg_av);
476 			if (kstype == 0)
477 				return (PK_ERR_USAGE);
478 			break;
479 		case 's':
480 			subject = optarg_av;
481 			break;
482 		case 'i':
483 			issuer = optarg_av;
484 			break;
485 		case 'd':
486 			dir = optarg_av;
487 			break;
488 		case 'p':
489 			prefix = optarg_av;
490 			break;
491 		case 'S':
492 			serstr = optarg_av;
493 			break;
494 		case 'f':
495 			infile = optarg_av;
496 			break;
497 		case 'c':
498 			find_criteria = optarg_av;
499 			if (!strcasecmp(find_criteria, "valid"))
500 				find_criteria_flag =
501 					KMF_NONEXPIRED_CERTS;
502 			else if (!strcasecmp(find_criteria, "expired"))
503 				find_criteria_flag = KMF_EXPIRED_CERTS;
504 			else if (!strcasecmp(find_criteria, "both"))
505 				find_criteria_flag = KMF_ALL_CERTS;
506 			else
507 				return (PK_ERR_USAGE);
508 			break;
509 		default:
510 			return (PK_ERR_USAGE);
511 			break;
512 		}
513 	}
514 
515 	/* Assume keystore = PKCS#11 if not specified */
516 	if (kstype == 0)
517 		kstype = KMF_KEYSTORE_PK11TOKEN;
518 
519 	/* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
520 	if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
521 		kstype != KMF_KEYSTORE_PK11TOKEN) {
522 
523 		(void) fprintf(stderr, gettext("The objtype parameter "
524 			"is only relevant if keystore=pkcs11\n"));
525 		return (PK_ERR_USAGE);
526 	}
527 
528 	/* If no object class specified, delete everything but CRLs */
529 	if (oclass == 0)
530 		oclass = PK_CERT_OBJ | PK_PUBKEY_OBJ | PK_PRIKEY_OBJ |
531 			PK_SYMKEY_OBJ;
532 
533 	/* No additional args allowed. */
534 	argc -= optind_av;
535 	argv += optind_av;
536 	if (argc)
537 		return (PK_ERR_USAGE);
538 	/* Done parsing command line options. */
539 
540 	if (kstype == KMF_KEYSTORE_PK11TOKEN && token_spec == NULL) {
541 		token_spec = PK_DEFAULT_PK11TOKEN;
542 	} else if (kstype == KMF_KEYSTORE_NSS && token_spec == NULL) {
543 		token_spec = DEFAULT_NSS_TOKEN;
544 	}
545 
546 	if (serstr != NULL) {
547 		uchar_t *bytes = NULL;
548 		size_t bytelen;
549 
550 		rv = KMF_HexString2Bytes((uchar_t *)serstr, &bytes, &bytelen);
551 		if (rv != KMF_OK || bytes == NULL) {
552 			(void) fprintf(stderr, gettext("serial number "
553 				"must be specified as a hex number "
554 				"(ex: 0x0102030405ffeeddee)\n"));
555 			return (PK_ERR_USAGE);
556 		}
557 		serial.val = bytes;
558 		serial.len = bytelen;
559 	}
560 
561 	if ((kstype == KMF_KEYSTORE_PK11TOKEN ||
562 		kstype == KMF_KEYSTORE_NSS) &&
563 		(oclass & (PK_KEY_OBJ | PK_PRIVATE_OBJ))) {
564 
565 		(void) get_token_password(kstype, token_spec,
566 			&tokencred);
567 	}
568 
569 	if ((kmfrv = KMF_Initialize(&kmfhandle, NULL, NULL)) != KMF_OK)
570 		return (kmfrv);
571 
572 	switch (kstype) {
573 		case KMF_KEYSTORE_PK11TOKEN:
574 			if (oclass & PK_KEY_OBJ) {
575 				kmfrv = delete_pk11_keys(kmfhandle,
576 						token_spec, oclass,
577 						object_label,
578 						&tokencred);
579 				/*
580 				 * If deleting groups of objects, it is OK
581 				 * to ignore the "key not found" case so that
582 				 * we can continue to find other objects.
583 				 */
584 				if (kmfrv == KMF_ERR_KEY_NOT_FOUND &&
585 					(oclass != PK_KEY_OBJ))
586 					kmfrv = KMF_OK;
587 				if (kmfrv != KMF_OK)
588 					break;
589 			}
590 			if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) {
591 				kmfrv = delete_pk11_certs(kmfhandle,
592 						token_spec,
593 						object_label,
594 						&serial, issuer,
595 						subject, find_criteria_flag);
596 				/*
597 				 * If cert delete failed, but we are looking at
598 				 * other objects, then it is OK.
599 				 */
600 				if (kmfrv == KMF_ERR_CERT_NOT_FOUND &&
601 					(oclass & (PK_CRL_OBJ | PK_KEY_OBJ)))
602 					kmfrv = KMF_OK;
603 				if (kmfrv != KMF_OK)
604 					break;
605 			}
606 			if (oclass & PK_CRL_OBJ)
607 				kmfrv = delete_file_crl(kmfhandle,
608 						dir, infile);
609 			break;
610 		case KMF_KEYSTORE_NSS:
611 			if (oclass & PK_KEY_OBJ) {
612 				kmfrv = delete_nss_keys(kmfhandle,
613 					dir, prefix, token_spec,
614 					oclass, (char  *)object_label,
615 					&tokencred);
616 				if (kmfrv != KMF_OK)
617 					break;
618 			}
619 			if (oclass & PK_CERT_OBJ) {
620 				kmfrv = delete_nss_certs(kmfhandle,
621 					dir, prefix, token_spec,
622 					(char  *)object_label,
623 					&serial, issuer, subject,
624 					find_criteria_flag);
625 				if (kmfrv != KMF_OK)
626 					break;
627 			}
628 			if (oclass & PK_CRL_OBJ)
629 				kmfrv = delete_nss_crl(kmfhandle,
630 					dir, prefix, token_spec,
631 					(char  *)object_label, subject);
632 			break;
633 		case KMF_KEYSTORE_OPENSSL:
634 			if (oclass & PK_KEY_OBJ) {
635 				kmfrv = delete_file_keys(kmfhandle, oclass,
636 					dir, infile);
637 				if (kmfrv != KMF_OK)
638 					break;
639 			}
640 			if (oclass & (PK_CERT_OBJ)) {
641 				kmfrv = delete_file_certs(kmfhandle,
642 					dir, infile, &serial, issuer,
643 					subject, find_criteria_flag);
644 				if (kmfrv != KMF_OK)
645 					break;
646 			}
647 			if (oclass & PK_CRL_OBJ)
648 				kmfrv = delete_file_crl(kmfhandle,
649 					dir, infile);
650 			break;
651 		default:
652 			rv = PK_ERR_USAGE;
653 			break;
654 	}
655 
656 	if (kmfrv != KMF_OK) {
657 		display_error(kmfhandle, kmfrv,
658 			gettext("Error deleting objects"));
659 	}
660 
661 	if (serial.val != NULL)
662 		free(serial.val);
663 	(void) KMF_Finalize(kmfhandle);
664 	return (kmfrv);
665 }
666