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