xref: /titanic_41/usr/src/cmd/cmd-crypto/pktool/delete.c (revision 4ebb14b236958cfe1ef4ff3b7a50216d9e51f997)
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 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.cred.cred = tokencred->cred;
284 	parms.cred.credlen = tokencred->credlen;
285 
286 	if (oclass & PK_PRIKEY_OBJ) {
287 		parms.keyclass = KMF_ASYM_PRI;
288 		rv = pk_delete_keys(kmfhandle, &parms, "private", &nk);
289 		numkeys += nk;
290 	}
291 
292 	if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) {
293 		parms.keyclass = KMF_SYMMETRIC;
294 		rv = pk_delete_keys(kmfhandle, &parms, "symmetric", &nk);
295 		numkeys += nk;
296 	}
297 
298 	if (rv == KMF_OK && (oclass & PK_PUBKEY_OBJ)) {
299 		parms.keyclass = KMF_ASYM_PUB;
300 		rv = pk_delete_keys(kmfhandle, &parms, "public", &nk);
301 		numkeys += nk;
302 	}
303 	if (rv == KMF_OK && numkeys == 0)
304 		rv = KMF_ERR_KEY_NOT_FOUND;
305 
306 	return (rv);
307 }
308 
309 static KMF_RETURN
310 delete_pk11_certs(KMF_HANDLE_T kmfhandle,
311 	char *token, char *objlabel,
312 	KMF_BIGINT *serno, char *issuer, char *subject,
313 	KMF_CERT_VALIDITY find_criteria_flag)
314 {
315 	KMF_RETURN kmfrv;
316 	KMF_DELETECERT_PARAMS dparms;
317 	KMF_FINDCERT_PARAMS fcargs;
318 
319 	kmfrv = select_token(kmfhandle, token, FALSE);
320 
321 	if (kmfrv != KMF_OK) {
322 		return (kmfrv);
323 	}
324 
325 	(void) memset(&dparms, 0, sizeof (dparms));
326 	dparms.kstype = KMF_KEYSTORE_PK11TOKEN;
327 	dparms.certLabel = objlabel;
328 	dparms.issuer = issuer;
329 	dparms.subject = subject;
330 	dparms.serial = serno;
331 	dparms.find_cert_validity = find_criteria_flag;
332 
333 	fcargs = dparms;
334 	kmfrv = pk_delete_certs(kmfhandle, &fcargs, &dparms);
335 
336 	return (kmfrv);
337 }
338 
339 static KMF_RETURN
340 delete_file_certs(KMF_HANDLE_T kmfhandle,
341 	char *dir, char *filename, KMF_BIGINT *serial, char *issuer,
342 	char *subject, KMF_CERT_VALIDITY find_criteria_flag)
343 {
344 	KMF_RETURN rv;
345 	KMF_DELETECERT_PARAMS dparms;
346 	KMF_FINDCERT_PARAMS fcargs;
347 
348 	(void *)memset(&dparms, 0, sizeof (dparms));
349 	(void *)memset(&fcargs, 0, sizeof (fcargs));
350 	fcargs.kstype = KMF_KEYSTORE_OPENSSL;
351 	fcargs.certLabel = NULL;
352 	fcargs.issuer = issuer;
353 	fcargs.subject = subject;
354 	fcargs.serial = serial;
355 	fcargs.sslparms.dirpath = dir;
356 	fcargs.sslparms.certfile = filename;
357 	fcargs.find_cert_validity = find_criteria_flag;
358 
359 	/* For now, delete parameters and find parameters are the same */
360 	dparms = fcargs;
361 
362 	rv = pk_delete_certs(kmfhandle, &fcargs, &dparms);
363 
364 	return (rv);
365 }
366 
367 static KMF_RETURN
368 delete_file_keys(KMF_HANDLE_T kmfhandle, int oclass,
369 	char *dir, char *infile)
370 {
371 	KMF_RETURN rv = KMF_OK;
372 	KMF_FINDKEY_PARAMS parms;
373 	char *keytype = "";
374 	int nk, numkeys = 0;
375 
376 	(void) memset(&parms, 0, sizeof (parms));
377 	parms.kstype = KMF_KEYSTORE_OPENSSL;
378 	parms.sslparms.dirpath = dir;
379 	parms.sslparms.keyfile = infile;
380 
381 	if (oclass & (PK_PUBKEY_OBJ | PK_PRIKEY_OBJ)) {
382 		parms.keyclass = KMF_ASYM_PRI;
383 		keytype = "Asymmetric";
384 		rv = pk_delete_keys(kmfhandle, &parms, keytype, &nk);
385 		numkeys += nk;
386 	}
387 	if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) {
388 		parms.keyclass = KMF_SYMMETRIC;
389 		keytype = "symmetric";
390 		rv = pk_delete_keys(kmfhandle, &parms, keytype, &nk);
391 		numkeys += nk;
392 	}
393 	if (rv == KMF_OK && numkeys == 0)
394 		rv = KMF_ERR_KEY_NOT_FOUND;
395 
396 	return (rv);
397 }
398 
399 static KMF_RETURN
400 delete_file_crl(void *kmfhandle, char *dir, char *filename)
401 {
402 	KMF_RETURN rv;
403 	KMF_DELETECRL_PARAMS dcrlparms;
404 
405 	(void) memset(&dcrlparms, 0, sizeof (dcrlparms));
406 
407 	dcrlparms.kstype = KMF_KEYSTORE_OPENSSL;
408 	dcrlparms.sslparms.dirpath = dir;
409 	dcrlparms.sslparms.crlfile = filename;
410 
411 	rv = KMF_DeleteCRL(kmfhandle, &dcrlparms);
412 
413 	return (rv);
414 }
415 
416 /*
417  * Delete token objects.
418  */
419 int
420 pk_delete(int argc, char *argv[])
421 {
422 	int		opt;
423 	extern int	optind_av;
424 	extern char	*optarg_av;
425 	char		*token_spec = NULL;
426 	char		*subject = NULL;
427 	char		*issuer = NULL;
428 	char		*dir = NULL;
429 	char		*prefix = NULL;
430 	char		*infile = NULL;
431 	char		*object_label = NULL;
432 	char		*serstr = NULL;
433 
434 	int		oclass = 0;
435 	KMF_BIGINT	serial = { NULL, 0 };
436 	KMF_HANDLE_T	kmfhandle = NULL;
437 	KMF_KEYSTORE_TYPE	kstype = 0;
438 	KMF_RETURN	kmfrv;
439 	int		rv = 0;
440 	char			*find_criteria = NULL;
441 	KMF_CERT_VALIDITY	find_criteria_flag = KMF_ALL_CERTS;
442 	KMF_CREDENTIAL	tokencred = {NULL, 0};
443 
444 	/* Parse command line options.  Do NOT i18n/l10n. */
445 	while ((opt = getopt_av(argc, argv,
446 		"T:(token)y:(objtype)l:(label)"
447 		"k:(keystore)s:(subject)n:(nickname)"
448 		"d:(dir)p:(prefix)S:(serial)i:(issuer)"
449 		"c:(criteria)"
450 		"f:(infile)")) != EOF) {
451 
452 		if (EMPTYSTRING(optarg_av))
453 			return (PK_ERR_USAGE);
454 		switch (opt) {
455 		case 'T':	/* token specifier */
456 			if (token_spec)
457 				return (PK_ERR_USAGE);
458 			token_spec = optarg_av;
459 			break;
460 		case 'y':	/* object type:  public, private, both */
461 			if (oclass)
462 				return (PK_ERR_USAGE);
463 			oclass = OT2Int(optarg_av);
464 			if (oclass == -1)
465 				return (PK_ERR_USAGE);
466 			break;
467 		case 'l':	/* objects with specific label */
468 		case 'n':
469 			if (object_label)
470 				return (PK_ERR_USAGE);
471 			object_label = (char *)optarg_av;
472 			break;
473 		case 'k':
474 			kstype = KS2Int(optarg_av);
475 			if (kstype == 0)
476 				return (PK_ERR_USAGE);
477 			break;
478 		case 's':
479 			subject = optarg_av;
480 			break;
481 		case 'i':
482 			issuer = optarg_av;
483 			break;
484 		case 'd':
485 			dir = optarg_av;
486 			break;
487 		case 'p':
488 			prefix = optarg_av;
489 			break;
490 		case 'S':
491 			serstr = optarg_av;
492 			break;
493 		case 'f':
494 			infile = optarg_av;
495 			break;
496 		case 'c':
497 			find_criteria = optarg_av;
498 			if (!strcasecmp(find_criteria, "valid"))
499 				find_criteria_flag =
500 					KMF_NONEXPIRED_CERTS;
501 			else if (!strcasecmp(find_criteria, "expired"))
502 				find_criteria_flag = KMF_EXPIRED_CERTS;
503 			else if (!strcasecmp(find_criteria, "both"))
504 				find_criteria_flag = KMF_ALL_CERTS;
505 			else
506 				return (PK_ERR_USAGE);
507 			break;
508 		default:
509 			return (PK_ERR_USAGE);
510 			break;
511 		}
512 	}
513 
514 	/* Assume keystore = PKCS#11 if not specified */
515 	if (kstype == 0)
516 		kstype = KMF_KEYSTORE_PK11TOKEN;
517 
518 	/* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
519 	if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
520 		kstype != KMF_KEYSTORE_PK11TOKEN) {
521 
522 		(void) fprintf(stderr, gettext("The objtype parameter "
523 			"is only relevant if keystore=pkcs11\n"));
524 		return (PK_ERR_USAGE);
525 	}
526 
527 	/* If no object class specified, delete everything but CRLs */
528 	if (oclass == 0)
529 		oclass = PK_CERT_OBJ | PK_PUBKEY_OBJ | PK_PRIKEY_OBJ |
530 			PK_SYMKEY_OBJ;
531 
532 	/* No additional args allowed. */
533 	argc -= optind_av;
534 	argv += optind_av;
535 	if (argc)
536 		return (PK_ERR_USAGE);
537 	/* Done parsing command line options. */
538 
539 	if (kstype == KMF_KEYSTORE_PK11TOKEN && token_spec == NULL) {
540 		token_spec = PK_DEFAULT_PK11TOKEN;
541 	} else if (kstype == KMF_KEYSTORE_NSS && token_spec == NULL) {
542 		token_spec = DEFAULT_NSS_TOKEN;
543 	}
544 
545 	if (serstr != NULL) {
546 		uchar_t *bytes = NULL;
547 		size_t bytelen;
548 
549 		rv = KMF_HexString2Bytes((uchar_t *)serstr, &bytes, &bytelen);
550 		if (rv != KMF_OK || bytes == NULL) {
551 			(void) fprintf(stderr, gettext("serial number "
552 				"must be specified as a hex number "
553 				"(ex: 0x0102030405ffeeddee)\n"));
554 			return (PK_ERR_USAGE);
555 		}
556 		serial.val = bytes;
557 		serial.len = bytelen;
558 	}
559 
560 	if ((kstype == KMF_KEYSTORE_PK11TOKEN ||
561 		kstype == KMF_KEYSTORE_NSS) &&
562 		(oclass & (PK_KEY_OBJ | PK_PRIVATE_OBJ))) {
563 
564 		(void) get_token_password(kstype, token_spec,
565 			&tokencred);
566 	}
567 
568 	if ((kmfrv = KMF_Initialize(&kmfhandle, NULL, NULL)) != KMF_OK)
569 		return (kmfrv);
570 
571 	switch (kstype) {
572 		case KMF_KEYSTORE_PK11TOKEN:
573 			if (oclass & PK_KEY_OBJ) {
574 				kmfrv = delete_pk11_keys(kmfhandle,
575 						token_spec, oclass,
576 						object_label,
577 						&tokencred);
578 				/*
579 				 * If deleting groups of objects, it is OK
580 				 * to ignore the "key not found" case so that
581 				 * we can continue to find other objects.
582 				 */
583 				if (kmfrv == KMF_ERR_KEY_NOT_FOUND &&
584 					(oclass != PK_KEY_OBJ))
585 					kmfrv = KMF_OK;
586 				if (kmfrv != KMF_OK)
587 					break;
588 			}
589 			if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) {
590 				kmfrv = delete_pk11_certs(kmfhandle,
591 						token_spec,
592 						object_label,
593 						&serial, issuer,
594 						subject, find_criteria_flag);
595 				/*
596 				 * If cert delete failed, but we are looking at
597 				 * other objects, then it is OK.
598 				 */
599 				if (kmfrv == KMF_ERR_CERT_NOT_FOUND &&
600 					(oclass & (PK_CRL_OBJ | PK_KEY_OBJ)))
601 					kmfrv = KMF_OK;
602 				if (kmfrv != KMF_OK)
603 					break;
604 			}
605 			if (oclass & PK_CRL_OBJ)
606 				kmfrv = delete_file_crl(kmfhandle,
607 						dir, infile);
608 			break;
609 		case KMF_KEYSTORE_NSS:
610 			if (oclass & PK_KEY_OBJ) {
611 				kmfrv = delete_nss_keys(kmfhandle,
612 					dir, prefix, token_spec,
613 					oclass, (char  *)object_label,
614 					&tokencred);
615 				if (kmfrv != KMF_OK)
616 					break;
617 			}
618 			if (oclass & PK_CERT_OBJ) {
619 				kmfrv = delete_nss_certs(kmfhandle,
620 					dir, prefix, token_spec,
621 					(char  *)object_label,
622 					&serial, issuer, subject,
623 					find_criteria_flag);
624 				if (kmfrv != KMF_OK)
625 					break;
626 			}
627 			if (oclass & PK_CRL_OBJ)
628 				kmfrv = delete_nss_crl(kmfhandle,
629 					dir, prefix, token_spec,
630 					(char  *)object_label, subject);
631 			break;
632 		case KMF_KEYSTORE_OPENSSL:
633 			if (oclass & PK_KEY_OBJ) {
634 				kmfrv = delete_file_keys(kmfhandle, oclass,
635 					dir, infile);
636 				if (kmfrv != KMF_OK)
637 					break;
638 			}
639 			if (oclass & (PK_CERT_OBJ)) {
640 				kmfrv = delete_file_certs(kmfhandle,
641 					dir, infile, &serial, issuer,
642 					subject, find_criteria_flag);
643 				if (kmfrv != KMF_OK)
644 					break;
645 			}
646 			if (oclass & PK_CRL_OBJ)
647 				kmfrv = delete_file_crl(kmfhandle,
648 					dir, infile);
649 			break;
650 		default:
651 			rv = PK_ERR_USAGE;
652 			break;
653 	}
654 
655 	if (kmfrv != KMF_OK) {
656 		display_error(kmfhandle, kmfrv,
657 			gettext("Error deleting objects"));
658 	}
659 
660 	if (serial.val != NULL)
661 		free(serial.val);
662 	(void) KMF_Finalize(kmfhandle);
663 	return (kmfrv);
664 }
665