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 2006 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_KEY_HANDLE *keys, 43 KMF_FINDKEY_PARAMS *fkparams, uint32_t numkeys) 44 { 45 int i; 46 KMF_RETURN rv = KMF_OK; 47 KMF_DELETEKEY_PARAMS dkparams; 48 49 (void) memset(&dkparams, 0, sizeof (dkparams)); 50 dkparams.kstype = fkparams->kstype; 51 52 switch (fkparams->kstype) { 53 case KMF_KEYSTORE_NSS: 54 dkparams.nssparms = fkparams->nssparms; 55 dkparams.cred = fkparams->cred; 56 break; 57 case KMF_KEYSTORE_OPENSSL: 58 break; 59 case KMF_KEYSTORE_PK11TOKEN: 60 dkparams.cred = fkparams->cred; 61 break; 62 default: 63 return (PK_ERR_USAGE); 64 } 65 66 for (i = 0; rv == KMF_OK && i < numkeys; i++) { 67 rv = KMF_DeleteKeyFromKeystore(handle, &dkparams, &keys[i]); 68 } 69 return (rv); 70 } 71 72 static KMF_RETURN 73 pk_delete_keys(KMF_HANDLE_T kmfhandle, KMF_FINDKEY_PARAMS *parms, char *desc, 74 int *keysdeleted) 75 { 76 KMF_RETURN rv = KMF_OK; 77 uint32_t numkeys = 0; 78 79 *keysdeleted = 0; 80 numkeys = 0; 81 rv = KMF_FindKey(kmfhandle, parms, NULL, &numkeys); 82 if (rv == KMF_OK && numkeys > 0) { 83 KMF_KEY_HANDLE *keys = NULL; 84 char prompt[1024]; 85 86 (void) snprintf(prompt, sizeof (prompt), 87 gettext("%d %s key(s) found, do you want " 88 "to delete them (y/N) ?"), numkeys, 89 (desc != NULL ? desc : "")); 90 91 if (!yesno(prompt, 92 gettext("Respond with yes or no.\n"), 93 B_FALSE)) { 94 return (KMF_OK); 95 } 96 keys = (KMF_KEY_HANDLE *)malloc(numkeys * 97 sizeof (KMF_KEY_HANDLE)); 98 if (keys == NULL) 99 return (KMF_ERR_MEMORY); 100 (void) memset(keys, 0, numkeys * 101 sizeof (KMF_KEY_HANDLE)); 102 103 rv = KMF_FindKey(kmfhandle, parms, keys, &numkeys); 104 if (rv == KMF_OK) { 105 rv = pk_destroy_keys(kmfhandle, keys, 106 parms, numkeys); 107 } 108 109 free(keys); 110 } 111 112 if (rv == KMF_ERR_KEY_NOT_FOUND) { 113 rv = KMF_OK; 114 } 115 116 *keysdeleted = numkeys; 117 return (rv); 118 } 119 120 static KMF_RETURN 121 pk_delete_certs(KMF_HANDLE_T kmfhandle, KMF_FINDCERT_PARAMS *fcparms, 122 KMF_DELETECERT_PARAMS *dcparms) 123 { 124 KMF_RETURN rv = KMF_OK; 125 uint32_t numcerts = 0; 126 127 rv = KMF_FindCert(kmfhandle, fcparms, NULL, &numcerts); 128 if (rv == KMF_OK && numcerts > 0) { 129 char prompt[1024]; 130 (void) snprintf(prompt, sizeof (prompt), 131 gettext("%d certificate(s) found, do you want " 132 "to delete them (y/N) ?"), numcerts); 133 134 if (!yesno(prompt, 135 gettext("Respond with yes or no.\n"), 136 B_FALSE)) { 137 return (KMF_OK); 138 } 139 140 rv = KMF_DeleteCertFromKeystore(kmfhandle, dcparms); 141 142 } else if (rv == KMF_ERR_CERT_NOT_FOUND) { 143 rv = KMF_OK; 144 } 145 146 return (rv); 147 } 148 149 static KMF_RETURN 150 delete_nss_keys(KMF_HANDLE_T kmfhandle, char *dir, char *prefix, 151 char *token, int oclass, char *objlabel, 152 KMF_CREDENTIAL *tokencred) 153 { 154 KMF_RETURN rv = KMF_OK; 155 KMF_FINDKEY_PARAMS parms; 156 char *keytype = NULL; 157 int nk, numkeys = 0; 158 159 rv = configure_nss(kmfhandle, dir, prefix); 160 if (rv != KMF_OK) 161 return (rv); 162 163 (void) memset(&parms, 0, sizeof (parms)); 164 parms.kstype = KMF_KEYSTORE_NSS; 165 parms.findLabel = objlabel; 166 parms.cred = *tokencred; 167 parms.nssparms.slotlabel = token; 168 169 if (oclass & PK_PRIKEY_OBJ) { 170 parms.keyclass = KMF_ASYM_PRI; 171 keytype = "private"; 172 rv = pk_delete_keys(kmfhandle, &parms, keytype, &nk); 173 numkeys += nk; 174 } 175 if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) { 176 parms.keyclass = KMF_SYMMETRIC; 177 keytype = "symmetric"; 178 rv = pk_delete_keys(kmfhandle, &parms, keytype, &nk); 179 numkeys += nk; 180 } 181 if (rv == KMF_OK && (oclass & PK_PUBKEY_OBJ)) { 182 parms.keyclass = KMF_ASYM_PUB; 183 keytype = "public"; 184 rv = pk_delete_keys(kmfhandle, &parms, keytype, &nk); 185 numkeys += nk; 186 } 187 if (rv == KMF_OK && numkeys == 0) 188 rv = KMF_ERR_KEY_NOT_FOUND; 189 190 return (rv); 191 } 192 193 194 static KMF_RETURN 195 delete_nss_certs(KMF_HANDLE_T kmfhandle, 196 char *dir, char *prefix, 197 char *token, char *objlabel, 198 KMF_BIGINT *serno, char *issuer, char *subject, 199 KMF_CERT_VALIDITY find_criteria_flag) 200 { 201 KMF_RETURN rv = KMF_OK; 202 KMF_DELETECERT_PARAMS dcparms; 203 KMF_FINDCERT_PARAMS fcargs; 204 205 rv = configure_nss(kmfhandle, dir, prefix); 206 if (rv != KMF_OK) 207 return (rv); 208 209 (void) memset(&dcparms, 0, sizeof (dcparms)); 210 dcparms.kstype = KMF_KEYSTORE_NSS; 211 dcparms.certLabel = objlabel; 212 dcparms.issuer = issuer; 213 dcparms.subject = subject; 214 dcparms.serial = serno; 215 dcparms.find_cert_validity = find_criteria_flag; 216 dcparms.nssparms.slotlabel = token; 217 218 (void) memset(&fcargs, 0, sizeof (fcargs)); 219 fcargs.kstype = KMF_KEYSTORE_NSS; 220 fcargs.certLabel = objlabel; 221 fcargs.issuer = issuer; 222 fcargs.subject = subject; 223 fcargs.serial = serno; 224 fcargs.find_cert_validity = find_criteria_flag; 225 fcargs.nssparms.slotlabel = token; 226 227 rv = pk_delete_certs(kmfhandle, &fcargs, &dcparms); 228 229 return (rv); 230 } 231 232 static KMF_RETURN 233 delete_nss_crl(void *kmfhandle, 234 char *dir, char *prefix, char *token, 235 char *issuernickname, char *subject) 236 { 237 KMF_RETURN rv = KMF_OK; 238 KMF_DELETECRL_PARAMS dcrlparms; 239 240 rv = configure_nss(kmfhandle, dir, prefix); 241 if (rv != KMF_OK) 242 return (rv); 243 244 (void) memset(&dcrlparms, 0, sizeof (dcrlparms)); 245 246 dcrlparms.kstype = KMF_KEYSTORE_NSS; 247 dcrlparms.nssparms.slotlabel = token; 248 dcrlparms.nssparms.crl_issuerName = issuernickname; 249 dcrlparms.nssparms.crl_subjName = subject; 250 251 rv = KMF_DeleteCRL(kmfhandle, &dcrlparms); 252 253 return (rv); 254 } 255 256 static KMF_RETURN 257 delete_pk11_keys(KMF_HANDLE_T kmfhandle, 258 char *token, int oclass, char *objlabel, 259 KMF_CREDENTIAL *tokencred) 260 { 261 KMF_RETURN rv = KMF_OK; 262 KMF_FINDKEY_PARAMS parms; 263 int nk, numkeys = 0; 264 265 /* 266 * Symmetric keys and RSA/DSA private keys are always 267 * created with the "CKA_PRIVATE" field == TRUE, so 268 * make sure we search for them with it also set. 269 */ 270 if (oclass & (PK_SYMKEY_OBJ | PK_PRIKEY_OBJ)) 271 oclass |= PK_PRIVATE_OBJ; 272 273 rv = select_token(kmfhandle, token, FALSE); 274 if (rv != KMF_OK) { 275 return (rv); 276 } 277 278 (void) memset(&parms, 0, sizeof (parms)); 279 parms.kstype = KMF_KEYSTORE_PK11TOKEN; 280 parms.findLabel = (char *)objlabel; 281 parms.keytype = 0; 282 parms.pkcs11parms.private = ((oclass & PK_PRIVATE_OBJ) > 0); 283 parms.cred.cred = tokencred->cred; 284 parms.cred.credlen = tokencred->credlen; 285 286 if (oclass & PK_PRIKEY_OBJ) { 287 parms.keyclass = KMF_ASYM_PRI; 288 rv = pk_delete_keys(kmfhandle, &parms, "private", &nk); 289 numkeys += nk; 290 } 291 292 if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) { 293 parms.keyclass = KMF_SYMMETRIC; 294 rv = pk_delete_keys(kmfhandle, &parms, "symmetric", &nk); 295 numkeys += nk; 296 } 297 298 if (rv == KMF_OK && (oclass & PK_PUBKEY_OBJ)) { 299 parms.keyclass = KMF_ASYM_PUB; 300 rv = pk_delete_keys(kmfhandle, &parms, "public", &nk); 301 numkeys += nk; 302 } 303 if (rv == KMF_OK && numkeys == 0) 304 rv = KMF_ERR_KEY_NOT_FOUND; 305 306 return (rv); 307 } 308 309 static KMF_RETURN 310 delete_pk11_certs(KMF_HANDLE_T kmfhandle, 311 char *token, char *objlabel, 312 KMF_BIGINT *serno, char *issuer, char *subject, 313 KMF_CERT_VALIDITY find_criteria_flag) 314 { 315 KMF_RETURN kmfrv; 316 KMF_DELETECERT_PARAMS dparms; 317 KMF_FINDCERT_PARAMS fcargs; 318 319 kmfrv = select_token(kmfhandle, token, FALSE); 320 321 if (kmfrv != KMF_OK) { 322 return (kmfrv); 323 } 324 325 (void) memset(&dparms, 0, sizeof (dparms)); 326 dparms.kstype = KMF_KEYSTORE_PK11TOKEN; 327 dparms.certLabel = objlabel; 328 dparms.issuer = issuer; 329 dparms.subject = subject; 330 dparms.serial = serno; 331 dparms.find_cert_validity = find_criteria_flag; 332 333 fcargs = dparms; 334 kmfrv = pk_delete_certs(kmfhandle, &fcargs, &dparms); 335 336 return (kmfrv); 337 } 338 339 static KMF_RETURN 340 delete_file_certs(KMF_HANDLE_T kmfhandle, 341 char *dir, char *filename, KMF_BIGINT *serial, char *issuer, 342 char *subject, KMF_CERT_VALIDITY find_criteria_flag) 343 { 344 KMF_RETURN rv; 345 KMF_DELETECERT_PARAMS dparms; 346 KMF_FINDCERT_PARAMS fcargs; 347 348 (void *)memset(&dparms, 0, sizeof (dparms)); 349 (void *)memset(&fcargs, 0, sizeof (fcargs)); 350 fcargs.kstype = KMF_KEYSTORE_OPENSSL; 351 fcargs.certLabel = NULL; 352 fcargs.issuer = issuer; 353 fcargs.subject = subject; 354 fcargs.serial = serial; 355 fcargs.sslparms.dirpath = dir; 356 fcargs.sslparms.certfile = filename; 357 fcargs.find_cert_validity = find_criteria_flag; 358 359 /* For now, delete parameters and find parameters are the same */ 360 dparms = fcargs; 361 362 rv = pk_delete_certs(kmfhandle, &fcargs, &dparms); 363 364 return (rv); 365 } 366 367 static KMF_RETURN 368 delete_file_keys(KMF_HANDLE_T kmfhandle, int oclass, 369 char *dir, char *infile) 370 { 371 KMF_RETURN rv = KMF_OK; 372 KMF_FINDKEY_PARAMS parms; 373 char *keytype = ""; 374 int nk, numkeys = 0; 375 376 (void) memset(&parms, 0, sizeof (parms)); 377 parms.kstype = KMF_KEYSTORE_OPENSSL; 378 parms.sslparms.dirpath = dir; 379 parms.sslparms.keyfile = infile; 380 381 if (oclass & (PK_PUBKEY_OBJ | PK_PRIKEY_OBJ)) { 382 parms.keyclass = KMF_ASYM_PRI; 383 keytype = "Asymmetric"; 384 rv = pk_delete_keys(kmfhandle, &parms, keytype, &nk); 385 numkeys += nk; 386 } 387 if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) { 388 parms.keyclass = KMF_SYMMETRIC; 389 keytype = "symmetric"; 390 rv = pk_delete_keys(kmfhandle, &parms, keytype, &nk); 391 numkeys += nk; 392 } 393 if (rv == KMF_OK && numkeys == 0) 394 rv = KMF_ERR_KEY_NOT_FOUND; 395 396 return (rv); 397 } 398 399 static KMF_RETURN 400 delete_file_crl(void *kmfhandle, char *dir, char *filename) 401 { 402 KMF_RETURN rv; 403 KMF_DELETECRL_PARAMS dcrlparms; 404 405 (void) memset(&dcrlparms, 0, sizeof (dcrlparms)); 406 407 dcrlparms.kstype = KMF_KEYSTORE_OPENSSL; 408 dcrlparms.sslparms.dirpath = dir; 409 dcrlparms.sslparms.crlfile = filename; 410 411 rv = KMF_DeleteCRL(kmfhandle, &dcrlparms); 412 413 return (rv); 414 } 415 416 /* 417 * Delete token objects. 418 */ 419 int 420 pk_delete(int argc, char *argv[]) 421 { 422 int opt; 423 extern int optind_av; 424 extern char *optarg_av; 425 char *token_spec = NULL; 426 char *subject = NULL; 427 char *issuer = NULL; 428 char *dir = NULL; 429 char *prefix = NULL; 430 char *infile = NULL; 431 char *object_label = NULL; 432 char *serstr = NULL; 433 434 int oclass = 0; 435 KMF_BIGINT serial = { NULL, 0 }; 436 KMF_HANDLE_T kmfhandle = NULL; 437 KMF_KEYSTORE_TYPE kstype = 0; 438 KMF_RETURN kmfrv; 439 int rv = 0; 440 char *find_criteria = NULL; 441 KMF_CERT_VALIDITY find_criteria_flag = KMF_ALL_CERTS; 442 KMF_CREDENTIAL tokencred = {NULL, 0}; 443 444 /* Parse command line options. Do NOT i18n/l10n. */ 445 while ((opt = getopt_av(argc, argv, 446 "T:(token)y:(objtype)l:(label)" 447 "k:(keystore)s:(subject)n:(nickname)" 448 "d:(dir)p:(prefix)S:(serial)i:(issuer)" 449 "c:(criteria)" 450 "f:(infile)")) != EOF) { 451 452 if (EMPTYSTRING(optarg_av)) 453 return (PK_ERR_USAGE); 454 switch (opt) { 455 case 'T': /* token specifier */ 456 if (token_spec) 457 return (PK_ERR_USAGE); 458 token_spec = optarg_av; 459 break; 460 case 'y': /* object type: public, private, both */ 461 if (oclass) 462 return (PK_ERR_USAGE); 463 oclass = OT2Int(optarg_av); 464 if (oclass == -1) 465 return (PK_ERR_USAGE); 466 break; 467 case 'l': /* objects with specific label */ 468 case 'n': 469 if (object_label) 470 return (PK_ERR_USAGE); 471 object_label = (char *)optarg_av; 472 break; 473 case 'k': 474 kstype = KS2Int(optarg_av); 475 if (kstype == 0) 476 return (PK_ERR_USAGE); 477 break; 478 case 's': 479 subject = optarg_av; 480 break; 481 case 'i': 482 issuer = optarg_av; 483 break; 484 case 'd': 485 dir = optarg_av; 486 break; 487 case 'p': 488 prefix = optarg_av; 489 break; 490 case 'S': 491 serstr = optarg_av; 492 break; 493 case 'f': 494 infile = optarg_av; 495 break; 496 case 'c': 497 find_criteria = optarg_av; 498 if (!strcasecmp(find_criteria, "valid")) 499 find_criteria_flag = 500 KMF_NONEXPIRED_CERTS; 501 else if (!strcasecmp(find_criteria, "expired")) 502 find_criteria_flag = KMF_EXPIRED_CERTS; 503 else if (!strcasecmp(find_criteria, "both")) 504 find_criteria_flag = KMF_ALL_CERTS; 505 else 506 return (PK_ERR_USAGE); 507 break; 508 default: 509 return (PK_ERR_USAGE); 510 break; 511 } 512 } 513 514 /* Assume keystore = PKCS#11 if not specified */ 515 if (kstype == 0) 516 kstype = KMF_KEYSTORE_PK11TOKEN; 517 518 /* if PUBLIC or PRIVATE obj was given, the old syntax was used. */ 519 if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) && 520 kstype != KMF_KEYSTORE_PK11TOKEN) { 521 522 (void) fprintf(stderr, gettext("The objtype parameter " 523 "is only relevant if keystore=pkcs11\n")); 524 return (PK_ERR_USAGE); 525 } 526 527 /* If no object class specified, delete everything but CRLs */ 528 if (oclass == 0) 529 oclass = PK_CERT_OBJ | PK_PUBKEY_OBJ | PK_PRIKEY_OBJ | 530 PK_SYMKEY_OBJ; 531 532 /* No additional args allowed. */ 533 argc -= optind_av; 534 argv += optind_av; 535 if (argc) 536 return (PK_ERR_USAGE); 537 /* Done parsing command line options. */ 538 539 if (kstype == KMF_KEYSTORE_PK11TOKEN && token_spec == NULL) { 540 token_spec = PK_DEFAULT_PK11TOKEN; 541 } else if (kstype == KMF_KEYSTORE_NSS && token_spec == NULL) { 542 token_spec = DEFAULT_NSS_TOKEN; 543 } 544 545 if (serstr != NULL) { 546 uchar_t *bytes = NULL; 547 size_t bytelen; 548 549 rv = KMF_HexString2Bytes((uchar_t *)serstr, &bytes, &bytelen); 550 if (rv != KMF_OK || bytes == NULL) { 551 (void) fprintf(stderr, gettext("serial number " 552 "must be specified as a hex number " 553 "(ex: 0x0102030405ffeeddee)\n")); 554 return (PK_ERR_USAGE); 555 } 556 serial.val = bytes; 557 serial.len = bytelen; 558 } 559 560 if ((kstype == KMF_KEYSTORE_PK11TOKEN || 561 kstype == KMF_KEYSTORE_NSS) && 562 (oclass & (PK_KEY_OBJ | PK_PRIVATE_OBJ))) { 563 564 (void) get_token_password(kstype, token_spec, 565 &tokencred); 566 } 567 568 if ((kmfrv = KMF_Initialize(&kmfhandle, NULL, NULL)) != KMF_OK) 569 return (kmfrv); 570 571 switch (kstype) { 572 case KMF_KEYSTORE_PK11TOKEN: 573 if (oclass & PK_KEY_OBJ) { 574 kmfrv = delete_pk11_keys(kmfhandle, 575 token_spec, oclass, 576 object_label, 577 &tokencred); 578 /* 579 * If deleting groups of objects, it is OK 580 * to ignore the "key not found" case so that 581 * we can continue to find other objects. 582 */ 583 if (kmfrv == KMF_ERR_KEY_NOT_FOUND && 584 (oclass != PK_KEY_OBJ)) 585 kmfrv = KMF_OK; 586 if (kmfrv != KMF_OK) 587 break; 588 } 589 if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) { 590 kmfrv = delete_pk11_certs(kmfhandle, 591 token_spec, 592 object_label, 593 &serial, issuer, 594 subject, find_criteria_flag); 595 /* 596 * If cert delete failed, but we are looking at 597 * other objects, then it is OK. 598 */ 599 if (kmfrv == KMF_ERR_CERT_NOT_FOUND && 600 (oclass & (PK_CRL_OBJ | PK_KEY_OBJ))) 601 kmfrv = KMF_OK; 602 if (kmfrv != KMF_OK) 603 break; 604 } 605 if (oclass & PK_CRL_OBJ) 606 kmfrv = delete_file_crl(kmfhandle, 607 dir, infile); 608 break; 609 case KMF_KEYSTORE_NSS: 610 if (oclass & PK_KEY_OBJ) { 611 kmfrv = delete_nss_keys(kmfhandle, 612 dir, prefix, token_spec, 613 oclass, (char *)object_label, 614 &tokencred); 615 if (kmfrv != KMF_OK) 616 break; 617 } 618 if (oclass & PK_CERT_OBJ) { 619 kmfrv = delete_nss_certs(kmfhandle, 620 dir, prefix, token_spec, 621 (char *)object_label, 622 &serial, issuer, subject, 623 find_criteria_flag); 624 if (kmfrv != KMF_OK) 625 break; 626 } 627 if (oclass & PK_CRL_OBJ) 628 kmfrv = delete_nss_crl(kmfhandle, 629 dir, prefix, token_spec, 630 (char *)object_label, subject); 631 break; 632 case KMF_KEYSTORE_OPENSSL: 633 if (oclass & PK_KEY_OBJ) { 634 kmfrv = delete_file_keys(kmfhandle, oclass, 635 dir, infile); 636 if (kmfrv != KMF_OK) 637 break; 638 } 639 if (oclass & (PK_CERT_OBJ)) { 640 kmfrv = delete_file_certs(kmfhandle, 641 dir, infile, &serial, issuer, 642 subject, find_criteria_flag); 643 if (kmfrv != KMF_OK) 644 break; 645 } 646 if (oclass & PK_CRL_OBJ) 647 kmfrv = delete_file_crl(kmfhandle, 648 dir, infile); 649 break; 650 default: 651 rv = PK_ERR_USAGE; 652 break; 653 } 654 655 if (kmfrv != KMF_OK) { 656 display_error(kmfhandle, kmfrv, 657 gettext("Error deleting objects")); 658 } 659 660 if (serial.val != NULL) 661 free(serial.val); 662 (void) KMF_Finalize(kmfhandle); 663 return (kmfrv); 664 } 665