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