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