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