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