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 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 *keysdeleted = numkeys; 186 return (rv); 187 } 188 189 static KMF_RETURN 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 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 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 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 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 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 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 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 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