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