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 2007 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 export operation for this tool. 30 * The basic flow of the process is to find the soft token, 31 * log into it, find the PKCS#11 objects in the soft token 32 * to be exported matching keys with their certificates, export 33 * them to the PKCS#12 file encrypting them with a file password 34 * if desired, and log out. 35 */ 36 37 #include <stdio.h> 38 #include <stdlib.h> 39 #include <string.h> 40 #include <errno.h> 41 #include <fcntl.h> 42 #include "common.h" 43 44 #include <kmfapi.h> 45 46 static KMF_RETURN 47 pk_find_export_cert(KMF_HANDLE_T kmfhandle, KMF_ATTRIBUTE *attrlist, 48 int numattr, KMF_X509_DER_CERT *cert) 49 { 50 KMF_RETURN rv = KMF_OK; 51 uint32_t numcerts = 0; 52 53 numcerts = 0; 54 (void) memset(cert, 0, sizeof (KMF_X509_DER_CERT)); 55 56 kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, 57 &numcerts, sizeof (uint32_t)); 58 numattr++; 59 60 rv = kmf_find_cert(kmfhandle, numattr, attrlist); 61 if (rv != KMF_OK) { 62 return (rv); 63 } 64 if (numcerts == 0) { 65 cryptoerror(LOG_STDERR, 66 gettext("No matching certificates found.")); 67 return (KMF_ERR_CERT_NOT_FOUND); 68 69 } else if (numcerts == 1) { 70 kmf_set_attr_at_index(attrlist, numattr, 71 KMF_X509_DER_CERT_ATTR, cert, 72 sizeof (KMF_X509_DER_CERT)); 73 numattr++; 74 rv = kmf_find_cert(kmfhandle, numattr, attrlist); 75 76 } else if (numcerts > 1) { 77 cryptoerror(LOG_STDERR, 78 gettext("%d certificates found, refine the " 79 "search parameters to eliminate ambiguity\n"), 80 numcerts); 81 return (KMF_ERR_BAD_PARAMETER); 82 } 83 return (rv); 84 } 85 86 static KMF_RETURN 87 pk_export_file_objects(KMF_HANDLE_T kmfhandle, int oclass, 88 char *issuer, char *subject, KMF_BIGINT *serial, 89 char *dir, char *infile, char *filename) 90 { 91 KMF_RETURN rv = KMF_OK; 92 KMF_X509_DER_CERT kmfcert; 93 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 94 int numattr = 0; 95 KMF_ATTRIBUTE attrlist[16]; 96 97 /* If searching for public objects or certificates, find certs now */ 98 if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) { 99 kmf_set_attr_at_index(attrlist, numattr, 100 KMF_KEYSTORE_TYPE_ATTR, &kstype, 101 sizeof (kstype)); 102 numattr++; 103 104 if (issuer != NULL) { 105 kmf_set_attr_at_index(attrlist, numattr, 106 KMF_ISSUER_NAME_ATTR, issuer, 107 strlen(issuer)); 108 numattr++; 109 } 110 111 if (subject != NULL) { 112 kmf_set_attr_at_index(attrlist, numattr, 113 KMF_SUBJECT_NAME_ATTR, subject, 114 strlen(subject)); 115 numattr++; 116 } 117 118 if (serial != NULL) { 119 kmf_set_attr_at_index(attrlist, numattr, 120 KMF_BIGINT_ATTR, serial, 121 sizeof (KMF_BIGINT)); 122 numattr++; 123 } 124 125 if (dir != NULL) { 126 kmf_set_attr_at_index(attrlist, numattr, 127 KMF_DIRPATH_ATTR, dir, 128 strlen(dir)); 129 numattr++; 130 } 131 132 if (infile != NULL) { 133 kmf_set_attr_at_index(attrlist, numattr, 134 KMF_CERT_FILENAME_ATTR, infile, 135 strlen(infile)); 136 numattr++; 137 } 138 139 rv = pk_find_export_cert(kmfhandle, attrlist, numattr, 140 &kmfcert); 141 if (rv == KMF_OK) { 142 kstype = KMF_KEYSTORE_OPENSSL; 143 numattr = 0; 144 145 kmf_set_attr_at_index(attrlist, numattr, 146 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 147 numattr++; 148 149 kmf_set_attr_at_index(attrlist, numattr, 150 KMF_CERT_DATA_ATTR, &kmfcert.certificate, 151 sizeof (KMF_DATA)); 152 numattr++; 153 154 kmf_set_attr_at_index(attrlist, numattr, 155 KMF_CERT_FILENAME_ATTR, filename, 156 strlen(filename)); 157 numattr++; 158 159 rv = kmf_store_cert(kmfhandle, numattr, 160 attrlist); 161 162 kmf_free_kmf_cert(kmfhandle, &kmfcert); 163 } 164 } 165 return (rv); 166 } 167 168 static KMF_RETURN 169 pk_export_pk12_nss(KMF_HANDLE_T kmfhandle, 170 char *token_spec, char *dir, char *prefix, 171 char *certlabel, char *issuer, char *subject, 172 KMF_BIGINT *serial, KMF_CREDENTIAL *tokencred, 173 char *filename) 174 { 175 KMF_RETURN rv = KMF_OK; 176 KMF_KEYSTORE_TYPE kstype; 177 KMF_CREDENTIAL p12cred = { NULL, 0}; 178 KMF_ATTRIBUTE attrlist[16]; 179 int numattr = 0; 180 181 rv = configure_nss(kmfhandle, dir, prefix); 182 if (rv != KMF_OK) 183 return (rv); 184 185 if (token_spec == NULL) 186 token_spec = DEFAULT_NSS_TOKEN; 187 188 kstype = KMF_KEYSTORE_NSS; 189 kmf_set_attr_at_index(attrlist, numattr, 190 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 191 numattr++; 192 193 if (certlabel != NULL) { 194 kmf_set_attr_at_index(attrlist, numattr, 195 KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel)); 196 numattr++; 197 } 198 199 if (issuer != NULL) { 200 kmf_set_attr_at_index(attrlist, numattr, 201 KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer)); 202 numattr++; 203 } 204 205 if (subject != NULL) { 206 kmf_set_attr_at_index(attrlist, numattr, 207 KMF_SUBJECT_NAME_ATTR, subject, strlen(subject)); 208 numattr++; 209 } 210 211 if (serial != NULL) { 212 kmf_set_attr_at_index(attrlist, numattr, 213 KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT)); 214 numattr++; 215 } 216 217 if (tokencred != NULL) { 218 kmf_set_attr_at_index(attrlist, numattr, 219 KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL)); 220 numattr++; 221 } 222 223 kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, 224 token_spec, strlen(token_spec)); 225 numattr++; 226 227 (void) get_pk12_password(&p12cred); 228 kmf_set_attr_at_index(attrlist, numattr, 229 KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL)); 230 numattr++; 231 232 kmf_set_attr_at_index(attrlist, numattr, 233 KMF_OUTPUT_FILENAME_ATTR, filename, strlen(filename)); 234 numattr++; 235 236 rv = kmf_export_pk12(kmfhandle, numattr, attrlist); 237 238 if (p12cred.cred) 239 free(p12cred.cred); 240 241 return (rv); 242 } 243 244 static KMF_RETURN 245 pk_export_pk12_files(KMF_HANDLE_T kmfhandle, 246 char *certfile, char *keyfile, char *dir, 247 char *outfile) 248 { 249 KMF_RETURN rv; 250 KMF_KEYSTORE_TYPE kstype; 251 KMF_CREDENTIAL p12cred = { NULL, 0}; 252 KMF_ATTRIBUTE attrlist[16]; 253 int numattr = 0; 254 255 kstype = KMF_KEYSTORE_OPENSSL; 256 kmf_set_attr_at_index(attrlist, numattr, 257 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 258 numattr++; 259 260 if (dir != NULL) { 261 kmf_set_attr_at_index(attrlist, numattr, 262 KMF_DIRPATH_ATTR, dir, strlen(dir)); 263 numattr++; 264 } 265 266 if (certfile != NULL) { 267 kmf_set_attr_at_index(attrlist, numattr, 268 KMF_CERT_FILENAME_ATTR, certfile, strlen(certfile)); 269 numattr++; 270 } 271 272 if (keyfile != NULL) { 273 kmf_set_attr_at_index(attrlist, numattr, 274 KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile)); 275 numattr++; 276 } 277 278 (void) get_pk12_password(&p12cred); 279 kmf_set_attr_at_index(attrlist, numattr, 280 KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL)); 281 numattr++; 282 283 kmf_set_attr_at_index(attrlist, numattr, 284 KMF_OUTPUT_FILENAME_ATTR, outfile, strlen(outfile)); 285 numattr++; 286 287 rv = kmf_export_pk12(kmfhandle, numattr, attrlist); 288 289 if (p12cred.cred) 290 free(p12cred.cred); 291 292 return (rv); 293 } 294 295 static KMF_RETURN 296 pk_export_nss_objects(KMF_HANDLE_T kmfhandle, char *token_spec, 297 int oclass, char *certlabel, char *issuer, char *subject, 298 KMF_BIGINT *serial, KMF_ENCODE_FORMAT kfmt, char *dir, 299 char *prefix, char *filename) 300 { 301 KMF_RETURN rv = KMF_OK; 302 KMF_X509_DER_CERT kmfcert; 303 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; 304 KMF_ATTRIBUTE attrlist[16]; 305 int numattr = 0; 306 307 rv = configure_nss(kmfhandle, dir, prefix); 308 if (rv != KMF_OK) 309 return (rv); 310 311 /* If searching for public objects or certificates, find certs now */ 312 if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) { 313 kmf_set_attr_at_index(attrlist, numattr, 314 KMF_KEYSTORE_TYPE_ATTR, &kstype, 315 sizeof (kstype)); 316 numattr++; 317 318 if (certlabel != NULL) { 319 kmf_set_attr_at_index(attrlist, numattr, 320 KMF_CERT_LABEL_ATTR, certlabel, 321 strlen(certlabel)); 322 numattr++; 323 } 324 325 if (issuer != NULL) { 326 kmf_set_attr_at_index(attrlist, numattr, 327 KMF_ISSUER_NAME_ATTR, issuer, 328 strlen(issuer)); 329 numattr++; 330 } 331 332 if (subject != NULL) { 333 kmf_set_attr_at_index(attrlist, numattr, 334 KMF_SUBJECT_NAME_ATTR, subject, 335 strlen(subject)); 336 numattr++; 337 } 338 339 if (serial != NULL) { 340 kmf_set_attr_at_index(attrlist, numattr, 341 KMF_BIGINT_ATTR, serial, 342 sizeof (KMF_BIGINT)); 343 numattr++; 344 } 345 346 if (token_spec != NULL) { 347 kmf_set_attr_at_index(attrlist, numattr, 348 KMF_TOKEN_LABEL_ATTR, token_spec, 349 strlen(token_spec)); 350 numattr++; 351 } 352 353 rv = pk_find_export_cert(kmfhandle, attrlist, numattr, 354 &kmfcert); 355 if (rv == KMF_OK) { 356 kstype = KMF_KEYSTORE_OPENSSL; 357 numattr = 0; 358 359 kmf_set_attr_at_index(attrlist, numattr, 360 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 361 numattr++; 362 363 kmf_set_attr_at_index(attrlist, numattr, 364 KMF_CERT_DATA_ATTR, &kmfcert.certificate, 365 sizeof (KMF_DATA)); 366 numattr++; 367 368 kmf_set_attr_at_index(attrlist, numattr, 369 KMF_CERT_FILENAME_ATTR, filename, 370 strlen(filename)); 371 numattr++; 372 373 kmf_set_attr_at_index(attrlist, numattr, 374 KMF_ENCODE_FORMAT_ATTR, &kfmt, sizeof (kfmt)); 375 numattr++; 376 377 rv = kmf_store_cert(kmfhandle, numattr, attrlist); 378 379 kmf_free_kmf_cert(kmfhandle, &kmfcert); 380 } 381 } 382 return (rv); 383 } 384 385 static KMF_RETURN 386 pk_export_pk12_pk11(KMF_HANDLE_T kmfhandle, char *token_spec, 387 char *certlabel, char *issuer, char *subject, 388 KMF_BIGINT *serial, KMF_CREDENTIAL *tokencred, char *filename) 389 { 390 KMF_RETURN rv = KMF_OK; 391 KMF_KEYSTORE_TYPE kstype; 392 KMF_CREDENTIAL p12cred = { NULL, 0}; 393 KMF_ATTRIBUTE attrlist[16]; 394 int numattr = 0; 395 396 rv = select_token(kmfhandle, token_spec, TRUE); 397 if (rv != KMF_OK) { 398 return (rv); 399 } 400 401 kstype = KMF_KEYSTORE_PK11TOKEN; 402 kmf_set_attr_at_index(attrlist, numattr, 403 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 404 numattr++; 405 406 if (certlabel != NULL) { 407 kmf_set_attr_at_index(attrlist, numattr, 408 KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel)); 409 numattr++; 410 } 411 412 if (issuer != NULL) { 413 kmf_set_attr_at_index(attrlist, numattr, 414 KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer)); 415 numattr++; 416 } 417 418 if (subject != NULL) { 419 kmf_set_attr_at_index(attrlist, numattr, 420 KMF_SUBJECT_NAME_ATTR, subject, strlen(subject)); 421 numattr++; 422 } 423 424 if (serial != NULL) { 425 kmf_set_attr_at_index(attrlist, numattr, 426 KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT)); 427 numattr++; 428 } 429 430 if (tokencred != NULL) { 431 kmf_set_attr_at_index(attrlist, numattr, 432 KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL)); 433 numattr++; 434 } 435 436 (void) get_pk12_password(&p12cred); 437 kmf_set_attr_at_index(attrlist, numattr, 438 KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL)); 439 numattr++; 440 441 kmf_set_attr_at_index(attrlist, numattr, 442 KMF_OUTPUT_FILENAME_ATTR, filename, strlen(filename)); 443 numattr++; 444 445 rv = kmf_export_pk12(kmfhandle, numattr, attrlist); 446 447 if (p12cred.cred) 448 free(p12cred.cred); 449 450 return (rv); 451 } 452 453 static KMF_RETURN 454 pk_export_pk11_keys(KMF_HANDLE_T kmfhandle, char *token, 455 KMF_CREDENTIAL *cred, KMF_ENCODE_FORMAT format, 456 char *label, char *filename) 457 { 458 KMF_RETURN rv = KMF_OK; 459 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 460 int numattr = 0; 461 uint32_t numkeys = 1; 462 KMF_ATTRIBUTE attrlist[16]; 463 KMF_KEY_HANDLE key; 464 boolean_t is_token = B_TRUE; 465 466 if (EMPTYSTRING(label)) { 467 cryptoerror(LOG_STDERR, gettext("A label " 468 "must be specified to export a key.")); 469 return (KMF_ERR_BAD_PARAMETER); 470 } 471 472 rv = select_token(kmfhandle, token, TRUE); 473 if (rv != KMF_OK) { 474 return (rv); 475 } 476 477 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 478 &kstype, sizeof (kstype)); 479 numattr++; 480 481 if (cred != NULL) { 482 kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, 483 cred, sizeof (KMF_CREDENTIAL)); 484 numattr++; 485 } 486 487 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR, 488 label, strlen(label)); 489 numattr++; 490 491 kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, 492 &numkeys, sizeof (numkeys)); 493 numattr++; 494 495 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 496 &key, sizeof (key)); 497 numattr++; 498 499 kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_BOOL_ATTR, 500 &is_token, sizeof (is_token)); 501 numattr++; 502 503 kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, 504 &format, sizeof (format)); 505 numattr++; 506 507 rv = kmf_find_key(kmfhandle, numattr, attrlist); 508 if (rv == KMF_OK && key.keyclass == KMF_SYMMETRIC) { 509 KMF_RAW_SYM_KEY rkey; 510 511 (void) memset(&rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 512 rv = kmf_get_sym_key_value(kmfhandle, &key, &rkey); 513 if (rv == KMF_OK) { 514 int fd, n, total = 0; 515 516 fd = open(filename, O_CREAT | O_RDWR |O_TRUNC, 0600); 517 if (fd == -1) { 518 rv = KMF_ERR_OPEN_FILE; 519 goto done; 520 } 521 do { 522 n = write(fd, rkey.keydata.val + total, 523 rkey.keydata.len - total); 524 if (n < 0) { 525 if (errno == EINTR) 526 continue; 527 (void) close(fd); 528 rv = KMF_ERR_WRITE_FILE; 529 goto done; 530 } 531 total += n; 532 533 } while (total < rkey.keydata.len); 534 (void) close(fd); 535 } 536 done: 537 kmf_free_bigint(&rkey.keydata); 538 kmf_free_kmf_key(kmfhandle, &key); 539 } else if (rv == KMF_OK) { 540 KMF_KEYSTORE_TYPE sslks = KMF_KEYSTORE_OPENSSL; 541 (void) printf(gettext("Found %d asymmetric keys\n"), numkeys); 542 543 numattr = 0; 544 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 545 &sslks, sizeof (sslks)); 546 numattr++; 547 548 kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR, 549 key.keyp, sizeof (KMF_RAW_KEY_DATA)); 550 numattr++; 551 552 kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, 553 &format, sizeof (format)); 554 numattr++; 555 556 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR, 557 filename, strlen(filename)); 558 numattr++; 559 560 rv = kmf_store_key(kmfhandle, numattr, attrlist); 561 kmf_free_kmf_key(kmfhandle, &key); 562 } 563 564 return (rv); 565 } 566 567 static KMF_RETURN 568 pk_export_pk11_objects(KMF_HANDLE_T kmfhandle, char *token_spec, 569 char *certlabel, char *issuer, char *subject, 570 KMF_BIGINT *serial, KMF_ENCODE_FORMAT kfmt, 571 char *filename) 572 { 573 KMF_RETURN rv = KMF_OK; 574 KMF_X509_DER_CERT kmfcert; 575 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 576 int numattr = 0; 577 KMF_ATTRIBUTE attrlist[16]; 578 579 rv = select_token(kmfhandle, token_spec, TRUE); 580 581 if (rv != KMF_OK) { 582 return (rv); 583 } 584 585 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 586 &kstype, sizeof (kstype)); 587 numattr++; 588 589 if (certlabel != NULL) { 590 kmf_set_attr_at_index(attrlist, numattr, 591 KMF_CERT_LABEL_ATTR, certlabel, 592 strlen(certlabel)); 593 numattr++; 594 } 595 596 if (issuer != NULL) { 597 kmf_set_attr_at_index(attrlist, numattr, 598 KMF_ISSUER_NAME_ATTR, issuer, 599 strlen(issuer)); 600 numattr++; 601 } 602 603 if (subject != NULL) { 604 kmf_set_attr_at_index(attrlist, numattr, 605 KMF_SUBJECT_NAME_ATTR, subject, 606 strlen(subject)); 607 numattr++; 608 } 609 610 if (serial != NULL) { 611 kmf_set_attr_at_index(attrlist, numattr, 612 KMF_BIGINT_ATTR, serial, 613 sizeof (KMF_BIGINT)); 614 numattr++; 615 } 616 617 rv = pk_find_export_cert(kmfhandle, attrlist, numattr, &kmfcert); 618 619 if (rv == KMF_OK) { 620 kstype = KMF_KEYSTORE_OPENSSL; 621 numattr = 0; 622 623 kmf_set_attr_at_index(attrlist, numattr, 624 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 625 numattr++; 626 627 kmf_set_attr_at_index(attrlist, numattr, 628 KMF_CERT_DATA_ATTR, &kmfcert.certificate, 629 sizeof (KMF_DATA)); 630 numattr++; 631 632 kmf_set_attr_at_index(attrlist, numattr, 633 KMF_CERT_FILENAME_ATTR, filename, strlen(filename)); 634 numattr++; 635 636 kmf_set_attr_at_index(attrlist, numattr, 637 KMF_ENCODE_FORMAT_ATTR, &kfmt, sizeof (kfmt)); 638 numattr++; 639 640 rv = kmf_store_cert(kmfhandle, numattr, attrlist); 641 642 kmf_free_kmf_cert(kmfhandle, &kmfcert); 643 } 644 return (rv); 645 } 646 647 /* 648 * Export objects from one keystore to a file. 649 */ 650 int 651 pk_export(int argc, char *argv[]) 652 { 653 int opt; 654 extern int optind_av; 655 extern char *optarg_av; 656 char *token_spec = NULL; 657 char *filename = NULL; 658 char *dir = NULL; 659 char *prefix = NULL; 660 char *certlabel = NULL; 661 char *subject = NULL; 662 char *issuer = NULL; 663 char *infile = NULL; 664 char *keyfile = NULL; 665 char *certfile = NULL; 666 char *serstr = NULL; 667 KMF_KEYSTORE_TYPE kstype = 0; 668 KMF_ENCODE_FORMAT kfmt = KMF_FORMAT_PKCS12; 669 KMF_RETURN rv = KMF_OK; 670 int oclass = PK_CERT_OBJ; 671 KMF_BIGINT serial = { NULL, 0 }; 672 KMF_HANDLE_T kmfhandle = NULL; 673 KMF_CREDENTIAL tokencred = {NULL, 0}; 674 675 /* Parse command line options. Do NOT i18n/l10n. */ 676 while ((opt = getopt_av(argc, argv, 677 "k:(keystore)y:(objtype)T:(token)" 678 "d:(dir)p:(prefix)" 679 "l:(label)n:(nickname)s:(subject)" 680 "i:(issuer)S:(serial)" 681 "K:(keyfile)c:(certfile)" 682 "F:(outformat)" 683 "I:(infile)o:(outfile)")) != EOF) { 684 if (EMPTYSTRING(optarg_av)) 685 return (PK_ERR_USAGE); 686 switch (opt) { 687 case 'k': 688 kstype = KS2Int(optarg_av); 689 if (kstype == 0) 690 return (PK_ERR_USAGE); 691 break; 692 case 'y': 693 oclass = OT2Int(optarg_av); 694 if (oclass == -1) 695 return (PK_ERR_USAGE); 696 break; 697 case 'T': /* token specifier */ 698 if (token_spec) 699 return (PK_ERR_USAGE); 700 token_spec = optarg_av; 701 break; 702 case 'd': 703 if (dir) 704 return (PK_ERR_USAGE); 705 dir = optarg_av; 706 break; 707 case 'p': 708 if (prefix) 709 return (PK_ERR_USAGE); 710 prefix = optarg_av; 711 break; 712 case 'n': 713 case 'l': 714 if (certlabel) 715 return (PK_ERR_USAGE); 716 certlabel = optarg_av; 717 break; 718 case 's': 719 if (subject) 720 return (PK_ERR_USAGE); 721 subject = optarg_av; 722 break; 723 case 'i': 724 if (issuer) 725 return (PK_ERR_USAGE); 726 issuer = optarg_av; 727 break; 728 case 'S': 729 serstr = optarg_av; 730 break; 731 case 'F': 732 kfmt = Str2Format(optarg_av); 733 if (kfmt == KMF_FORMAT_UNDEF) 734 return (PK_ERR_USAGE); 735 break; 736 case 'I': /* output file name */ 737 if (infile) 738 return (PK_ERR_USAGE); 739 infile = optarg_av; 740 break; 741 case 'o': /* output file name */ 742 if (filename) 743 return (PK_ERR_USAGE); 744 filename = optarg_av; 745 break; 746 case 'c': /* input cert file name */ 747 if (certfile) 748 return (PK_ERR_USAGE); 749 certfile = optarg_av; 750 break; 751 case 'K': /* input key file name */ 752 if (keyfile) 753 return (PK_ERR_USAGE); 754 keyfile = optarg_av; 755 break; 756 default: 757 return (PK_ERR_USAGE); 758 break; 759 } 760 } 761 762 /* Assume keystore = PKCS#11 if not specified */ 763 if (kstype == 0) 764 kstype = KMF_KEYSTORE_PK11TOKEN; 765 766 /* Filename arg is required. */ 767 if (EMPTYSTRING(filename)) { 768 cryptoerror(LOG_STDERR, gettext("You must specify " 769 "an 'outfile' parameter when exporting.\n")); 770 return (PK_ERR_USAGE); 771 } 772 773 /* No additional args allowed. */ 774 argc -= optind_av; 775 argv += optind_av; 776 if (argc) 777 return (PK_ERR_USAGE); 778 779 /* if PUBLIC or PRIVATE obj was given, the old syntax was used. */ 780 if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) && 781 kstype != KMF_KEYSTORE_PK11TOKEN) { 782 783 (void) fprintf(stderr, gettext("The objtype parameter " 784 "is only relevant if keystore=pkcs11\n")); 785 return (PK_ERR_USAGE); 786 } 787 788 if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) 789 token_spec = PK_DEFAULT_PK11TOKEN; 790 else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) 791 token_spec = DEFAULT_NSS_TOKEN; 792 793 if (kstype == KMF_KEYSTORE_OPENSSL) { 794 if (kfmt != KMF_FORMAT_PKCS12) { 795 cryptoerror(LOG_STDERR, gettext("PKCS12 " 796 "is the only export format " 797 "supported for the 'file' " 798 "keystore.\n")); 799 return (PK_ERR_USAGE); 800 } 801 if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) { 802 cryptoerror(LOG_STDERR, gettext("A cert file" 803 "and a key file must be specified " 804 "when exporting to PKCS12 from the " 805 "'file' keystore.\n")); 806 return (PK_ERR_USAGE); 807 } 808 } 809 810 /* Check if the file exists and might be overwritten. */ 811 if (access(filename, F_OK) == 0) { 812 cryptoerror(LOG_STDERR, 813 gettext("Warning: file \"%s\" exists, " 814 "will be overwritten."), filename); 815 if (yesno(gettext("Continue with export? "), 816 gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) { 817 return (0); 818 } 819 } else { 820 rv = verify_file(filename); 821 if (rv != KMF_OK) { 822 cryptoerror(LOG_STDERR, gettext("The file (%s) " 823 "cannot be created.\n"), filename); 824 return (PK_ERR_USAGE); 825 } 826 } 827 828 if (serstr != NULL) { 829 uchar_t *bytes = NULL; 830 size_t bytelen; 831 832 rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen); 833 if (rv != KMF_OK || bytes == NULL) { 834 (void) fprintf(stderr, gettext("serial number " 835 "must be specified as a hex number " 836 "(ex: 0x0102030405ffeeddee)\n")); 837 return (PK_ERR_USAGE); 838 } 839 serial.val = bytes; 840 serial.len = bytelen; 841 } 842 843 if ((kstype == KMF_KEYSTORE_PK11TOKEN || 844 kstype == KMF_KEYSTORE_NSS) && 845 (oclass & (PK_KEY_OBJ | PK_PRIVATE_OBJ) || 846 kfmt == KMF_FORMAT_PKCS12)) { 847 (void) get_token_password(kstype, token_spec, 848 &tokencred); 849 } 850 851 if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 852 cryptoerror(LOG_STDERR, gettext("Error initializing " 853 "KMF: 0x%02x\n"), rv); 854 return (rv); 855 } 856 857 switch (kstype) { 858 case KMF_KEYSTORE_PK11TOKEN: 859 if (kfmt == KMF_FORMAT_PKCS12) 860 rv = pk_export_pk12_pk11(kmfhandle, 861 token_spec, certlabel, 862 issuer, subject, 863 &serial, &tokencred, 864 filename); 865 else if ((oclass & PK_KEY_OBJ) || 866 kfmt == KMF_FORMAT_RAWKEY) 867 rv = pk_export_pk11_keys(kmfhandle, 868 token_spec, &tokencred, kfmt, 869 certlabel, filename); 870 else 871 rv = pk_export_pk11_objects(kmfhandle, 872 token_spec, certlabel, 873 issuer, subject, &serial, kfmt, 874 filename); 875 break; 876 case KMF_KEYSTORE_NSS: 877 if (dir == NULL) 878 dir = PK_DEFAULT_DIRECTORY; 879 if (kfmt == KMF_FORMAT_PKCS12) 880 rv = pk_export_pk12_nss(kmfhandle, 881 token_spec, dir, prefix, 882 certlabel, issuer, 883 subject, &serial, 884 &tokencred, filename); 885 else 886 rv = pk_export_nss_objects(kmfhandle, 887 token_spec, 888 oclass, certlabel, issuer, subject, 889 &serial, kfmt, dir, prefix, filename); 890 break; 891 case KMF_KEYSTORE_OPENSSL: 892 if (kfmt == KMF_FORMAT_PKCS12) 893 rv = pk_export_pk12_files(kmfhandle, 894 certfile, keyfile, dir, 895 filename); 896 else 897 rv = pk_export_file_objects(kmfhandle, oclass, 898 issuer, subject, &serial, 899 dir, infile, filename); 900 break; 901 default: 902 rv = PK_ERR_USAGE; 903 break; 904 } 905 906 if (rv != KMF_OK) { 907 display_error(kmfhandle, rv, 908 gettext("Error exporting objects")); 909 } 910 911 if (serial.val != NULL) 912 free(serial.val); 913 914 (void) kmf_finalize(kmfhandle); 915 916 return (rv); 917 } 918