delete.c revision 5051:cbbb7c8b40a9
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
41static KMF_RETURN
42pk_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
134static KMF_RETURN
135pk_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
192static KMF_RETURN
193pk_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
229static KMF_RETURN
230delete_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
311static KMF_RETURN
312delete_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
376static KMF_RETURN
377delete_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
415static KMF_RETURN
416delete_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
513static KMF_RETURN
514delete_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
567static KMF_RETURN
568delete_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
620static KMF_RETURN
621delete_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
678static KMF_RETURN
679delete_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 */
709int
710pk_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