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 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * This file implements the token object list operation for this tool. 30 * It loads the PKCS#11 modules, finds the object to list, lists it, 31 * and cleans up. User must be logged into the token to list private 32 * objects. 33 */ 34 35 #include <stdio.h> 36 #include <errno.h> 37 #include <string.h> 38 #include <cryptoutil.h> 39 #include <security/cryptoki.h> 40 #include "common.h" 41 42 #include <kmfapi.h> 43 44 static void 45 pk_show_certs(KMF_HANDLE_T kmfhandle, KMF_X509_DER_CERT *certs, int num_certs) 46 { 47 int i; 48 char *subject, *issuer, *serial, *id, *altname; 49 char *start, *end, *keyusage, *extkeyusage; 50 51 for (i = 0; i < num_certs; i++) { 52 subject = NULL; 53 issuer = NULL; 54 serial = NULL; 55 id = NULL; 56 altname = NULL; 57 start = end = NULL; 58 keyusage = extkeyusage = NULL; 59 60 (void) fprintf(stdout, 61 gettext("%d. (X.509 certificate)\n"), i + 1); 62 if (certs[i].kmf_private.label != NULL) 63 (void) fprintf(stdout, gettext("\t%s: %s\n"), 64 (certs[i].kmf_private.keystore_type == 65 KMF_KEYSTORE_OPENSSL ? "Filename" : "Label"), 66 certs[i].kmf_private.label); 67 if (kmf_get_cert_id_str(&certs[i].certificate, 68 &id) == KMF_OK) 69 (void) fprintf(stdout, gettext("\tID: %s\n"), id); 70 if (kmf_get_cert_subject_str(kmfhandle, 71 &certs[i].certificate, &subject) == KMF_OK) 72 (void) fprintf(stdout, gettext("\tSubject: %s\n"), 73 subject); 74 if (kmf_get_cert_issuer_str(kmfhandle, 75 &certs[i].certificate, &issuer) == KMF_OK) 76 (void) fprintf(stdout, gettext("\tIssuer: %s\n"), 77 issuer); 78 if (kmf_get_cert_start_date_str(kmfhandle, 79 &certs[i].certificate, &start) == KMF_OK) 80 (void) fprintf(stdout, gettext("\tNot Before: %s\n"), 81 start); 82 if (kmf_get_cert_end_date_str(kmfhandle, 83 &certs[i].certificate, &end) == KMF_OK) 84 (void) fprintf(stdout, gettext("\tNot After: %s\n"), 85 end); 86 if (kmf_get_cert_serial_str(kmfhandle, 87 &certs[i].certificate, &serial) == KMF_OK) 88 (void) fprintf(stdout, gettext("\tSerial: %s\n"), 89 serial); 90 if (kmf_get_cert_extn_str(kmfhandle, 91 &certs[i].certificate, KMF_X509_EXT_SUBJ_ALTNAME, 92 &altname) == KMF_OK) { 93 (void) fprintf(stdout, gettext("\t%s\n"), 94 altname); 95 } 96 if (kmf_get_cert_extn_str(kmfhandle, 97 &certs[i].certificate, KMF_X509_EXT_KEY_USAGE, 98 &keyusage) == KMF_OK) { 99 (void) fprintf(stdout, gettext("\t%s\n"), 100 keyusage); 101 } 102 if (kmf_get_cert_extn_str(kmfhandle, 103 &certs[i].certificate, KMF_X509_EXT_EXT_KEY_USAGE, 104 &extkeyusage) == KMF_OK) { 105 (void) fprintf(stdout, gettext("\t%s\n"), 106 extkeyusage); 107 } 108 kmf_free_str(subject); 109 kmf_free_str(issuer); 110 kmf_free_str(serial); 111 kmf_free_str(id); 112 kmf_free_str(altname); 113 kmf_free_str(keyusage); 114 kmf_free_str(extkeyusage); 115 kmf_free_str(start); 116 kmf_free_str(end); 117 (void) fprintf(stdout, "\n"); 118 } 119 } 120 121 static char * 122 describeKey(KMF_KEY_HANDLE *key) 123 { 124 if (key->keyclass == KMF_ASYM_PUB) { 125 if (key->keyalg == KMF_RSA) 126 return (gettext("RSA public key")); 127 if (key->keyalg == KMF_DSA) 128 return (gettext("DSA public key")); 129 } 130 if (key->keyclass == KMF_ASYM_PRI) { 131 if (key->keyalg == KMF_RSA) 132 return ("RSA private key"); 133 if (key->keyalg == KMF_DSA) 134 return ("DSA private key"); 135 } 136 if (key->keyclass == KMF_SYMMETRIC) { 137 switch (key->keyalg) { 138 case KMF_AES: 139 return (gettext("AES")); 140 break; 141 case KMF_RC4: 142 return (gettext("ARCFOUR")); 143 break; 144 case KMF_DES: 145 return (gettext("DES")); 146 break; 147 case KMF_DES3: 148 return (gettext("Triple-DES")); 149 break; 150 default: 151 return (gettext("symmetric")); 152 break; 153 } 154 } 155 156 return (gettext("unrecognized key object")); 157 158 } 159 160 161 static void 162 pk_show_keys(void *handle, KMF_KEY_HANDLE *keys, int numkeys) 163 { 164 int i; 165 166 for (i = 0; i < numkeys; i++) { 167 (void) fprintf(stdout, gettext("Key #%d - %s: %s"), 168 i+1, describeKey(&keys[i]), 169 keys[i].keylabel ? keys[i].keylabel : 170 gettext("No label")); 171 172 if (keys[i].keyclass == KMF_SYMMETRIC) { 173 KMF_RETURN rv; 174 KMF_RAW_SYM_KEY rkey; 175 176 (void) memset(&rkey, 0, sizeof (rkey)); 177 rv = kmf_get_sym_key_value(handle, &keys[i], 178 &rkey); 179 if (rv == KMF_OK) { 180 (void) fprintf(stdout, " (%d bits)", 181 rkey.keydata.len * 8); 182 kmf_free_bigint(&rkey.keydata); 183 } else if (keys[i].kstype == KMF_KEYSTORE_PK11TOKEN) { 184 if (rv == KMF_ERR_SENSITIVE_KEY) { 185 (void) fprintf(stdout, " (sensitive)"); 186 } else if (rv == KMF_ERR_UNEXTRACTABLE_KEY) { 187 (void) fprintf(stdout, 188 " (non-extractable)"); 189 } else { 190 char *err = NULL; 191 if (kmf_get_kmf_error_str(rv, &err) == 192 KMF_OK) 193 (void) fprintf(stdout, 194 " (error: %s)", err); 195 if (err != NULL) 196 free(err); 197 } 198 } 199 } 200 (void) fprintf(stdout, "\n"); 201 } 202 } 203 204 /* 205 * Generic routine used by all "list cert" operations to find 206 * all matching certificates. 207 */ 208 static KMF_RETURN 209 pk_find_certs(KMF_HANDLE_T kmfhandle, KMF_ATTRIBUTE *attrlist, int numattr) 210 { 211 KMF_RETURN rv = KMF_OK; 212 KMF_X509_DER_CERT *certlist = NULL; 213 uint32_t numcerts = 0; 214 KMF_KEYSTORE_TYPE kstype; 215 216 rv = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr, 217 &kstype, NULL); 218 if (rv != KMF_OK) 219 return (rv); 220 221 kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, 222 &numcerts, sizeof (uint32_t)); 223 numattr++; 224 225 rv = kmf_find_cert(kmfhandle, numattr, attrlist); 226 if (rv == KMF_OK && numcerts > 0) { 227 (void) printf(gettext("Found %d certificates.\n"), 228 numcerts); 229 certlist = (KMF_X509_DER_CERT *)malloc(numcerts * 230 sizeof (KMF_X509_DER_CERT)); 231 if (certlist == NULL) 232 return (KMF_ERR_MEMORY); 233 (void) memset(certlist, 0, numcerts * 234 sizeof (KMF_X509_DER_CERT)); 235 236 kmf_set_attr_at_index(attrlist, numattr, 237 KMF_X509_DER_CERT_ATTR, certlist, 238 sizeof (KMF_X509_DER_CERT)); 239 numattr++; 240 241 rv = kmf_find_cert(kmfhandle, numattr, attrlist); 242 if (rv == KMF_OK) { 243 int i; 244 (void) pk_show_certs(kmfhandle, certlist, 245 numcerts); 246 for (i = 0; i < numcerts; i++) 247 kmf_free_kmf_cert(kmfhandle, &certlist[i]); 248 } 249 free(certlist); 250 } 251 if (rv == KMF_ERR_CERT_NOT_FOUND && 252 kstype != KMF_KEYSTORE_OPENSSL) 253 rv = KMF_OK; 254 255 return (rv); 256 } 257 258 static KMF_RETURN 259 pk_list_keys(void *handle, KMF_ATTRIBUTE *attrlist, int numattr, char *label) 260 { 261 KMF_RETURN rv; 262 KMF_KEY_HANDLE *keys; 263 uint32_t numkeys = 0; 264 KMF_KEYSTORE_TYPE kstype; 265 266 rv = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr, 267 &kstype, NULL); 268 if (rv != KMF_OK) 269 return (rv); 270 271 kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, 272 &numkeys, sizeof (uint32_t)); 273 numattr++; 274 275 rv = kmf_find_key(handle, numattr, attrlist); 276 if (rv == KMF_OK && numkeys > 0) { 277 int i; 278 (void) printf(gettext("Found %d %s keys.\n"), 279 numkeys, label); 280 keys = (KMF_KEY_HANDLE *)malloc(numkeys * 281 sizeof (KMF_KEY_HANDLE)); 282 if (keys == NULL) 283 return (KMF_ERR_MEMORY); 284 (void) memset(keys, 0, numkeys * 285 sizeof (KMF_KEY_HANDLE)); 286 287 kmf_set_attr_at_index(attrlist, numattr, 288 KMF_KEY_HANDLE_ATTR, 289 keys, sizeof (KMF_KEY_HANDLE)); 290 numattr++; 291 292 rv = kmf_find_key(handle, numattr, attrlist); 293 if (rv == KMF_OK) 294 pk_show_keys(handle, keys, numkeys); 295 for (i = 0; i < numkeys; i++) 296 kmf_free_kmf_key(handle, &keys[i]); 297 free(keys); 298 } 299 if (rv == KMF_ERR_KEY_NOT_FOUND && 300 kstype != KMF_KEYSTORE_OPENSSL) 301 rv = KMF_OK; 302 return (rv); 303 } 304 305 static KMF_RETURN 306 list_pk11_objects(KMF_HANDLE_T kmfhandle, char *token, int oclass, 307 char *objlabel, KMF_BIGINT *serial, char *issuer, char *subject, 308 char *dir, char *filename, KMF_CREDENTIAL *tokencred, 309 KMF_CERT_VALIDITY find_criteria_flag) 310 { 311 KMF_RETURN rv; 312 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 313 int numattr = 0; 314 KMF_ATTRIBUTE attrlist[18]; 315 boolean_t token_bool = B_TRUE; 316 boolean_t private = B_FALSE; 317 KMF_KEY_CLASS keyclass; 318 KMF_ENCODE_FORMAT format; 319 int auth = 0; 320 KMF_CREDENTIAL cred = {NULL, 0}; 321 322 /* 323 * Symmetric keys and RSA/DSA private keys are always 324 * created with the "CKA_PRIVATE" field == TRUE, so 325 * make sure we search for them with it also set. 326 */ 327 if (oclass & (PK_SYMKEY_OBJ | PK_PRIKEY_OBJ)) 328 oclass |= PK_PRIVATE_OBJ; 329 330 rv = select_token(kmfhandle, token, 331 !(oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ))); 332 333 if (rv != KMF_OK) { 334 return (rv); 335 } 336 337 rv = token_auth_needed(kmfhandle, token, &auth); 338 if (rv != KMF_OK) 339 return (rv); 340 341 if (tokencred != NULL) 342 cred = *tokencred; 343 344 if (oclass & (PK_KEY_OBJ | PK_PRIVATE_OBJ)) { 345 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 346 &kstype, sizeof (kstype)); 347 numattr++; 348 349 if (objlabel != NULL) { 350 kmf_set_attr_at_index(attrlist, numattr, 351 KMF_KEYLABEL_ATTR, objlabel, 352 strlen(objlabel)); 353 numattr++; 354 } 355 356 private = ((oclass & PK_PRIVATE_OBJ) > 0); 357 358 kmf_set_attr_at_index(attrlist, numattr, 359 KMF_PRIVATE_BOOL_ATTR, &private, 360 sizeof (private)); 361 numattr++; 362 363 kmf_set_attr_at_index(attrlist, numattr, 364 KMF_TOKEN_BOOL_ATTR, &token_bool, 365 sizeof (token_bool)); 366 numattr++; 367 368 if (oclass & PK_PRIKEY_OBJ) { 369 int num = numattr; 370 371 keyclass = KMF_ASYM_PRI; 372 kmf_set_attr_at_index(attrlist, num, 373 KMF_KEYCLASS_ATTR, &keyclass, 374 sizeof (keyclass)); 375 num++; 376 377 if (tokencred != NULL && 378 tokencred->credlen > 0) { 379 kmf_set_attr_at_index(attrlist, num, 380 KMF_CREDENTIAL_ATTR, tokencred, 381 sizeof (KMF_CREDENTIAL)); 382 num++; 383 } 384 385 /* list asymmetric private keys */ 386 rv = pk_list_keys(kmfhandle, attrlist, num, 387 "asymmetric private"); 388 } 389 390 if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) { 391 int num = numattr; 392 393 keyclass = KMF_SYMMETRIC; 394 kmf_set_attr_at_index(attrlist, num, 395 KMF_KEYCLASS_ATTR, &keyclass, 396 sizeof (keyclass)); 397 num++; 398 399 if (tokencred != NULL && 400 tokencred->credlen > 0) { 401 kmf_set_attr_at_index(attrlist, num, 402 KMF_CREDENTIAL_ATTR, tokencred, 403 sizeof (KMF_CREDENTIAL)); 404 num++; 405 } 406 407 format = KMF_FORMAT_RAWKEY; 408 kmf_set_attr_at_index(attrlist, num, 409 KMF_ENCODE_FORMAT_ATTR, &format, 410 sizeof (format)); 411 num++; 412 413 /* list symmetric keys */ 414 rv = pk_list_keys(kmfhandle, attrlist, num, 415 "symmetric"); 416 } 417 418 if (rv == KMF_OK && (oclass & PK_PUBKEY_OBJ)) { 419 int num = numattr; 420 421 if (auth > 0 && (tokencred == NULL || 422 tokencred->cred == NULL) && 423 (cred.cred == NULL)) { 424 (void) get_token_password(kstype, token, &cred); 425 kmf_set_attr_at_index(attrlist, numattr, 426 KMF_CREDENTIAL_ATTR, 427 &cred, sizeof (KMF_CREDENTIAL)); 428 numattr++; 429 } 430 431 private = B_FALSE; 432 keyclass = KMF_ASYM_PUB; 433 kmf_set_attr_at_index(attrlist, num, 434 KMF_KEYCLASS_ATTR, &keyclass, 435 sizeof (keyclass)); 436 num++; 437 438 /* list asymmetric public keys (if any) */ 439 rv = pk_list_keys(kmfhandle, attrlist, num, 440 "asymmetric public"); 441 } 442 443 if (rv != KMF_OK) 444 return (rv); 445 } 446 447 numattr = 0; 448 if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) { 449 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 450 &kstype, sizeof (kstype)); 451 452 numattr++; 453 if (auth > 0 && (cred.cred == NULL)) { 454 (void) get_token_password(kstype, token, &cred); 455 } 456 457 if (cred.cred != NULL) { 458 kmf_set_attr_at_index(attrlist, numattr, 459 KMF_CREDENTIAL_ATTR, 460 &cred, sizeof (KMF_CREDENTIAL)); 461 numattr++; 462 } 463 464 if (objlabel != NULL) { 465 kmf_set_attr_at_index(attrlist, numattr, 466 KMF_CERT_LABEL_ATTR, objlabel, 467 strlen(objlabel)); 468 numattr++; 469 } 470 471 if (issuer != NULL) { 472 kmf_set_attr_at_index(attrlist, numattr, 473 KMF_ISSUER_NAME_ATTR, issuer, 474 strlen(issuer)); 475 numattr++; 476 } 477 478 if (subject != NULL) { 479 kmf_set_attr_at_index(attrlist, numattr, 480 KMF_SUBJECT_NAME_ATTR, subject, 481 strlen(subject)); 482 numattr++; 483 } 484 485 if (serial != NULL && serial->val != NULL) { 486 kmf_set_attr_at_index(attrlist, numattr, 487 KMF_BIGINT_ATTR, serial, 488 sizeof (KMF_BIGINT)); 489 numattr++; 490 } 491 492 kmf_set_attr_at_index(attrlist, numattr, 493 KMF_PRIVATE_BOOL_ATTR, &private, 494 sizeof (private)); 495 numattr++; 496 497 kmf_set_attr_at_index(attrlist, numattr, 498 KMF_CERT_VALIDITY_ATTR, &find_criteria_flag, 499 sizeof (KMF_CERT_VALIDITY)); 500 numattr++; 501 502 rv = pk_find_certs(kmfhandle, attrlist, numattr); 503 if (rv != KMF_OK) 504 return (rv); 505 } 506 507 numattr = 0; 508 kstype = KMF_KEYSTORE_OPENSSL; /* CRL is file-based */ 509 if (oclass & PK_CRL_OBJ) { 510 char *crldata = NULL; 511 512 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 513 &kstype, sizeof (kstype)); 514 numattr++; 515 516 if (dir != NULL) { 517 kmf_set_attr_at_index(attrlist, numattr, 518 KMF_DIRPATH_ATTR, dir, strlen(dir)); 519 numattr++; 520 } 521 if (filename != NULL) { 522 kmf_set_attr_at_index(attrlist, numattr, 523 KMF_CRL_FILENAME_ATTR, 524 filename, strlen(filename)); 525 numattr++; 526 } 527 kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_DATA_ATTR, 528 &crldata, sizeof (char *)); 529 numattr++; 530 531 rv = kmf_list_crl(kmfhandle, numattr, attrlist); 532 if (rv == KMF_OK && crldata != NULL) { 533 (void) printf("%s\n", crldata); 534 free(crldata); 535 } 536 } 537 538 return (rv); 539 } 540 541 static int 542 list_file_objects(KMF_HANDLE_T kmfhandle, int oclass, 543 char *dir, char *filename, KMF_BIGINT *serial, 544 char *issuer, char *subject, 545 KMF_CERT_VALIDITY find_criteria_flag) 546 { 547 KMF_RETURN rv = KMF_OK; 548 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 549 int numattr = 0; 550 KMF_ATTRIBUTE attrlist[16]; 551 KMF_KEY_CLASS keyclass; 552 KMF_ENCODE_FORMAT format; 553 char *defaultdir = "."; 554 555 if (oclass & PK_KEY_OBJ) { 556 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 557 &kstype, sizeof (kstype)); 558 numattr++; 559 560 if (dir == NULL && filename == NULL) 561 dir = defaultdir; 562 563 if (dir != NULL) { 564 kmf_set_attr_at_index(attrlist, numattr, 565 KMF_DIRPATH_ATTR, dir, 566 strlen(dir)); 567 numattr++; 568 } 569 570 if (filename != NULL) { 571 kmf_set_attr_at_index(attrlist, numattr, 572 KMF_KEY_FILENAME_ATTR, filename, 573 strlen(filename)); 574 numattr++; 575 } 576 577 if (oclass & PK_PRIKEY_OBJ) { 578 int num = numattr; 579 580 keyclass = KMF_ASYM_PRI; 581 kmf_set_attr_at_index(attrlist, num, 582 KMF_KEYCLASS_ATTR, &keyclass, 583 sizeof (keyclass)); 584 num++; 585 586 /* list asymmetric private keys */ 587 rv = pk_list_keys(kmfhandle, attrlist, num, 588 "asymmetric private"); 589 } 590 if (rv == KMF_ERR_KEY_NOT_FOUND) 591 rv = KMF_OK; 592 593 if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) { 594 int num = numattr; 595 596 keyclass = KMF_SYMMETRIC; 597 kmf_set_attr_at_index(attrlist, num, 598 KMF_KEYCLASS_ATTR, &keyclass, 599 sizeof (keyclass)); 600 num++; 601 602 format = KMF_FORMAT_RAWKEY; 603 kmf_set_attr_at_index(attrlist, num, 604 KMF_ENCODE_FORMAT_ATTR, &format, 605 sizeof (format)); 606 num++; 607 608 /* list symmetric keys */ 609 rv = pk_list_keys(kmfhandle, attrlist, num, 610 "symmetric"); 611 } 612 if (rv == KMF_ERR_KEY_NOT_FOUND) 613 rv = KMF_OK; 614 if (rv != KMF_OK) 615 return (rv); 616 } 617 618 numattr = 0; 619 if (oclass & PK_CERT_OBJ) { 620 kmf_set_attr_at_index(attrlist, numattr, 621 KMF_KEYSTORE_TYPE_ATTR, &kstype, 622 sizeof (kstype)); 623 numattr++; 624 625 if (issuer != NULL) { 626 kmf_set_attr_at_index(attrlist, numattr, 627 KMF_ISSUER_NAME_ATTR, issuer, 628 strlen(issuer)); 629 numattr++; 630 } 631 632 if (subject != NULL) { 633 kmf_set_attr_at_index(attrlist, numattr, 634 KMF_SUBJECT_NAME_ATTR, subject, 635 strlen(subject)); 636 numattr++; 637 } 638 639 if (serial != NULL && serial->val != NULL) { 640 kmf_set_attr_at_index(attrlist, numattr, 641 KMF_BIGINT_ATTR, serial, 642 sizeof (KMF_BIGINT)); 643 numattr++; 644 } 645 646 if (filename != NULL) { 647 kmf_set_attr_at_index(attrlist, numattr, 648 KMF_CERT_FILENAME_ATTR, filename, 649 strlen(filename)); 650 numattr++; 651 } 652 653 if (dir != NULL) { 654 kmf_set_attr_at_index(attrlist, numattr, 655 KMF_DIRPATH_ATTR, dir, 656 strlen(dir)); 657 numattr++; 658 } 659 660 kmf_set_attr_at_index(attrlist, numattr, 661 KMF_CERT_VALIDITY_ATTR, &find_criteria_flag, 662 sizeof (KMF_CERT_VALIDITY)); 663 numattr++; 664 665 rv = pk_find_certs(kmfhandle, attrlist, numattr); 666 if (rv != KMF_OK) 667 return (rv); 668 } 669 670 numattr = 0; 671 if (oclass & PK_CRL_OBJ) { 672 char *crldata = NULL; 673 674 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 675 &kstype, sizeof (kstype)); 676 numattr++; 677 678 if (dir != NULL) { 679 kmf_set_attr_at_index(attrlist, numattr, 680 KMF_DIRPATH_ATTR, dir, strlen(dir)); 681 numattr++; 682 } 683 if (filename != NULL) { 684 kmf_set_attr_at_index(attrlist, numattr, 685 KMF_CRL_FILENAME_ATTR, 686 filename, strlen(filename)); 687 numattr++; 688 } 689 kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_DATA_ATTR, 690 &crldata, sizeof (char *)); 691 numattr++; 692 693 rv = kmf_list_crl(kmfhandle, numattr, attrlist); 694 if (rv == KMF_OK && crldata != NULL) { 695 (void) printf("%s\n", crldata); 696 free(crldata); 697 } 698 } 699 700 return (rv); 701 } 702 703 static int 704 list_nss_objects(KMF_HANDLE_T kmfhandle, 705 int oclass, char *token_spec, char *dir, char *prefix, 706 char *nickname, KMF_BIGINT *serial, char *issuer, char *subject, 707 KMF_CREDENTIAL *tokencred, 708 KMF_CERT_VALIDITY find_criteria_flag) 709 { 710 KMF_RETURN rv = KMF_OK; 711 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; 712 int numattr = 0; 713 KMF_ATTRIBUTE attrlist[16]; 714 KMF_KEY_CLASS keyclass; 715 KMF_ENCODE_FORMAT format; 716 717 rv = configure_nss(kmfhandle, dir, prefix); 718 if (rv != KMF_OK) 719 return (rv); 720 721 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 722 &kstype, sizeof (kstype)); 723 numattr++; 724 725 if (oclass & PK_KEY_OBJ) { 726 if (tokencred != NULL && tokencred->credlen > 0) { 727 kmf_set_attr_at_index(attrlist, numattr, 728 KMF_CREDENTIAL_ATTR, tokencred, 729 sizeof (KMF_CREDENTIAL)); 730 numattr++; 731 } 732 733 if (token_spec && strlen(token_spec)) { 734 kmf_set_attr_at_index(attrlist, numattr, 735 KMF_TOKEN_LABEL_ATTR, token_spec, 736 strlen(token_spec)); 737 numattr++; 738 } 739 740 if (nickname != NULL) { 741 kmf_set_attr_at_index(attrlist, numattr, 742 KMF_KEYLABEL_ATTR, nickname, 743 strlen(nickname)); 744 numattr++; 745 } 746 } 747 748 if (oclass & PK_PRIKEY_OBJ) { 749 int num = numattr; 750 751 keyclass = KMF_ASYM_PRI; 752 kmf_set_attr_at_index(attrlist, num, 753 KMF_KEYCLASS_ATTR, &keyclass, 754 sizeof (keyclass)); 755 num++; 756 757 /* list asymmetric private keys */ 758 rv = pk_list_keys(kmfhandle, attrlist, num, 759 "asymmetric private"); 760 } 761 762 if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) { 763 int num = numattr; 764 765 keyclass = KMF_SYMMETRIC; 766 kmf_set_attr_at_index(attrlist, num, 767 KMF_KEYCLASS_ATTR, &keyclass, 768 sizeof (keyclass)); 769 num++; 770 771 format = KMF_FORMAT_RAWKEY; 772 kmf_set_attr_at_index(attrlist, num, 773 KMF_ENCODE_FORMAT_ATTR, &format, 774 sizeof (format)); 775 num++; 776 777 /* list symmetric keys */ 778 rv = pk_list_keys(kmfhandle, attrlist, num, "symmetric"); 779 } 780 781 if (rv == KMF_OK && (oclass & PK_PUBKEY_OBJ)) { 782 int num = numattr; 783 784 keyclass = KMF_ASYM_PUB; 785 kmf_set_attr_at_index(attrlist, num, 786 KMF_KEYCLASS_ATTR, &keyclass, 787 sizeof (keyclass)); 788 num++; 789 790 /* list asymmetric public keys */ 791 rv = pk_list_keys(kmfhandle, attrlist, num, 792 "asymmetric public"); 793 } 794 795 /* If searching for public objects or certificates, find certs now */ 796 numattr = 0; 797 if (rv == KMF_OK && (oclass & PK_CERT_OBJ)) { 798 kmf_set_attr_at_index(attrlist, numattr, 799 KMF_KEYSTORE_TYPE_ATTR, &kstype, 800 sizeof (kstype)); 801 numattr++; 802 803 if (nickname != NULL) { 804 kmf_set_attr_at_index(attrlist, numattr, 805 KMF_CERT_LABEL_ATTR, nickname, 806 strlen(nickname)); 807 numattr++; 808 } 809 810 if (issuer != NULL) { 811 kmf_set_attr_at_index(attrlist, numattr, 812 KMF_ISSUER_NAME_ATTR, issuer, 813 strlen(issuer)); 814 numattr++; 815 } 816 817 if (subject != NULL) { 818 kmf_set_attr_at_index(attrlist, numattr, 819 KMF_SUBJECT_NAME_ATTR, subject, 820 strlen(subject)); 821 numattr++; 822 } 823 824 if (serial != NULL) { 825 kmf_set_attr_at_index(attrlist, numattr, 826 KMF_BIGINT_ATTR, serial, 827 sizeof (KMF_BIGINT)); 828 numattr++; 829 } 830 831 if (token_spec != NULL) { 832 kmf_set_attr_at_index(attrlist, numattr, 833 KMF_TOKEN_LABEL_ATTR, token_spec, 834 strlen(token_spec)); 835 numattr++; 836 } 837 838 kmf_set_attr_at_index(attrlist, numattr, 839 KMF_CERT_VALIDITY_ATTR, &find_criteria_flag, 840 sizeof (KMF_CERT_VALIDITY)); 841 numattr++; 842 843 rv = pk_find_certs(kmfhandle, attrlist, numattr); 844 } 845 846 numattr = 0; 847 if (rv == KMF_OK && (oclass & PK_CRL_OBJ)) { 848 int numcrls; 849 850 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 851 &kstype, sizeof (kstype)); 852 numattr++; 853 854 if (token_spec != NULL) { 855 kmf_set_attr_at_index(attrlist, numattr, 856 KMF_TOKEN_LABEL_ATTR, 857 token_spec, strlen(token_spec)); 858 numattr++; 859 } 860 kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_COUNT_ATTR, 861 &numcrls, sizeof (int)); 862 numattr++; 863 864 rv = kmf_find_crl(kmfhandle, numattr, attrlist); 865 if (rv == KMF_OK) { 866 char **p; 867 if (numcrls == 0) { 868 (void) printf(gettext("No CRLs found in " 869 "NSS keystore.\n")); 870 871 return (KMF_OK); 872 } 873 p = malloc(numcrls * sizeof (char *)); 874 if (p == NULL) { 875 return (KMF_ERR_MEMORY); 876 } 877 (void) memset(p, 0, numcrls * sizeof (char *)); 878 879 kmf_set_attr_at_index(attrlist, numattr, 880 KMF_CRL_NAMELIST_ATTR, p, sizeof (char *)); 881 numattr++; 882 rv = kmf_find_crl(kmfhandle, numattr, attrlist); 883 if (rv == KMF_OK) { 884 int i; 885 for (i = 0; i < numcrls; i++) { 886 (void) printf("%d. Name = %s\n", 887 i + 1, p[i]); 888 free(p[i]); 889 } 890 } 891 free(p); 892 } 893 } 894 return (rv); 895 } 896 897 /* 898 * List token object. 899 */ 900 int 901 pk_list(int argc, char *argv[]) 902 { 903 int opt; 904 extern int optind_av; 905 extern char *optarg_av; 906 char *token_spec = NULL; 907 char *subject = NULL; 908 char *issuer = NULL; 909 char *dir = NULL; 910 char *prefix = NULL; 911 char *filename = NULL; 912 char *serstr = NULL; 913 KMF_BIGINT serial = { NULL, 0 }; 914 915 char *list_label = NULL; 916 int oclass = 0; 917 KMF_KEYSTORE_TYPE kstype = 0; 918 KMF_RETURN rv = KMF_OK; 919 KMF_HANDLE_T kmfhandle = NULL; 920 char *find_criteria = NULL; 921 KMF_CERT_VALIDITY find_criteria_flag = KMF_ALL_CERTS; 922 KMF_CREDENTIAL tokencred = {NULL, 0}; 923 924 /* Parse command line options. Do NOT i18n/l10n. */ 925 while ((opt = getopt_av(argc, argv, 926 "k:(keystore)t:(objtype)T:(token)d:(dir)" 927 "p:(prefix)n:(nickname)S:(serial)s:(subject)" 928 "c:(criteria)" 929 "i:(issuer)l:(label)f:(infile)")) != EOF) { 930 if (EMPTYSTRING(optarg_av)) 931 return (PK_ERR_USAGE); 932 switch (opt) { 933 case 'k': 934 if (kstype != 0) 935 return (PK_ERR_USAGE); 936 kstype = KS2Int(optarg_av); 937 if (kstype == 0) 938 return (PK_ERR_USAGE); 939 break; 940 case 't': 941 if (oclass != 0) 942 return (PK_ERR_USAGE); 943 oclass = OT2Int(optarg_av); 944 if (oclass == -1) 945 return (PK_ERR_USAGE); 946 break; 947 case 's': 948 if (subject) 949 return (PK_ERR_USAGE); 950 subject = optarg_av; 951 break; 952 case 'i': 953 if (issuer) 954 return (PK_ERR_USAGE); 955 issuer = optarg_av; 956 break; 957 case 'd': 958 if (dir) 959 return (PK_ERR_USAGE); 960 dir = optarg_av; 961 break; 962 case 'p': 963 if (prefix) 964 return (PK_ERR_USAGE); 965 prefix = optarg_av; 966 break; 967 case 'S': 968 serstr = optarg_av; 969 break; 970 case 'f': 971 if (filename) 972 return (PK_ERR_USAGE); 973 filename = optarg_av; 974 break; 975 case 'T': /* token specifier */ 976 if (token_spec) 977 return (PK_ERR_USAGE); 978 token_spec = optarg_av; 979 break; 980 case 'n': 981 case 'l': /* object with specific label */ 982 if (list_label) 983 return (PK_ERR_USAGE); 984 list_label = optarg_av; 985 break; 986 case 'c': 987 find_criteria = optarg_av; 988 if (!strcasecmp(find_criteria, "valid")) 989 find_criteria_flag = 990 KMF_NONEXPIRED_CERTS; 991 else if (!strcasecmp(find_criteria, "expired")) 992 find_criteria_flag = KMF_EXPIRED_CERTS; 993 else if (!strcasecmp(find_criteria, "both")) 994 find_criteria_flag = KMF_ALL_CERTS; 995 else 996 return (PK_ERR_USAGE); 997 break; 998 default: 999 return (PK_ERR_USAGE); 1000 } 1001 } 1002 /* No additional args allowed. */ 1003 argc -= optind_av; 1004 argv += optind_av; 1005 if (argc) 1006 return (PK_ERR_USAGE); 1007 1008 if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 1009 /* Error message ? */ 1010 return (rv); 1011 } 1012 1013 /* Assume keystore = PKCS#11 if not specified. */ 1014 if (kstype == 0) 1015 kstype = KMF_KEYSTORE_PK11TOKEN; 1016 1017 /* if PUBLIC or PRIVATE obj was given, the old syntax was used. */ 1018 if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) && 1019 kstype != KMF_KEYSTORE_PK11TOKEN) { 1020 1021 (void) fprintf(stderr, gettext("The objtype parameter " 1022 "is only relevant if keystore=pkcs11\n")); 1023 return (PK_ERR_USAGE); 1024 } 1025 1026 1027 if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) { 1028 token_spec = PK_DEFAULT_PK11TOKEN; 1029 } else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) { 1030 token_spec = DEFAULT_NSS_TOKEN; 1031 } 1032 1033 if (serstr != NULL) { 1034 uchar_t *bytes = NULL; 1035 size_t bytelen; 1036 1037 rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen); 1038 if (rv != KMF_OK || bytes == NULL) { 1039 (void) fprintf(stderr, gettext("serial number " 1040 "must be specified as a hex number " 1041 "(ex: 0x0102030405ffeeddee)\n")); 1042 return (PK_ERR_USAGE); 1043 } 1044 serial.val = bytes; 1045 serial.len = bytelen; 1046 /* if objtype was not given, it must be for certs */ 1047 if (oclass == 0) 1048 oclass = PK_CERT_OBJ; 1049 } 1050 if (oclass == 0 && (issuer != NULL || subject != NULL)) 1051 oclass = PK_CERT_OBJ; 1052 1053 /* If no object class specified, list public objects. */ 1054 if (oclass == 0) 1055 oclass = PK_CERT_OBJ | PK_PUBKEY_OBJ; 1056 1057 if ((kstype == KMF_KEYSTORE_PK11TOKEN || 1058 kstype == KMF_KEYSTORE_NSS) && 1059 (oclass & (PK_PRIKEY_OBJ | PK_PRIVATE_OBJ))) { 1060 1061 (void) get_token_password(kstype, token_spec, 1062 &tokencred); 1063 } 1064 if (kstype == KMF_KEYSTORE_PK11TOKEN) { 1065 rv = list_pk11_objects(kmfhandle, token_spec, 1066 oclass, list_label, &serial, 1067 issuer, subject, dir, filename, 1068 &tokencred, find_criteria_flag); 1069 1070 } else if (kstype == KMF_KEYSTORE_NSS) { 1071 if (dir == NULL) 1072 dir = PK_DEFAULT_DIRECTORY; 1073 rv = list_nss_objects(kmfhandle, 1074 oclass, token_spec, dir, prefix, 1075 list_label, &serial, issuer, subject, 1076 &tokencred, find_criteria_flag); 1077 1078 } else if (kstype == KMF_KEYSTORE_OPENSSL) { 1079 1080 rv = list_file_objects(kmfhandle, 1081 oclass, dir, filename, 1082 &serial, issuer, subject, find_criteria_flag); 1083 } 1084 1085 if (rv != KMF_OK) { 1086 display_error(kmfhandle, rv, 1087 gettext("Error listing objects")); 1088 } 1089 1090 if (serial.val != NULL) 1091 free(serial.val); 1092 1093 if (tokencred.cred != NULL) 1094 free(tokencred.cred); 1095 1096 (void) kmf_finalize(kmfhandle); 1097 return (rv); 1098 } 1099