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 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 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 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 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 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 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 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 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 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 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 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 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