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