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