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 * Copyright 2017 Toomas Soome <tsoome@me.com>
26 */
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, 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