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 KMF_KEY_CLASS keyclass = KMF_SYMMETRIC; 465 boolean_t is_token = B_TRUE; 466 467 if (EMPTYSTRING(label)) { 468 cryptoerror(LOG_STDERR, gettext("A label " 469 "must be specified to export a key.")); 470 return (KMF_ERR_BAD_PARAMETER); 471 } 472 473 rv = select_token(kmfhandle, token, TRUE); 474 if (rv != KMF_OK) { 475 return (rv); 476 } 477 478 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 479 &kstype, sizeof (kstype)); 480 numattr++; 481 482 if (cred != NULL) { 483 kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, 484 cred, sizeof (KMF_CREDENTIAL)); 485 numattr++; 486 } 487 488 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR, 489 label, strlen(label)); 490 numattr++; 491 492 kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, 493 &numkeys, sizeof (numkeys)); 494 numattr++; 495 496 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 497 &key, sizeof (key)); 498 numattr++; 499 500 kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_BOOL_ATTR, 501 &is_token, sizeof (is_token)); 502 numattr++; 503 504 kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, 505 &format, sizeof (format)); 506 numattr++; 507 508 rv = kmf_find_key(kmfhandle, numattr, attrlist); 509 if (rv == KMF_OK && key.keyclass == KMF_SYMMETRIC) { 510 KMF_RAW_SYM_KEY rkey; 511 512 (void) memset(&rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 513 rv = kmf_get_sym_key_value(kmfhandle, &key, &rkey); 514 if (rv == KMF_OK) { 515 int fd, n, total = 0; 516 517 fd = open(filename, O_CREAT | O_RDWR |O_TRUNC, 0600); 518 if (fd == -1) { 519 rv = KMF_ERR_OPEN_FILE; 520 goto done; 521 } 522 do { 523 n = write(fd, rkey.keydata.val + total, 524 rkey.keydata.len - total); 525 if (n < 0) { 526 if (errno == EINTR) 527 continue; 528 close(fd); 529 rv = KMF_ERR_WRITE_FILE; 530 goto done; 531 } 532 total += n; 533 534 } while (total < rkey.keydata.len); 535 close(fd); 536 } 537 done: 538 kmf_free_bigint(&rkey.keydata); 539 kmf_free_kmf_key(kmfhandle, &key); 540 } else if (rv == KMF_OK) { 541 KMF_KEYSTORE_TYPE sslks = KMF_KEYSTORE_OPENSSL; 542 printf(gettext("Found %d asymmetric keys\n"), numkeys); 543 544 numattr = 0; 545 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 546 &sslks, sizeof (sslks)); 547 numattr++; 548 549 kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR, 550 key.keyp, sizeof (KMF_RAW_KEY_DATA)); 551 numattr++; 552 553 kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, 554 &format, sizeof (format)); 555 numattr++; 556 557 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR, 558 filename, strlen(filename)); 559 numattr++; 560 561 rv = kmf_store_key(kmfhandle, numattr, attrlist); 562 kmf_free_kmf_key(kmfhandle, &key); 563 } 564 565 return (rv); 566 } 567 568 static KMF_RETURN 569 pk_export_pk11_objects(KMF_HANDLE_T kmfhandle, char *token_spec, 570 char *certlabel, char *issuer, char *subject, 571 KMF_BIGINT *serial, KMF_ENCODE_FORMAT kfmt, 572 char *filename) 573 { 574 KMF_RETURN rv = KMF_OK; 575 KMF_X509_DER_CERT kmfcert; 576 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 577 int numattr = 0; 578 KMF_ATTRIBUTE attrlist[16]; 579 580 rv = select_token(kmfhandle, token_spec, TRUE); 581 582 if (rv != KMF_OK) { 583 return (rv); 584 } 585 586 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 587 &kstype, sizeof (kstype)); 588 numattr++; 589 590 if (certlabel != NULL) { 591 kmf_set_attr_at_index(attrlist, numattr, 592 KMF_CERT_LABEL_ATTR, certlabel, 593 strlen(certlabel)); 594 numattr++; 595 } 596 597 if (issuer != NULL) { 598 kmf_set_attr_at_index(attrlist, numattr, 599 KMF_ISSUER_NAME_ATTR, issuer, 600 strlen(issuer)); 601 numattr++; 602 } 603 604 if (subject != NULL) { 605 kmf_set_attr_at_index(attrlist, numattr, 606 KMF_SUBJECT_NAME_ATTR, subject, 607 strlen(subject)); 608 numattr++; 609 } 610 611 if (serial != NULL) { 612 kmf_set_attr_at_index(attrlist, numattr, 613 KMF_BIGINT_ATTR, serial, 614 sizeof (KMF_BIGINT)); 615 numattr++; 616 } 617 618 rv = pk_find_export_cert(kmfhandle, attrlist, numattr, &kmfcert); 619 620 if (rv == KMF_OK) { 621 kstype = KMF_KEYSTORE_OPENSSL; 622 numattr = 0; 623 624 kmf_set_attr_at_index(attrlist, numattr, 625 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 626 numattr++; 627 628 kmf_set_attr_at_index(attrlist, numattr, 629 KMF_CERT_DATA_ATTR, &kmfcert.certificate, 630 sizeof (KMF_DATA)); 631 numattr++; 632 633 kmf_set_attr_at_index(attrlist, numattr, 634 KMF_CERT_FILENAME_ATTR, filename, strlen(filename)); 635 numattr++; 636 637 kmf_set_attr_at_index(attrlist, numattr, 638 KMF_ENCODE_FORMAT_ATTR, &kfmt, sizeof (kfmt)); 639 numattr++; 640 641 rv = kmf_store_cert(kmfhandle, numattr, attrlist); 642 643 kmf_free_kmf_cert(kmfhandle, &kmfcert); 644 } 645 return (rv); 646 } 647 648 /* 649 * Export objects from one keystore to a file. 650 */ 651 int 652 pk_export(int argc, char *argv[]) 653 { 654 int opt; 655 extern int optind_av; 656 extern char *optarg_av; 657 char *token_spec = NULL; 658 char *filename = NULL; 659 char *dir = NULL; 660 char *prefix = NULL; 661 char *certlabel = NULL; 662 char *subject = NULL; 663 char *issuer = NULL; 664 char *infile = NULL; 665 char *keyfile = NULL; 666 char *certfile = NULL; 667 char *serstr = NULL; 668 KMF_KEYSTORE_TYPE kstype = 0; 669 KMF_ENCODE_FORMAT kfmt = KMF_FORMAT_PKCS12; 670 KMF_RETURN rv = KMF_OK; 671 int oclass = PK_CERT_OBJ; 672 KMF_BIGINT serial = { NULL, 0 }; 673 KMF_HANDLE_T kmfhandle = NULL; 674 KMF_CREDENTIAL tokencred = {NULL, 0}; 675 676 /* Parse command line options. Do NOT i18n/l10n. */ 677 while ((opt = getopt_av(argc, argv, 678 "k:(keystore)y:(objtype)T:(token)" 679 "d:(dir)p:(prefix)" 680 "l:(label)n:(nickname)s:(subject)" 681 "i:(issuer)S:(serial)" 682 "K:(keyfile)c:(certfile)" 683 "F:(outformat)" 684 "I:(infile)o:(outfile)")) != EOF) { 685 if (EMPTYSTRING(optarg_av)) 686 return (PK_ERR_USAGE); 687 switch (opt) { 688 case 'k': 689 kstype = KS2Int(optarg_av); 690 if (kstype == 0) 691 return (PK_ERR_USAGE); 692 break; 693 case 'y': 694 oclass = OT2Int(optarg_av); 695 if (oclass == -1) 696 return (PK_ERR_USAGE); 697 break; 698 case 'T': /* token specifier */ 699 if (token_spec) 700 return (PK_ERR_USAGE); 701 token_spec = optarg_av; 702 break; 703 case 'd': 704 if (dir) 705 return (PK_ERR_USAGE); 706 dir = optarg_av; 707 break; 708 case 'p': 709 if (prefix) 710 return (PK_ERR_USAGE); 711 prefix = optarg_av; 712 break; 713 case 'n': 714 case 'l': 715 if (certlabel) 716 return (PK_ERR_USAGE); 717 certlabel = optarg_av; 718 break; 719 case 's': 720 if (subject) 721 return (PK_ERR_USAGE); 722 subject = optarg_av; 723 break; 724 case 'i': 725 if (issuer) 726 return (PK_ERR_USAGE); 727 issuer = optarg_av; 728 break; 729 case 'S': 730 serstr = optarg_av; 731 break; 732 case 'F': 733 kfmt = Str2Format(optarg_av); 734 if (kfmt == KMF_FORMAT_UNDEF) 735 return (PK_ERR_USAGE); 736 break; 737 case 'I': /* output file name */ 738 if (infile) 739 return (PK_ERR_USAGE); 740 infile = optarg_av; 741 break; 742 case 'o': /* output file name */ 743 if (filename) 744 return (PK_ERR_USAGE); 745 filename = optarg_av; 746 break; 747 case 'c': /* input cert file name */ 748 if (certfile) 749 return (PK_ERR_USAGE); 750 certfile = optarg_av; 751 break; 752 case 'K': /* input key file name */ 753 if (keyfile) 754 return (PK_ERR_USAGE); 755 keyfile = optarg_av; 756 break; 757 default: 758 return (PK_ERR_USAGE); 759 break; 760 } 761 } 762 763 /* Assume keystore = PKCS#11 if not specified */ 764 if (kstype == 0) 765 kstype = KMF_KEYSTORE_PK11TOKEN; 766 767 /* Filename arg is required. */ 768 if (EMPTYSTRING(filename)) { 769 cryptoerror(LOG_STDERR, gettext("You must specify " 770 "an 'outfile' parameter when exporting.\n")); 771 return (PK_ERR_USAGE); 772 } 773 774 /* No additional args allowed. */ 775 argc -= optind_av; 776 argv += optind_av; 777 if (argc) 778 return (PK_ERR_USAGE); 779 780 /* if PUBLIC or PRIVATE obj was given, the old syntax was used. */ 781 if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) && 782 kstype != KMF_KEYSTORE_PK11TOKEN) { 783 784 (void) fprintf(stderr, gettext("The objtype parameter " 785 "is only relevant if keystore=pkcs11\n")); 786 return (PK_ERR_USAGE); 787 } 788 789 if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) 790 token_spec = PK_DEFAULT_PK11TOKEN; 791 else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) 792 token_spec = DEFAULT_NSS_TOKEN; 793 794 if (kstype == KMF_KEYSTORE_OPENSSL) { 795 if (kfmt != KMF_FORMAT_PKCS12) { 796 cryptoerror(LOG_STDERR, gettext("PKCS12 " 797 "is the only export format " 798 "supported for the 'file' " 799 "keystore.\n")); 800 return (PK_ERR_USAGE); 801 } 802 if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) { 803 cryptoerror(LOG_STDERR, gettext("A cert file" 804 "and a key file must be specified " 805 "when exporting to PKCS12 from the " 806 "'file' keystore.\n")); 807 return (PK_ERR_USAGE); 808 } 809 } 810 811 /* Check if the file exists and might be overwritten. */ 812 if (access(filename, F_OK) == 0) { 813 cryptoerror(LOG_STDERR, 814 gettext("Warning: file \"%s\" exists, " 815 "will be overwritten."), filename); 816 if (yesno(gettext("Continue with export? "), 817 gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) { 818 return (0); 819 } 820 } else { 821 rv = verify_file(filename); 822 if (rv != KMF_OK) { 823 cryptoerror(LOG_STDERR, gettext("The file (%s) " 824 "cannot be created.\n"), filename); 825 return (PK_ERR_USAGE); 826 } 827 } 828 829 if (serstr != NULL) { 830 uchar_t *bytes = NULL; 831 size_t bytelen; 832 833 rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen); 834 if (rv != KMF_OK || bytes == NULL) { 835 (void) fprintf(stderr, gettext("serial number " 836 "must be specified as a hex number " 837 "(ex: 0x0102030405ffeeddee)\n")); 838 return (PK_ERR_USAGE); 839 } 840 serial.val = bytes; 841 serial.len = bytelen; 842 } 843 844 if ((kstype == KMF_KEYSTORE_PK11TOKEN || 845 kstype == KMF_KEYSTORE_NSS) && 846 (oclass & (PK_KEY_OBJ | PK_PRIVATE_OBJ) || 847 kfmt == KMF_FORMAT_PKCS12)) { 848 (void) get_token_password(kstype, token_spec, 849 &tokencred); 850 } 851 852 if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 853 cryptoerror(LOG_STDERR, gettext("Error initializing " 854 "KMF: 0x%02x\n"), rv); 855 return (rv); 856 } 857 858 switch (kstype) { 859 case KMF_KEYSTORE_PK11TOKEN: 860 if (kfmt == KMF_FORMAT_PKCS12) 861 rv = pk_export_pk12_pk11(kmfhandle, 862 token_spec, certlabel, 863 issuer, subject, 864 &serial, &tokencred, 865 filename); 866 else if ((oclass & PK_KEY_OBJ) || 867 kfmt == KMF_FORMAT_RAWKEY) 868 rv = pk_export_pk11_keys(kmfhandle, 869 token_spec, &tokencred, kfmt, 870 certlabel, filename); 871 else 872 rv = pk_export_pk11_objects(kmfhandle, 873 token_spec, certlabel, 874 issuer, subject, &serial, kfmt, 875 filename); 876 break; 877 case KMF_KEYSTORE_NSS: 878 if (dir == NULL) 879 dir = PK_DEFAULT_DIRECTORY; 880 if (kfmt == KMF_FORMAT_PKCS12) 881 rv = pk_export_pk12_nss(kmfhandle, 882 token_spec, dir, prefix, 883 certlabel, issuer, 884 subject, &serial, 885 &tokencred, filename); 886 else 887 rv = pk_export_nss_objects(kmfhandle, 888 token_spec, 889 oclass, certlabel, issuer, subject, 890 &serial, kfmt, dir, prefix, filename); 891 break; 892 case KMF_KEYSTORE_OPENSSL: 893 if (kfmt == KMF_FORMAT_PKCS12) 894 rv = pk_export_pk12_files(kmfhandle, 895 certfile, keyfile, dir, 896 filename); 897 else 898 rv = pk_export_file_objects(kmfhandle, oclass, 899 issuer, subject, &serial, 900 dir, infile, filename); 901 break; 902 default: 903 rv = PK_ERR_USAGE; 904 break; 905 } 906 907 if (rv != KMF_OK) { 908 display_error(kmfhandle, rv, 909 gettext("Error exporting objects")); 910 } 911 912 if (serial.val != NULL) 913 free(serial.val); 914 915 (void) kmf_finalize(kmfhandle); 916 917 return (rv); 918 } 919