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_ATTRIBUTE *attrlist, int numattr)
43 {
44 	int i;
45 	KMF_RETURN rv = KMF_OK;
46 	uint32_t *numkeys;
47 	KMF_KEY_HANDLE *keys = NULL;
48 	int del_num = 0;
49 	KMF_ATTRIBUTE delete_attlist[16];
50 	KMF_KEYSTORE_TYPE kstype;
51 	uint32_t len;
52 	boolean_t destroy = B_TRUE;
53 	KMF_CREDENTIAL cred;
54 	char *slotlabel = NULL;
55 
56 	len = sizeof (kstype);
57 	rv = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
58 	    &kstype, &len);
59 	if (rv != KMF_OK)
60 		return (rv);
61 
62 	kmf_set_attr_at_index(delete_attlist, del_num,
63 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
64 	del_num++;
65 
66 	/* "destroy" is optional. Default is TRUE */
67 	(void) kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr,
68 	    (void *)&destroy, NULL);
69 
70 	kmf_set_attr_at_index(delete_attlist, del_num,
71 	    KMF_DESTROY_BOOL_ATTR, &destroy, sizeof (boolean_t));
72 	del_num++;
73 
74 	switch (kstype) {
75 	case KMF_KEYSTORE_NSS:
76 		rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
77 		    (void *)&cred, NULL);
78 		if (rv == KMF_OK) {
79 			if (cred.credlen > 0) {
80 				kmf_set_attr_at_index(delete_attlist, del_num,
81 				    KMF_CREDENTIAL_ATTR, &cred,
82 				    sizeof (KMF_CREDENTIAL));
83 				del_num++;
84 			}
85 		}
86 
87 		slotlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist,
88 		    numattr);
89 		if (slotlabel != NULL) {
90 			kmf_set_attr_at_index(delete_attlist, del_num,
91 			    KMF_TOKEN_LABEL_ATTR, slotlabel,
92 			    strlen(slotlabel));
93 			del_num++;
94 		}
95 		break;
96 	case KMF_KEYSTORE_OPENSSL:
97 		break;
98 	case KMF_KEYSTORE_PK11TOKEN:
99 		rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
100 		    (void *)&cred, NULL);
101 		if (rv == KMF_OK) {
102 			if (cred.credlen > 0) {
103 				kmf_set_attr_at_index(delete_attlist, del_num,
104 				    KMF_CREDENTIAL_ATTR, &cred,
105 				    sizeof (KMF_CREDENTIAL));
106 				del_num++;
107 			}
108 		}
109 		break;
110 	default:
111 		return (PK_ERR_USAGE);
112 	}
113 
114 	numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
115 	if (numkeys == NULL)
116 		return (PK_ERR_USAGE);
117 
118 	keys = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
119 	if (keys == NULL)
120 		return (PK_ERR_USAGE);
121 
122 	for (i = 0; rv == KMF_OK && i < *numkeys; i++) {
123 		int num = del_num;
124 
125 		kmf_set_attr_at_index(delete_attlist, num,
126 		    KMF_KEY_HANDLE_ATTR, &keys[i], sizeof (KMF_KEY_HANDLE));
127 		num++;
128 
129 		rv = kmf_delete_key_from_keystore(handle, num, delete_attlist);
130 	}
131 	return (rv);
132 }
133 
134 static KMF_RETURN
135 pk_delete_keys(KMF_HANDLE_T kmfhandle, KMF_ATTRIBUTE *attlist, int numattr,
136 	char *desc, int *keysdeleted)
137 {
138 	KMF_RETURN rv = KMF_OK;
139 	uint32_t numkeys = 0;
140 	int num = numattr;
141 
142 	*keysdeleted = 0;
143 	numkeys = 0;
144 
145 	kmf_set_attr_at_index(attlist, num,
146 	    KMF_COUNT_ATTR, &numkeys, sizeof (uint32_t));
147 	num++;
148 
149 	rv = kmf_find_key(kmfhandle, num, attlist);
150 
151 	if (rv == KMF_OK && numkeys > 0) {
152 		KMF_KEY_HANDLE *keys = NULL;
153 		char prompt[1024];
154 
155 		(void) snprintf(prompt, sizeof (prompt),
156 		    gettext("%d %s key(s) found, do you want "
157 		    "to delete them (y/N) ?"), numkeys,
158 		    (desc != NULL ? desc : ""));
159 
160 		if (!yesno(prompt,
161 		    gettext("Respond with yes or no.\n"),
162 		    B_FALSE)) {
163 			return (KMF_OK);
164 		}
165 		keys = (KMF_KEY_HANDLE *)malloc(numkeys *
166 		    sizeof (KMF_KEY_HANDLE));
167 		if (keys == NULL)
168 			return (KMF_ERR_MEMORY);
169 		(void) memset(keys, 0, numkeys *
170 		    sizeof (KMF_KEY_HANDLE));
171 
172 		kmf_set_attr_at_index(attlist, num,
173 		    KMF_KEY_HANDLE_ATTR, keys, sizeof (KMF_KEY_HANDLE));
174 		num++;
175 
176 		rv = kmf_find_key(kmfhandle, num, attlist);
177 		if (rv == KMF_OK) {
178 			rv = pk_destroy_keys(kmfhandle, attlist, num);
179 		}
180 
181 		free(keys);
182 	}
183 
184 	if (rv == KMF_ERR_KEY_NOT_FOUND) {
185 		rv = KMF_OK;
186 	}
187 
188 	*keysdeleted = numkeys;
189 	return (rv);
190 }
191 
192 static KMF_RETURN
193 pk_delete_certs(KMF_HANDLE_T kmfhandle, KMF_ATTRIBUTE *attlist, int numattr)
194 {
195 	KMF_RETURN rv = KMF_OK;
196 	uint32_t numcerts = 0;
197 	int num = numattr;
198 
199 	kmf_set_attr_at_index(attlist, num,
200 	    KMF_COUNT_ATTR, &numcerts, sizeof (uint32_t));
201 	num++;
202 
203 	rv = kmf_find_cert(kmfhandle, num, attlist);
204 	if (rv == KMF_OK && numcerts > 0) {
205 		char prompt[1024];
206 		(void) snprintf(prompt, sizeof (prompt),
207 		    gettext("%d certificate(s) found, do you want "
208 		    "to delete them (y/N) ?"), numcerts);
209 
210 		if (!yesno(prompt,
211 		    gettext("Respond with yes or no.\n"),
212 		    B_FALSE)) {
213 			return (KMF_OK);
214 		}
215 
216 		/*
217 		 * Use numattr because delete cert does not require
218 		 * KMF_COUNT_ATTR attribute.
219 		 */
220 		rv = kmf_delete_cert_from_keystore(kmfhandle, numattr, attlist);
221 
222 	} else if (rv == KMF_ERR_CERT_NOT_FOUND) {
223 		rv = KMF_OK;
224 	}
225 
226 	return (rv);
227 }
228 
229 static KMF_RETURN
230 delete_nss_keys(KMF_HANDLE_T kmfhandle, char *dir, char *prefix,
231 	char *token, int oclass, char *objlabel,
232 	KMF_CREDENTIAL *tokencred)
233 {
234 	KMF_RETURN rv = KMF_OK;
235 	char *keytype = NULL;
236 	int nk, numkeys = 0;
237 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
238 	int numattr = 0;
239 	KMF_ATTRIBUTE attrlist[16];
240 	KMF_KEY_CLASS keyclass;
241 
242 	rv = configure_nss(kmfhandle, dir, prefix);
243 	if (rv != KMF_OK)
244 		return (rv);
245 
246 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
247 	    &kstype, sizeof (kstype));
248 	numattr++;
249 
250 	if (objlabel != NULL) {
251 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR,
252 		    objlabel, strlen(objlabel));
253 		numattr++;
254 	}
255 
256 	if (tokencred->credlen > 0) {
257 		kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
258 		    tokencred, sizeof (KMF_CREDENTIAL));
259 		numattr++;
260 	}
261 
262 	if (token && strlen(token)) {
263 		kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
264 		    token, strlen(token));
265 		numattr++;
266 	}
267 
268 	if (oclass & PK_PRIKEY_OBJ) {
269 		int num = numattr;
270 
271 		keyclass = KMF_ASYM_PRI;
272 		kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR,
273 		    &keyclass, sizeof (keyclass));
274 		num++;
275 
276 		keytype = "private";
277 		rv = pk_delete_keys(kmfhandle, attrlist, num, keytype, &nk);
278 		numkeys += nk;
279 	}
280 	if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) {
281 		int num = numattr;
282 
283 		keyclass = KMF_SYMMETRIC;
284 		kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR,
285 		    &keyclass, sizeof (keyclass));
286 		num++;
287 
288 		keytype = "symmetric";
289 		rv = pk_delete_keys(kmfhandle, attrlist, num, keytype, &nk);
290 		numkeys += nk;
291 	}
292 	if (rv == KMF_OK && (oclass & PK_PUBKEY_OBJ)) {
293 		int num = numattr;
294 
295 		keyclass = KMF_ASYM_PUB;
296 		kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR,
297 		    &keyclass, sizeof (keyclass));
298 		num++;
299 
300 		keytype = "public";
301 		rv = pk_delete_keys(kmfhandle, attrlist, num, keytype, &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 
311 static KMF_RETURN
312 delete_nss_certs(KMF_HANDLE_T kmfhandle,
313 	char *dir, char *prefix,
314 	char *token, char *objlabel,
315 	KMF_BIGINT *serno, char *issuer, char *subject,
316 	KMF_CERT_VALIDITY find_criteria_flag)
317 {
318 	KMF_RETURN rv = KMF_OK;
319 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
320 	int numattr = 0;
321 	KMF_ATTRIBUTE attrlist[16];
322 
323 	rv = configure_nss(kmfhandle, dir, prefix);
324 	if (rv != KMF_OK)
325 		return (rv);
326 
327 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
328 		    &kstype, sizeof (kstype));
329 		numattr++;
330 
331 		if (objlabel != NULL) {
332 			kmf_set_attr_at_index(attrlist, numattr,
333 			    KMF_CERT_LABEL_ATTR, objlabel,
334 			    strlen(objlabel));
335 			numattr++;
336 		}
337 
338 		if (issuer != NULL) {
339 			kmf_set_attr_at_index(attrlist, numattr,
340 			    KMF_ISSUER_NAME_ATTR, issuer,
341 			    strlen(issuer));
342 			numattr++;
343 		}
344 
345 		if (subject != NULL) {
346 			kmf_set_attr_at_index(attrlist, numattr,
347 			    KMF_SUBJECT_NAME_ATTR, subject,
348 			    strlen(subject));
349 			numattr++;
350 		}
351 
352 		if (serno != NULL) {
353 			kmf_set_attr_at_index(attrlist, numattr,
354 			    KMF_BIGINT_ATTR, serno,
355 			    sizeof (KMF_BIGINT));
356 			numattr++;
357 		}
358 
359 		kmf_set_attr_at_index(attrlist, numattr,
360 		    KMF_CERT_VALIDITY_ATTR, &find_criteria_flag,
361 		    sizeof (KMF_CERT_VALIDITY));
362 		numattr++;
363 
364 		if (token != NULL) {
365 			kmf_set_attr_at_index(attrlist, numattr,
366 			    KMF_TOKEN_LABEL_ATTR, token,
367 			    strlen(token));
368 			numattr++;
369 		}
370 
371 	rv = pk_delete_certs(kmfhandle, attrlist, numattr);
372 
373 	return (rv);
374 }
375 
376 static KMF_RETURN
377 delete_nss_crl(void *kmfhandle,
378 	char *dir, char *prefix, char *token,
379 	char *issuer, char *subject)
380 {
381 	KMF_RETURN rv = KMF_OK;
382 	int numattr = 0;
383 	KMF_ATTRIBUTE attrlist[8];
384 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
385 
386 	rv = configure_nss(kmfhandle, dir, prefix);
387 	if (rv != KMF_OK)
388 		return (rv);
389 
390 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
391 	    &kstype, sizeof (kstype));
392 	numattr++;
393 
394 	if (token != NULL) {
395 		kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
396 		    token, strlen(token));
397 		numattr++;
398 	}
399 	if (issuer != NULL) {
400 		kmf_set_attr_at_index(attrlist, numattr, KMF_ISSUER_NAME_ATTR,
401 		    issuer, strlen(issuer));
402 		numattr++;
403 	}
404 	if (subject != NULL) {
405 		kmf_set_attr_at_index(attrlist, numattr, KMF_SUBJECT_NAME_ATTR,
406 		    subject, strlen(subject));
407 		numattr++;
408 	}
409 
410 	rv = kmf_delete_crl(kmfhandle, numattr, attrlist);
411 
412 	return (rv);
413 }
414 
415 static KMF_RETURN
416 delete_pk11_keys(KMF_HANDLE_T kmfhandle,
417 	char *token, int oclass, char *objlabel,
418 	KMF_CREDENTIAL *tokencred)
419 {
420 	KMF_RETURN rv = KMF_OK;
421 	int nk, numkeys = 0;
422 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
423 	int numattr = 0;
424 	KMF_ATTRIBUTE attrlist[16];
425 	KMF_KEY_CLASS keyclass;
426 	boolean_t token_bool = B_TRUE;
427 	KMF_KEY_ALG keytype = 0;
428 	boolean_t private;
429 	/*
430 	 * Symmetric keys and RSA/DSA private keys are always
431 	 * created with the "CKA_PRIVATE" field == TRUE, so
432 	 * make sure we search for them with it also set.
433 	 */
434 	if (oclass & (PK_SYMKEY_OBJ | PK_PRIKEY_OBJ))
435 		oclass |= PK_PRIVATE_OBJ;
436 
437 	rv = select_token(kmfhandle, token, FALSE);
438 	if (rv != KMF_OK) {
439 		return (rv);
440 	}
441 
442 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
443 	    &kstype, sizeof (kstype));
444 	numattr++;
445 
446 	if (objlabel != NULL) {
447 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR,
448 		    objlabel, strlen(objlabel));
449 		numattr++;
450 	}
451 
452 	if (tokencred != NULL && tokencred->credlen > 0) {
453 		kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
454 		    tokencred, sizeof (KMF_CREDENTIAL));
455 		numattr++;
456 	}
457 
458 	private = ((oclass & PK_PRIVATE_OBJ) > 0);
459 
460 	kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVATE_BOOL_ATTR,
461 	    &private, sizeof (private));
462 	numattr++;
463 
464 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYALG_ATTR,
465 	    &keytype, sizeof (keytype));
466 	numattr++;
467 
468 	kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_BOOL_ATTR,
469 	    &token_bool, sizeof (token_bool));
470 	numattr++;
471 
472 	if (oclass & PK_PRIKEY_OBJ) {
473 		int num = numattr;
474 
475 		keyclass = KMF_ASYM_PRI;
476 		kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR,
477 		    &keyclass, sizeof (keyclass));
478 		num++;
479 
480 		rv = pk_delete_keys(kmfhandle, attrlist, num, "private", &nk);
481 		numkeys += nk;
482 	}
483 
484 	if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) {
485 		int num = numattr;
486 
487 		keyclass = KMF_SYMMETRIC;
488 		kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR,
489 		    &keyclass, sizeof (keyclass));
490 		num++;
491 
492 		rv = pk_delete_keys(kmfhandle, attrlist, num, "symmetric", &nk);
493 		numkeys += nk;
494 	}
495 
496 	if (rv == KMF_OK && (oclass & PK_PUBKEY_OBJ)) {
497 		int num = numattr;
498 
499 		keyclass = KMF_ASYM_PUB;
500 		kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR,
501 		    &keyclass, sizeof (keyclass));
502 		num++;
503 
504 		rv = pk_delete_keys(kmfhandle, attrlist, num, "public", &nk);
505 		numkeys += nk;
506 	}
507 	if (rv == KMF_OK && numkeys == 0)
508 		rv = KMF_ERR_KEY_NOT_FOUND;
509 
510 	return (rv);
511 }
512 
513 static KMF_RETURN
514 delete_pk11_certs(KMF_HANDLE_T kmfhandle,
515 	char *token, char *objlabel,
516 	KMF_BIGINT *serno, char *issuer, char *subject,
517 	KMF_CERT_VALIDITY find_criteria_flag)
518 {
519 	KMF_RETURN kmfrv;
520 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
521 	int numattr = 0;
522 	KMF_ATTRIBUTE attrlist[16];
523 
524 	kmfrv = select_token(kmfhandle, token, FALSE);
525 
526 	if (kmfrv != KMF_OK) {
527 		return (kmfrv);
528 	}
529 
530 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
531 	    &kstype, sizeof (kstype));
532 	numattr++;
533 
534 	if (objlabel != NULL) {
535 		kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR,
536 		    objlabel, strlen(objlabel));
537 		numattr++;
538 	}
539 
540 	if (issuer != NULL) {
541 		kmf_set_attr_at_index(attrlist, numattr, KMF_ISSUER_NAME_ATTR,
542 		    issuer, strlen(issuer));
543 		numattr++;
544 	}
545 
546 	if (subject != NULL) {
547 		kmf_set_attr_at_index(attrlist, numattr, KMF_SUBJECT_NAME_ATTR,
548 		    subject, strlen(subject));
549 		numattr++;
550 	}
551 
552 	if (serno != NULL) {
553 		kmf_set_attr_at_index(attrlist, numattr, KMF_BIGINT_ATTR,
554 		    serno, sizeof (KMF_BIGINT));
555 		numattr++;
556 	}
557 
558 	kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_VALIDITY_ATTR,
559 	    &find_criteria_flag, sizeof (KMF_CERT_VALIDITY));
560 	numattr++;
561 
562 	kmfrv = pk_delete_certs(kmfhandle, attrlist, numattr);
563 
564 	return (kmfrv);
565 }
566 
567 static KMF_RETURN
568 delete_file_certs(KMF_HANDLE_T kmfhandle,
569 	char *dir, char *filename, KMF_BIGINT *serial, char *issuer,
570 	char *subject, KMF_CERT_VALIDITY find_criteria_flag)
571 {
572 	KMF_RETURN rv;
573 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
574 	int numattr = 0;
575 	KMF_ATTRIBUTE attrlist[16];
576 
577 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
578 	    &kstype, sizeof (kstype));
579 	numattr++;
580 
581 	if (issuer != NULL) {
582 		kmf_set_attr_at_index(attrlist, numattr, KMF_ISSUER_NAME_ATTR,
583 		    issuer, strlen(issuer));
584 		numattr++;
585 	}
586 
587 	if (subject != NULL) {
588 		kmf_set_attr_at_index(attrlist, numattr, KMF_SUBJECT_NAME_ATTR,
589 		    subject, strlen(subject));
590 		numattr++;
591 	}
592 
593 	if (serial != NULL) {
594 		kmf_set_attr_at_index(attrlist, numattr, KMF_BIGINT_ATTR,
595 		    serial, sizeof (KMF_BIGINT));
596 		numattr++;
597 	}
598 
599 	if (dir != NULL) {
600 		kmf_set_attr_at_index(attrlist, numattr, KMF_DIRPATH_ATTR,
601 		    dir, strlen(dir));
602 		numattr++;
603 	}
604 
605 	if (filename != NULL) {
606 		kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_FILENAME_ATTR,
607 		    filename, strlen(filename));
608 		numattr++;
609 	}
610 
611 	kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_VALIDITY_ATTR,
612 	    &find_criteria_flag, sizeof (KMF_CERT_VALIDITY));
613 	numattr++;
614 
615 	rv = pk_delete_certs(kmfhandle, attrlist, numattr);
616 
617 	return (rv);
618 }
619 
620 static KMF_RETURN
621 delete_file_keys(KMF_HANDLE_T kmfhandle, int oclass,
622 	char *dir, char *infile)
623 {
624 	KMF_RETURN rv = KMF_OK;
625 	char *keytype = "";
626 	int nk, numkeys = 0;
627 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
628 	int numattr = 0;
629 	KMF_ATTRIBUTE attrlist[16];
630 	KMF_KEY_CLASS keyclass;
631 
632 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
633 	    &kstype, sizeof (kstype));
634 	numattr++;
635 
636 	if (dir != NULL) {
637 		kmf_set_attr_at_index(attrlist, numattr, KMF_DIRPATH_ATTR,
638 		    dir, strlen(dir));
639 		numattr++;
640 	}
641 
642 	if (infile != NULL) {
643 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR,
644 		    infile, strlen(infile));
645 		numattr++;
646 	}
647 
648 	if (oclass & (PK_PUBKEY_OBJ | PK_PRIKEY_OBJ)) {
649 		int num = numattr;
650 
651 		keyclass = KMF_ASYM_PRI;
652 		kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR,
653 		    &keyclass, sizeof (keyclass));
654 		num++;
655 
656 		keytype = "Asymmetric";
657 		rv = pk_delete_keys(kmfhandle, attrlist, num, keytype, &nk);
658 		numkeys += nk;
659 	}
660 	if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) {
661 		int num = numattr;
662 
663 		keyclass = KMF_SYMMETRIC;
664 		kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR,
665 		    &keyclass, sizeof (keyclass));
666 		num++;
667 
668 		keytype = "symmetric";
669 		rv = pk_delete_keys(kmfhandle, attrlist, num, keytype, &nk);
670 		numkeys += nk;
671 	}
672 	if (rv == KMF_OK && numkeys == 0)
673 		rv = KMF_ERR_KEY_NOT_FOUND;
674 
675 	return (rv);
676 }
677 
678 static KMF_RETURN
679 delete_file_crl(void *kmfhandle, char *dir, char *filename)
680 {
681 	KMF_RETURN rv;
682 	int numattr = 0;
683 	KMF_ATTRIBUTE attrlist[4];
684 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
685 
686 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
687 	    &kstype, sizeof (kstype));
688 	numattr++;
689 
690 	if (dir) {
691 		kmf_set_attr_at_index(attrlist, numattr, KMF_DIRPATH_ATTR,
692 		    dir, strlen(dir));
693 		numattr++;
694 	}
695 	if (filename) {
696 		kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_FILENAME_ATTR,
697 		    filename, strlen(filename));
698 		numattr++;
699 	}
700 
701 	rv = kmf_delete_crl(kmfhandle, numattr, attrlist);
702 
703 	return (rv);
704 }
705 
706 /*
707  * Delete token objects.
708  */
709 int
710 pk_delete(int argc, char *argv[])
711 {
712 	int		opt;
713 	extern int	optind_av;
714 	extern char	*optarg_av;
715 	char		*token_spec = NULL;
716 	char		*subject = NULL;
717 	char		*issuer = NULL;
718 	char		*dir = NULL;
719 	char		*prefix = NULL;
720 	char		*infile = NULL;
721 	char		*object_label = NULL;
722 	char		*serstr = NULL;
723 
724 	int		oclass = 0;
725 	KMF_BIGINT	serial = { NULL, 0 };
726 	KMF_HANDLE_T	kmfhandle = NULL;
727 	KMF_KEYSTORE_TYPE	kstype = 0;
728 	KMF_RETURN	kmfrv;
729 	int		rv = 0;
730 	char			*find_criteria = NULL;
731 	KMF_CERT_VALIDITY	find_criteria_flag = KMF_ALL_CERTS;
732 	KMF_CREDENTIAL	tokencred = {NULL, 0};
733 
734 	/* Parse command line options.  Do NOT i18n/l10n. */
735 	while ((opt = getopt_av(argc, argv,
736 	    "T:(token)y:(objtype)l:(label)"
737 	    "k:(keystore)s:(subject)n:(nickname)"
738 	    "d:(dir)p:(prefix)S:(serial)i:(issuer)"
739 	    "c:(criteria)"
740 	    "f:(infile)")) != EOF) {
741 
742 		if (EMPTYSTRING(optarg_av))
743 			return (PK_ERR_USAGE);
744 		switch (opt) {
745 		case 'T':	/* token specifier */
746 			if (token_spec)
747 				return (PK_ERR_USAGE);
748 			token_spec = optarg_av;
749 			break;
750 		case 'y':	/* object type:  public, private, both */
751 			if (oclass)
752 				return (PK_ERR_USAGE);
753 			oclass = OT2Int(optarg_av);
754 			if (oclass == -1)
755 				return (PK_ERR_USAGE);
756 			break;
757 		case 'l':	/* objects with specific label */
758 		case 'n':
759 			if (object_label)
760 				return (PK_ERR_USAGE);
761 			object_label = (char *)optarg_av;
762 			break;
763 		case 'k':
764 			kstype = KS2Int(optarg_av);
765 			if (kstype == 0)
766 				return (PK_ERR_USAGE);
767 			break;
768 		case 's':
769 			subject = optarg_av;
770 			break;
771 		case 'i':
772 			issuer = optarg_av;
773 			break;
774 		case 'd':
775 			dir = optarg_av;
776 			break;
777 		case 'p':
778 			prefix = optarg_av;
779 			break;
780 		case 'S':
781 			serstr = optarg_av;
782 			break;
783 		case 'f':
784 			infile = optarg_av;
785 			break;
786 		case 'c':
787 			find_criteria = optarg_av;
788 			if (!strcasecmp(find_criteria, "valid"))
789 				find_criteria_flag =
790 				    KMF_NONEXPIRED_CERTS;
791 			else if (!strcasecmp(find_criteria, "expired"))
792 				find_criteria_flag = KMF_EXPIRED_CERTS;
793 			else if (!strcasecmp(find_criteria, "both"))
794 				find_criteria_flag = KMF_ALL_CERTS;
795 			else
796 				return (PK_ERR_USAGE);
797 			break;
798 		default:
799 			return (PK_ERR_USAGE);
800 			break;
801 		}
802 	}
803 
804 	/* Assume keystore = PKCS#11 if not specified */
805 	if (kstype == 0)
806 		kstype = KMF_KEYSTORE_PK11TOKEN;
807 
808 	/* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
809 	if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
810 	    kstype != KMF_KEYSTORE_PK11TOKEN) {
811 
812 		(void) fprintf(stderr, gettext("The objtype parameter "
813 		    "is only relevant if keystore=pkcs11\n"));
814 		return (PK_ERR_USAGE);
815 	}
816 
817 	/* If no object class specified, delete everything but CRLs */
818 	if (oclass == 0)
819 		oclass = PK_CERT_OBJ | PK_PUBKEY_OBJ | PK_PRIKEY_OBJ |
820 		    PK_SYMKEY_OBJ;
821 
822 	/* No additional args allowed. */
823 	argc -= optind_av;
824 	argv += optind_av;
825 	if (argc)
826 		return (PK_ERR_USAGE);
827 	/* Done parsing command line options. */
828 
829 	if (kstype == KMF_KEYSTORE_PK11TOKEN && token_spec == NULL) {
830 		token_spec = PK_DEFAULT_PK11TOKEN;
831 	} else if (kstype == KMF_KEYSTORE_NSS && token_spec == NULL) {
832 		token_spec = DEFAULT_NSS_TOKEN;
833 	}
834 
835 	if (serstr != NULL) {
836 		uchar_t *bytes = NULL;
837 		size_t bytelen;
838 
839 		rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen);
840 		if (rv != KMF_OK || bytes == NULL) {
841 			(void) fprintf(stderr, gettext("serial number "
842 			    "must be specified as a hex number "
843 			    "(ex: 0x0102030405ffeeddee)\n"));
844 			return (PK_ERR_USAGE);
845 		}
846 		serial.val = bytes;
847 		serial.len = bytelen;
848 	}
849 
850 	if ((kstype == KMF_KEYSTORE_PK11TOKEN ||
851 	    kstype == KMF_KEYSTORE_NSS) &&
852 	    (oclass & (PK_KEY_OBJ | PK_PRIVATE_OBJ))) {
853 
854 		(void) get_token_password(kstype, token_spec,
855 		    &tokencred);
856 	}
857 
858 	if ((kmfrv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK)
859 		return (kmfrv);
860 
861 	switch (kstype) {
862 		case KMF_KEYSTORE_PK11TOKEN:
863 			if (oclass & PK_KEY_OBJ) {
864 				kmfrv = delete_pk11_keys(kmfhandle,
865 				    token_spec, oclass,
866 				    object_label, &tokencred);
867 				/*
868 				 * If deleting groups of objects, it is OK
869 				 * to ignore the "key not found" case so that
870 				 * we can continue to find other objects.
871 				 */
872 				if (kmfrv == KMF_ERR_KEY_NOT_FOUND &&
873 				    (oclass != PK_KEY_OBJ))
874 					kmfrv = KMF_OK;
875 				if (kmfrv != KMF_OK)
876 					break;
877 			}
878 			if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) {
879 				kmfrv = delete_pk11_certs(kmfhandle,
880 				    token_spec, object_label,
881 				    &serial, issuer,
882 				    subject, find_criteria_flag);
883 				/*
884 				 * If cert delete failed, but we are looking at
885 				 * other objects, then it is OK.
886 				 */
887 				if (kmfrv == KMF_ERR_CERT_NOT_FOUND &&
888 				    (oclass & (PK_CRL_OBJ | PK_KEY_OBJ)))
889 					kmfrv = KMF_OK;
890 				if (kmfrv != KMF_OK)
891 					break;
892 			}
893 			if (oclass & PK_CRL_OBJ)
894 				kmfrv = delete_file_crl(kmfhandle,
895 				    dir, infile);
896 			break;
897 		case KMF_KEYSTORE_NSS:
898 			if (oclass & PK_KEY_OBJ) {
899 				kmfrv = delete_nss_keys(kmfhandle,
900 				    dir, prefix, token_spec,
901 				    oclass, (char  *)object_label,
902 				    &tokencred);
903 				if (kmfrv != KMF_OK)
904 					break;
905 			}
906 			if (oclass & PK_CERT_OBJ) {
907 				kmfrv = delete_nss_certs(kmfhandle,
908 				    dir, prefix, token_spec,
909 				    (char  *)object_label,
910 				    &serial, issuer, subject,
911 				    find_criteria_flag);
912 				if (kmfrv != KMF_OK)
913 					break;
914 			}
915 			if (oclass & PK_CRL_OBJ)
916 				kmfrv = delete_nss_crl(kmfhandle,
917 				    dir, prefix, token_spec,
918 				    (char  *)object_label, subject);
919 			break;
920 		case KMF_KEYSTORE_OPENSSL:
921 			if (oclass & PK_KEY_OBJ) {
922 				kmfrv = delete_file_keys(kmfhandle, oclass,
923 				    dir, infile);
924 				if (kmfrv != KMF_OK)
925 					break;
926 			}
927 			if (oclass & (PK_CERT_OBJ)) {
928 				kmfrv = delete_file_certs(kmfhandle,
929 				    dir, infile, &serial, issuer,
930 				    subject, find_criteria_flag);
931 				if (kmfrv != KMF_OK)
932 					break;
933 			}
934 			if (oclass & PK_CRL_OBJ)
935 				kmfrv = delete_file_crl(kmfhandle,
936 				    dir, infile);
937 			break;
938 		default:
939 			rv = PK_ERR_USAGE;
940 			break;
941 	}
942 
943 	if (kmfrv != KMF_OK) {
944 		display_error(kmfhandle, kmfrv,
945 		    gettext("Error deleting objects"));
946 	}
947 
948 	if (serial.val != NULL)
949 		free(serial.val);
950 	(void) kmf_finalize(kmfhandle);
951 	return (kmfrv);
952 }
953