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 2008 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 import operation for this tool. 30 * The basic flow of the process is to decrypt the PKCS#12 31 * input file if it has a password, parse the elements in 32 * the file, find the soft token, log into it, import the 33 * PKCS#11 objects into the soft token, and log out. 34 */ 35 36 #include <stdio.h> 37 #include <stdlib.h> 38 #include <string.h> 39 #include <ctype.h> 40 #include <errno.h> 41 #include <fcntl.h> 42 #include <sys/types.h> 43 #include <sys/stat.h> 44 #include "common.h" 45 46 #include <kmfapi.h> 47 48 #define NEW_ATTRLIST(a, n) \ 49 { \ 50 a = (KMF_ATTRIBUTE *)malloc(n * sizeof (KMF_ATTRIBUTE)); \ 51 if (a == NULL) { \ 52 rv = KMF_ERR_MEMORY; \ 53 goto end; \ 54 } \ 55 (void) memset(a, 0, n * sizeof (KMF_ATTRIBUTE)); \ 56 } 57 58 static KMF_RETURN 59 pk_import_pk12_files(KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *cred, 60 char *outfile, char *certfile, char *keyfile, 61 char *dir, char *keydir, KMF_ENCODE_FORMAT outformat) 62 { 63 KMF_RETURN rv = KMF_OK; 64 KMF_X509_DER_CERT *certs = NULL; 65 KMF_RAW_KEY_DATA *keys = NULL; 66 int ncerts = 0; 67 int nkeys = 0; 68 int i; 69 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 70 KMF_ATTRIBUTE *attrlist = NULL; 71 int numattr = 0; 72 73 rv = kmf_import_objects(kmfhandle, outfile, cred, 74 &certs, &ncerts, &keys, &nkeys); 75 76 if (rv == KMF_OK) { 77 (void) printf(gettext("Found %d certificate(s) and %d " 78 "key(s) in %s\n"), ncerts, nkeys, outfile); 79 } 80 81 if (rv == KMF_OK && ncerts > 0) { 82 char newcertfile[MAXPATHLEN]; 83 84 NEW_ATTRLIST(attrlist, (3 + (3 * ncerts))); 85 86 kmf_set_attr_at_index(attrlist, numattr, 87 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 88 numattr++; 89 90 if (dir != NULL) { 91 kmf_set_attr_at_index(attrlist, numattr, 92 KMF_DIRPATH_ATTR, dir, strlen(dir)); 93 numattr++; 94 } 95 96 kmf_set_attr_at_index(attrlist, numattr, 97 KMF_ENCODE_FORMAT_ATTR, &outformat, sizeof (outformat)); 98 numattr++; 99 100 for (i = 0; rv == KMF_OK && i < ncerts; i++) { 101 int num = numattr; 102 103 /* 104 * If storing more than 1 cert, gotta change 105 * the name so we don't overwrite the previous one. 106 * Just append a _# to the name. 107 */ 108 if (i > 0) { 109 (void) snprintf(newcertfile, 110 sizeof (newcertfile), "%s_%d", certfile, i); 111 112 kmf_set_attr_at_index(attrlist, num, 113 KMF_CERT_FILENAME_ATTR, newcertfile, 114 strlen(newcertfile)); 115 num++; 116 } else { 117 kmf_set_attr_at_index(attrlist, num, 118 KMF_CERT_FILENAME_ATTR, certfile, 119 strlen(certfile)); 120 num++; 121 } 122 123 if (certs[i].kmf_private.label != NULL) { 124 kmf_set_attr_at_index(attrlist, num, 125 KMF_CERT_LABEL_ATTR, 126 certs[i].kmf_private.label, 127 strlen(certs[i].kmf_private.label)); 128 num++; 129 } 130 kmf_set_attr_at_index(attrlist, num, 131 KMF_CERT_DATA_ATTR, &certs[i].certificate, 132 sizeof (KMF_DATA)); 133 num++; 134 rv = kmf_store_cert(kmfhandle, num, attrlist); 135 } 136 free(attrlist); 137 } 138 if (rv == KMF_OK && nkeys > 0) { 139 char newkeyfile[MAXPATHLEN]; 140 numattr = 0; 141 NEW_ATTRLIST(attrlist, (4 + (4 * nkeys))); 142 143 kmf_set_attr_at_index(attrlist, numattr, 144 KMF_KEYSTORE_TYPE_ATTR, &kstype, 145 sizeof (kstype)); 146 numattr++; 147 148 if (keydir != NULL) { 149 kmf_set_attr_at_index(attrlist, numattr, 150 KMF_DIRPATH_ATTR, keydir, 151 strlen(keydir)); 152 numattr++; 153 } 154 155 kmf_set_attr_at_index(attrlist, numattr, 156 KMF_ENCODE_FORMAT_ATTR, &outformat, 157 sizeof (outformat)); 158 numattr++; 159 160 if (cred != NULL && cred->credlen > 0) { 161 kmf_set_attr_at_index(attrlist, numattr, 162 KMF_CREDENTIAL_ATTR, cred, 163 sizeof (KMF_CREDENTIAL)); 164 numattr++; 165 } 166 167 /* The order of certificates and keys should match */ 168 for (i = 0; rv == KMF_OK && i < nkeys; i++) { 169 int num = numattr; 170 171 if (i > 0) { 172 (void) snprintf(newkeyfile, 173 sizeof (newkeyfile), "%s_%d", keyfile, i); 174 175 kmf_set_attr_at_index(attrlist, num, 176 KMF_KEY_FILENAME_ATTR, newkeyfile, 177 strlen(newkeyfile)); 178 num++; 179 } else { 180 kmf_set_attr_at_index(attrlist, num, 181 KMF_KEY_FILENAME_ATTR, keyfile, 182 strlen(keyfile)); 183 num++; 184 } 185 186 if (i < ncerts) { 187 kmf_set_attr_at_index(attrlist, num, 188 KMF_CERT_DATA_ATTR, &certs[i], 189 sizeof (KMF_CERT_DATA_ATTR)); 190 num++; 191 } 192 193 kmf_set_attr_at_index(attrlist, num, 194 KMF_RAW_KEY_ATTR, &keys[i], 195 sizeof (KMF_RAW_KEY_DATA)); 196 num++; 197 198 rv = kmf_store_key(kmfhandle, num, attrlist); 199 } 200 free(attrlist); 201 } 202 end: 203 /* 204 * Cleanup memory. 205 */ 206 if (certs) { 207 for (i = 0; i < ncerts; i++) 208 kmf_free_kmf_cert(kmfhandle, &certs[i]); 209 free(certs); 210 } 211 if (keys) { 212 for (i = 0; i < nkeys; i++) 213 kmf_free_raw_key(&keys[i]); 214 free(keys); 215 } 216 217 218 return (rv); 219 } 220 221 222 static KMF_RETURN 223 pk_import_pk12_nss( 224 KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *kmfcred, 225 KMF_CREDENTIAL *tokencred, 226 char *token_spec, char *dir, char *prefix, 227 char *nickname, char *trustflags, char *filename) 228 { 229 KMF_RETURN rv = KMF_OK; 230 KMF_X509_DER_CERT *certs = NULL; 231 KMF_RAW_KEY_DATA *keys = NULL; 232 int ncerts = 0; 233 int nkeys = 0; 234 int i; 235 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; 236 KMF_ATTRIBUTE *attrlist = NULL; 237 int numattr = 0; 238 239 rv = configure_nss(kmfhandle, dir, prefix); 240 if (rv != KMF_OK) 241 return (rv); 242 243 rv = kmf_import_objects(kmfhandle, filename, kmfcred, 244 &certs, &ncerts, &keys, &nkeys); 245 246 if (rv == KMF_OK) 247 (void) printf(gettext("Found %d certificate(s) and %d " 248 "key(s) in %s\n"), ncerts, nkeys, filename); 249 250 if (rv == KMF_OK) { 251 NEW_ATTRLIST(attrlist, (3 + (2 * ncerts))); 252 253 kmf_set_attr_at_index(attrlist, numattr, 254 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 255 numattr++; 256 257 if (token_spec != NULL) { 258 kmf_set_attr_at_index(attrlist, numattr, 259 KMF_TOKEN_LABEL_ATTR, token_spec, 260 strlen(token_spec)); 261 numattr++; 262 } 263 264 if (trustflags != NULL) { 265 kmf_set_attr_at_index(attrlist, numattr, 266 KMF_TRUSTFLAG_ATTR, trustflags, 267 strlen(trustflags)); 268 numattr++; 269 } 270 271 for (i = 0; rv == KMF_OK && i < ncerts; i++) { 272 int num = numattr; 273 274 if (certs[i].kmf_private.label != NULL) { 275 kmf_set_attr_at_index(attrlist, num, 276 KMF_CERT_LABEL_ATTR, 277 certs[i].kmf_private.label, 278 strlen(certs[i].kmf_private.label)); 279 num++; 280 } else if (i == 0 && nickname != NULL) { 281 kmf_set_attr_at_index(attrlist, num, 282 KMF_CERT_LABEL_ATTR, nickname, 283 strlen(nickname)); 284 num++; 285 } 286 287 kmf_set_attr_at_index(attrlist, num, 288 KMF_CERT_DATA_ATTR, 289 &certs[i].certificate, sizeof (KMF_DATA)); 290 num++; 291 rv = kmf_store_cert(kmfhandle, num, attrlist); 292 } 293 free(attrlist); 294 attrlist = NULL; 295 if (rv != KMF_OK) { 296 display_error(kmfhandle, rv, 297 gettext("Error storing certificate in NSS token")); 298 } 299 } 300 301 if (rv == KMF_OK) { 302 numattr = 0; 303 NEW_ATTRLIST(attrlist, (4 + (2 * nkeys))); 304 305 kmf_set_attr_at_index(attrlist, numattr, 306 KMF_KEYSTORE_TYPE_ATTR, &kstype, 307 sizeof (kstype)); 308 numattr++; 309 310 if (token_spec != NULL) { 311 kmf_set_attr_at_index(attrlist, numattr, 312 KMF_TOKEN_LABEL_ATTR, token_spec, 313 strlen(token_spec)); 314 numattr++; 315 } 316 317 if (nickname != NULL) { 318 kmf_set_attr_at_index(attrlist, numattr, 319 KMF_KEYLABEL_ATTR, nickname, 320 strlen(nickname)); 321 numattr++; 322 } 323 324 if (tokencred->credlen > 0) { 325 kmf_set_attr_at_index(attrlist, numattr, 326 KMF_CREDENTIAL_ATTR, tokencred, 327 sizeof (KMF_CREDENTIAL)); 328 numattr++; 329 } 330 331 /* The order of certificates and keys should match */ 332 for (i = 0; i < nkeys; i++) { 333 int num = numattr; 334 335 if (i < ncerts) { 336 kmf_set_attr_at_index(attrlist, num, 337 KMF_CERT_DATA_ATTR, &certs[i], 338 sizeof (KMF_DATA)); 339 num++; 340 } 341 342 kmf_set_attr_at_index(attrlist, num, 343 KMF_RAW_KEY_ATTR, &keys[i], 344 sizeof (KMF_RAW_KEY_DATA)); 345 num++; 346 347 rv = kmf_store_key(kmfhandle, num, attrlist); 348 } 349 free(attrlist); 350 } 351 352 end: 353 /* 354 * Cleanup memory. 355 */ 356 if (certs) { 357 for (i = 0; i < ncerts; i++) 358 kmf_free_kmf_cert(kmfhandle, &certs[i]); 359 free(certs); 360 } 361 if (keys) { 362 for (i = 0; i < nkeys; i++) 363 kmf_free_raw_key(&keys[i]); 364 free(keys); 365 } 366 367 return (rv); 368 } 369 370 static KMF_RETURN 371 pk_import_cert( 372 KMF_HANDLE_T kmfhandle, 373 KMF_KEYSTORE_TYPE kstype, 374 char *label, char *token_spec, char *filename, 375 char *dir, char *prefix, char *trustflags) 376 { 377 KMF_RETURN rv = KMF_OK; 378 KMF_ATTRIBUTE attrlist[32]; 379 KMF_CREDENTIAL tokencred; 380 int i = 0; 381 382 if (kstype == KMF_KEYSTORE_PK11TOKEN) { 383 rv = select_token(kmfhandle, token_spec, FALSE); 384 } else if (kstype == KMF_KEYSTORE_NSS) { 385 rv = configure_nss(kmfhandle, dir, prefix); 386 } 387 if (rv != KMF_OK) 388 return (rv); 389 390 kmf_set_attr_at_index(attrlist, i, 391 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (KMF_KEYSTORE_TYPE)); 392 i++; 393 394 kmf_set_attr_at_index(attrlist, i, KMF_CERT_FILENAME_ATTR, 395 filename, strlen(filename)); 396 i++; 397 398 if (label != NULL) { 399 kmf_set_attr_at_index(attrlist, i, KMF_CERT_LABEL_ATTR, 400 label, strlen(label)); 401 i++; 402 } 403 404 if (kstype == KMF_KEYSTORE_NSS) { 405 if (trustflags != NULL) { 406 kmf_set_attr_at_index(attrlist, i, KMF_TRUSTFLAG_ATTR, 407 trustflags, strlen(trustflags)); 408 i++; 409 } 410 411 if (token_spec != NULL) { 412 kmf_set_attr_at_index(attrlist, i, 413 KMF_TOKEN_LABEL_ATTR, 414 token_spec, strlen(token_spec)); 415 i++; 416 } 417 } 418 419 rv = kmf_import_cert(kmfhandle, i, attrlist); 420 if (rv == KMF_ERR_AUTH_FAILED) { 421 /* 422 * The token requires a credential, prompt and try again. 423 */ 424 (void) get_token_password(kstype, token_spec, &tokencred); 425 kmf_set_attr_at_index(attrlist, i, KMF_CREDENTIAL_ATTR, 426 &tokencred, sizeof (KMF_CREDENTIAL)); 427 i++; 428 429 rv = kmf_import_cert(kmfhandle, i, attrlist); 430 431 } 432 return (rv); 433 } 434 435 static KMF_RETURN 436 pk_import_file_crl(void *kmfhandle, 437 char *infile, 438 char *outfile, 439 char *outdir, 440 KMF_ENCODE_FORMAT outfmt) 441 { 442 int numattr = 0; 443 KMF_ATTRIBUTE attrlist[8]; 444 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 445 446 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 447 &kstype, sizeof (kstype)); 448 numattr++; 449 if (infile) { 450 kmf_set_attr_at_index(attrlist, numattr, 451 KMF_CRL_FILENAME_ATTR, infile, strlen(infile)); 452 numattr++; 453 } 454 if (outdir) { 455 kmf_set_attr_at_index(attrlist, numattr, 456 KMF_DIRPATH_ATTR, outdir, strlen(outdir)); 457 numattr++; 458 } 459 if (outfile) { 460 kmf_set_attr_at_index(attrlist, numattr, 461 KMF_CRL_OUTFILE_ATTR, outfile, strlen(outfile)); 462 numattr++; 463 } 464 kmf_set_attr_at_index(attrlist, numattr, 465 KMF_ENCODE_FORMAT_ATTR, &outfmt, sizeof (outfmt)); 466 numattr++; 467 468 return (kmf_import_crl(kmfhandle, numattr, attrlist)); 469 } 470 471 static KMF_RETURN 472 pk_import_nss_crl(void *kmfhandle, 473 boolean_t verify_crl_flag, 474 char *infile, 475 char *outdir, 476 char *prefix) 477 { 478 KMF_RETURN rv; 479 int numattr = 0; 480 KMF_ATTRIBUTE attrlist[4]; 481 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; 482 483 rv = configure_nss(kmfhandle, outdir, prefix); 484 if (rv != KMF_OK) 485 return (rv); 486 487 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 488 &kstype, sizeof (kstype)); 489 numattr++; 490 if (infile) { 491 kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_FILENAME_ATTR, 492 infile, strlen(infile)); 493 numattr++; 494 } 495 kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_CHECK_ATTR, 496 &verify_crl_flag, sizeof (verify_crl_flag)); 497 numattr++; 498 499 return (kmf_import_crl(kmfhandle, numattr, attrlist)); 500 501 } 502 503 static KMF_RETURN 504 pk_import_pk12_pk11( 505 KMF_HANDLE_T kmfhandle, 506 KMF_CREDENTIAL *p12cred, 507 KMF_CREDENTIAL *tokencred, 508 char *label, char *token_spec, 509 char *filename) 510 { 511 KMF_RETURN rv = KMF_OK; 512 KMF_X509_DER_CERT *certs = NULL; 513 KMF_RAW_KEY_DATA *keys = NULL; 514 int ncerts = 0; 515 int nkeys = 0; 516 int i; 517 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 518 KMF_ATTRIBUTE *attrlist = NULL; 519 int numattr = 0; 520 521 rv = select_token(kmfhandle, token_spec, FALSE); 522 523 if (rv != KMF_OK) { 524 return (rv); 525 } 526 527 rv = kmf_import_objects(kmfhandle, filename, p12cred, 528 &certs, &ncerts, &keys, &nkeys); 529 530 if (rv == KMF_OK) { 531 NEW_ATTRLIST(attrlist, (3 + (2 * nkeys))); 532 533 kmf_set_attr_at_index(attrlist, numattr, 534 KMF_KEYSTORE_TYPE_ATTR, &kstype, 535 sizeof (kstype)); 536 numattr++; 537 538 if (label != NULL) { 539 kmf_set_attr_at_index(attrlist, numattr, 540 KMF_KEYLABEL_ATTR, label, 541 strlen(label)); 542 numattr++; 543 } 544 545 if (tokencred != NULL && tokencred->credlen > 0) { 546 kmf_set_attr_at_index(attrlist, numattr, 547 KMF_CREDENTIAL_ATTR, tokencred, 548 sizeof (KMF_CREDENTIAL)); 549 numattr++; 550 } 551 552 /* The order of certificates and keys should match */ 553 for (i = 0; i < nkeys; i++) { 554 int num = numattr; 555 556 if (i < ncerts) { 557 kmf_set_attr_at_index(attrlist, num, 558 KMF_CERT_DATA_ATTR, &certs[i].certificate, 559 sizeof (KMF_DATA)); 560 num++; 561 } 562 563 kmf_set_attr_at_index(attrlist, num, 564 KMF_RAW_KEY_ATTR, &keys[i], 565 sizeof (KMF_RAW_KEY_DATA)); 566 num++; 567 568 rv = kmf_store_key(kmfhandle, num, attrlist); 569 570 } 571 free(attrlist); 572 } 573 574 if (rv == KMF_OK) { 575 numattr = 0; 576 NEW_ATTRLIST(attrlist, (1 + (2 * ncerts))); 577 578 (void) printf(gettext("Found %d certificate(s) and %d " 579 "key(s) in %s\n"), ncerts, nkeys, filename); 580 581 kmf_set_attr_at_index(attrlist, numattr, 582 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 583 numattr++; 584 585 for (i = 0; rv == KMF_OK && i < ncerts; i++) { 586 int num = numattr; 587 if (certs[i].kmf_private.label != NULL) { 588 kmf_set_attr_at_index(attrlist, num, 589 KMF_CERT_LABEL_ATTR, 590 certs[i].kmf_private.label, 591 strlen(certs[i].kmf_private.label)); 592 num++; 593 } else if (i == 0 && label != NULL) { 594 kmf_set_attr_at_index(attrlist, num, 595 KMF_CERT_LABEL_ATTR, label, strlen(label)); 596 num++; 597 } 598 599 kmf_set_attr_at_index(attrlist, num, 600 KMF_CERT_DATA_ATTR, &certs[i].certificate, 601 sizeof (KMF_DATA)); 602 num++; 603 604 rv = kmf_store_cert(kmfhandle, num, attrlist); 605 } 606 free(attrlist); 607 } 608 609 end: 610 /* 611 * Cleanup memory. 612 */ 613 if (certs) { 614 for (i = 0; i < ncerts; i++) 615 kmf_free_kmf_cert(kmfhandle, &certs[i]); 616 free(certs); 617 } 618 if (keys) { 619 for (i = 0; i < nkeys; i++) 620 kmf_free_raw_key(&keys[i]); 621 free(keys); 622 } 623 624 return (rv); 625 } 626 627 /*ARGSUSED*/ 628 static KMF_RETURN 629 pk_import_keys(KMF_HANDLE_T kmfhandle, 630 KMF_KEYSTORE_TYPE kstype, char *token_spec, 631 KMF_CREDENTIAL *cred, char *filename, 632 char *label, char *senstr, char *extstr) 633 { 634 KMF_RETURN rv = KMF_OK; 635 KMF_ATTRIBUTE attrlist[16]; 636 KMF_KEYSTORE_TYPE fileks = KMF_KEYSTORE_OPENSSL; 637 int numattr = 0; 638 KMF_KEY_HANDLE key; 639 KMF_RAW_KEY_DATA rawkey; 640 KMF_KEY_CLASS class = KMF_ASYM_PRI; 641 int numkeys = 1; 642 643 if (kstype == KMF_KEYSTORE_PK11TOKEN) { 644 rv = select_token(kmfhandle, token_spec, FALSE); 645 } 646 if (rv != KMF_OK) 647 return (rv); 648 /* 649 * First, set up to read the keyfile using the FILE plugin 650 * mechanisms. 651 */ 652 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 653 &fileks, sizeof (fileks)); 654 numattr++; 655 656 kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, 657 &numkeys, sizeof (numkeys)); 658 numattr++; 659 660 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 661 &key, sizeof (key)); 662 numattr++; 663 664 kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR, 665 &rawkey, sizeof (rawkey)); 666 numattr++; 667 668 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR, 669 &class, sizeof (class)); 670 numattr++; 671 672 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR, 673 filename, strlen(filename)); 674 numattr++; 675 676 rv = kmf_find_key(kmfhandle, numattr, attrlist); 677 if (rv == KMF_OK) { 678 numattr = 0; 679 680 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 681 &kstype, sizeof (kstype)); 682 numattr++; 683 684 if (cred != NULL && cred->credlen > 0) { 685 kmf_set_attr_at_index(attrlist, numattr, 686 KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL)); 687 numattr++; 688 } 689 690 if (label != NULL) { 691 kmf_set_attr_at_index(attrlist, numattr, 692 KMF_KEYLABEL_ATTR, label, strlen(label)); 693 numattr++; 694 } 695 696 kmf_set_attr_at_index(attrlist, numattr, 697 KMF_RAW_KEY_ATTR, &rawkey, sizeof (rawkey)); 698 numattr++; 699 700 rv = kmf_store_key(kmfhandle, numattr, attrlist); 701 if (rv == KMF_OK) { 702 (void) printf(gettext("Importing %d keys\n"), numkeys); 703 } 704 705 kmf_free_kmf_key(kmfhandle, &key); 706 kmf_free_raw_key(&rawkey); 707 } else { 708 cryptoerror(LOG_STDERR, 709 gettext("Failed to load key from file (%s)\n"), 710 filename); 711 } 712 return (rv); 713 } 714 715 static KMF_RETURN 716 pk_import_rawkey(KMF_HANDLE_T kmfhandle, 717 KMF_KEYSTORE_TYPE kstype, char *token, 718 KMF_CREDENTIAL *cred, 719 char *filename, char *label, KMF_KEY_ALG keyAlg, 720 char *senstr, char *extstr) 721 { 722 KMF_RETURN rv = KMF_OK; 723 KMF_ATTRIBUTE attrlist[16]; 724 int numattr = 0; 725 uint32_t keylen; 726 boolean_t sensitive = B_FALSE; 727 boolean_t not_extractable = B_FALSE; 728 KMF_DATA keydata = {NULL, 0}; 729 KMF_KEY_HANDLE rawkey; 730 731 rv = kmf_read_input_file(kmfhandle, filename, &keydata); 732 if (rv != KMF_OK) 733 return (rv); 734 735 rv = select_token(kmfhandle, token, FALSE); 736 737 if (rv != KMF_OK) { 738 return (rv); 739 } 740 if (senstr != NULL) { 741 if (tolower(senstr[0]) == 'y') 742 sensitive = B_TRUE; 743 else if (tolower(senstr[0]) == 'n') 744 sensitive = B_FALSE; 745 else { 746 cryptoerror(LOG_STDERR, 747 gettext("Incorrect sensitive option value.\n")); 748 return (KMF_ERR_BAD_PARAMETER); 749 } 750 } 751 752 if (extstr != NULL) { 753 if (tolower(extstr[0]) == 'y') 754 not_extractable = B_FALSE; 755 else if (tolower(extstr[0]) == 'n') 756 not_extractable = B_TRUE; 757 else { 758 cryptoerror(LOG_STDERR, 759 gettext("Incorrect extractable option value.\n")); 760 return (KMF_ERR_BAD_PARAMETER); 761 } 762 } 763 kmf_set_attr_at_index(attrlist, numattr, 764 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 765 numattr++; 766 767 kmf_set_attr_at_index(attrlist, numattr, 768 KMF_KEY_HANDLE_ATTR, &rawkey, sizeof (rawkey)); 769 numattr++; 770 771 kmf_set_attr_at_index(attrlist, numattr, 772 KMF_KEYALG_ATTR, &keyAlg, sizeof (KMF_KEY_ALG)); 773 numattr++; 774 775 kmf_set_attr_at_index(attrlist, numattr, 776 KMF_KEY_DATA_ATTR, keydata.Data, keydata.Length); 777 numattr++; 778 779 /* Key length is given in bits not bytes */ 780 keylen = keydata.Length * 8; 781 kmf_set_attr_at_index(attrlist, numattr, 782 KMF_KEYLENGTH_ATTR, &keylen, sizeof (keydata.Length)); 783 numattr++; 784 785 kmf_set_attr_at_index(attrlist, numattr, 786 KMF_SENSITIVE_BOOL_ATTR, &sensitive, sizeof (sensitive)); 787 numattr++; 788 789 kmf_set_attr_at_index(attrlist, numattr, 790 KMF_NON_EXTRACTABLE_BOOL_ATTR, ¬_extractable, 791 sizeof (not_extractable)); 792 numattr++; 793 794 if (label != NULL) { 795 kmf_set_attr_at_index(attrlist, numattr, 796 KMF_KEYLABEL_ATTR, label, strlen(label)); 797 numattr++; 798 } 799 if (cred != NULL && cred->credlen > 0) { 800 kmf_set_attr_at_index(attrlist, numattr, 801 KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL)); 802 numattr++; 803 } 804 rv = kmf_create_sym_key(kmfhandle, numattr, attrlist); 805 806 return (rv); 807 } 808 809 /* 810 * Import objects from into KMF repositories. 811 */ 812 int 813 pk_import(int argc, char *argv[]) 814 { 815 int opt; 816 extern int optind_av; 817 extern char *optarg_av; 818 char *token_spec = NULL; 819 char *filename = NULL; 820 char *keyfile = NULL; 821 char *certfile = NULL; 822 char *crlfile = NULL; 823 char *label = NULL; 824 char *dir = NULL; 825 char *keydir = NULL; 826 char *prefix = NULL; 827 char *trustflags = NULL; 828 char *verify_crl = NULL; 829 char *keytype = "generic"; 830 char *senstr = NULL; 831 char *extstr = NULL; 832 boolean_t verify_crl_flag = B_FALSE; 833 int oclass = 0; 834 KMF_KEYSTORE_TYPE kstype = 0; 835 KMF_ENCODE_FORMAT kfmt = 0; 836 KMF_ENCODE_FORMAT okfmt = KMF_FORMAT_ASN1; 837 KMF_RETURN rv = KMF_OK; 838 KMF_CREDENTIAL pk12cred = { NULL, 0 }; 839 KMF_CREDENTIAL tokencred = { NULL, 0 }; 840 KMF_HANDLE_T kmfhandle = NULL; 841 KMF_KEY_ALG keyAlg = KMF_GENERIC_SECRET; 842 843 /* Parse command line options. Do NOT i18n/l10n. */ 844 while ((opt = getopt_av(argc, argv, 845 "T:(token)i:(infile)" 846 "k:(keystore)y:(objtype)" 847 "d:(dir)p:(prefix)" 848 "n:(certlabel)N:(label)" 849 "K:(outkey)c:(outcert)" 850 "v:(verifycrl)l:(outcrl)" 851 "E:(keytype)s:(sensitive)x:(extractable)" 852 "t:(trust)D:(keydir)F:(outformat)")) != EOF) { 853 if (EMPTYSTRING(optarg_av)) 854 return (PK_ERR_USAGE); 855 switch (opt) { 856 case 'T': /* token specifier */ 857 if (token_spec) 858 return (PK_ERR_USAGE); 859 token_spec = optarg_av; 860 break; 861 case 'c': /* output cert file name */ 862 if (certfile) 863 return (PK_ERR_USAGE); 864 certfile = optarg_av; 865 break; 866 case 'l': /* output CRL file name */ 867 if (crlfile) 868 return (PK_ERR_USAGE); 869 crlfile = optarg_av; 870 break; 871 case 'K': /* output key file name */ 872 if (keyfile) 873 return (PK_ERR_USAGE); 874 keyfile = optarg_av; 875 break; 876 case 'i': /* input file name */ 877 if (filename) 878 return (PK_ERR_USAGE); 879 filename = optarg_av; 880 break; 881 case 'k': 882 kstype = KS2Int(optarg_av); 883 if (kstype == 0) 884 return (PK_ERR_USAGE); 885 break; 886 case 'y': 887 oclass = OT2Int(optarg_av); 888 if (oclass == -1) 889 return (PK_ERR_USAGE); 890 break; 891 case 'd': 892 dir = optarg_av; 893 break; 894 case 'D': 895 keydir = optarg_av; 896 break; 897 case 'p': 898 if (prefix) 899 return (PK_ERR_USAGE); 900 prefix = optarg_av; 901 break; 902 case 'n': 903 case 'N': 904 if (label) 905 return (PK_ERR_USAGE); 906 label = optarg_av; 907 break; 908 case 'F': 909 okfmt = Str2Format(optarg_av); 910 if (okfmt == KMF_FORMAT_UNDEF) 911 return (PK_ERR_USAGE); 912 break; 913 case 't': 914 if (trustflags) 915 return (PK_ERR_USAGE); 916 trustflags = optarg_av; 917 break; 918 case 'v': 919 verify_crl = optarg_av; 920 if (tolower(verify_crl[0]) == 'y') 921 verify_crl_flag = B_TRUE; 922 else if (tolower(verify_crl[0]) == 'n') 923 verify_crl_flag = B_FALSE; 924 else 925 return (PK_ERR_USAGE); 926 break; 927 case 'E': 928 keytype = optarg_av; 929 break; 930 case 's': 931 if (senstr) 932 return (PK_ERR_USAGE); 933 senstr = optarg_av; 934 break; 935 case 'x': 936 if (extstr) 937 return (PK_ERR_USAGE); 938 extstr = optarg_av; 939 break; 940 default: 941 return (PK_ERR_USAGE); 942 break; 943 } 944 } 945 946 /* Assume keystore = PKCS#11 if not specified */ 947 if (kstype == 0) 948 kstype = KMF_KEYSTORE_PK11TOKEN; 949 950 /* Filename arg is required. */ 951 if (EMPTYSTRING(filename)) { 952 cryptoerror(LOG_STDERR, gettext("The 'infile' parameter" 953 "is required for the import operation.\n")); 954 return (PK_ERR_USAGE); 955 } 956 957 /* No additional args allowed. */ 958 argc -= optind_av; 959 argv += optind_av; 960 if (argc) 961 return (PK_ERR_USAGE); 962 963 /* if PUBLIC or PRIVATE obj was given, the old syntax was used. */ 964 if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) && 965 kstype != KMF_KEYSTORE_PK11TOKEN) { 966 967 (void) fprintf(stderr, gettext("The objtype parameter " 968 "is only relevant if keystore=pkcs11\n")); 969 return (PK_ERR_USAGE); 970 } 971 972 /* 973 * You must specify a certlabel (cert label) when importing 974 * into NSS or PKCS#11. 975 */ 976 if (kstype == KMF_KEYSTORE_NSS && 977 (oclass != PK_CRL_OBJ) && EMPTYSTRING(label)) { 978 cryptoerror(LOG_STDERR, gettext("The 'label' argument " 979 "is required for this operation\n")); 980 return (PK_ERR_USAGE); 981 } 982 983 if ((rv = kmf_get_file_format(filename, &kfmt)) != KMF_OK) { 984 /* 985 * Allow for raw key data to be imported. 986 */ 987 if (rv == KMF_ERR_ENCODING) { 988 rv = KMF_OK; 989 kfmt = KMF_FORMAT_RAWKEY; 990 /* 991 * Set the object class only if it was not 992 * given on the command line or if it was 993 * specified as a symmetric key object. 994 */ 995 if (oclass == 0 || (oclass & PK_SYMKEY_OBJ)) { 996 oclass = PK_SYMKEY_OBJ; 997 } else { 998 cryptoerror(LOG_STDERR, gettext( 999 "The input file does not contain the " 1000 "object type indicated on command " 1001 "line.")); 1002 return (KMF_ERR_BAD_PARAMETER); 1003 } 1004 } else { 1005 cryptoerror(LOG_STDERR, 1006 gettext("File format not recognized.")); 1007 return (rv); 1008 } 1009 } 1010 1011 /* Check parameters for raw key import operation */ 1012 if (kfmt == KMF_FORMAT_RAWKEY) { 1013 if (keytype != NULL && 1014 Str2SymKeyType(keytype, &keyAlg) != 0) { 1015 cryptoerror(LOG_STDERR, 1016 gettext("Unrecognized keytype(%s).\n"), keytype); 1017 return (PK_ERR_USAGE); 1018 } 1019 if (senstr != NULL && extstr != NULL && 1020 kstype != KMF_KEYSTORE_PK11TOKEN) { 1021 cryptoerror(LOG_STDERR, 1022 gettext("The sensitive or extractable option " 1023 "applies only when importing a key from a file " 1024 "into a PKCS#11 keystore.\n")); 1025 return (PK_ERR_USAGE); 1026 } 1027 } 1028 1029 /* If no objtype was given, treat it as a certificate */ 1030 if (oclass == 0 && (kfmt == KMF_FORMAT_ASN1 || 1031 kfmt == KMF_FORMAT_PEM)) 1032 oclass = PK_CERT_OBJ; 1033 1034 if (kstype == KMF_KEYSTORE_NSS) { 1035 if (oclass == PK_CRL_OBJ && 1036 (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) { 1037 cryptoerror(LOG_STDERR, gettext( 1038 "CRL data can only be imported as DER or " 1039 "PEM format")); 1040 return (PK_ERR_USAGE); 1041 } 1042 1043 if (oclass == PK_CERT_OBJ && 1044 (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) { 1045 cryptoerror(LOG_STDERR, gettext( 1046 "Certificates can only be imported as DER or " 1047 "PEM format")); 1048 return (PK_ERR_USAGE); 1049 } 1050 1051 /* we do not import private keys except in PKCS12 bundles */ 1052 if (oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)) { 1053 cryptoerror(LOG_STDERR, gettext( 1054 "Private key data can only be imported as part " 1055 "of a PKCS12 file.\n")); 1056 return (PK_ERR_USAGE); 1057 } 1058 } 1059 1060 if (kstype == KMF_KEYSTORE_OPENSSL && oclass != PK_CRL_OBJ) { 1061 if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) { 1062 cryptoerror(LOG_STDERR, gettext( 1063 "The 'outkey' and 'outcert' parameters " 1064 "are required for the import operation " 1065 "when the 'file' keystore is used.\n")); 1066 return (PK_ERR_USAGE); 1067 } 1068 } 1069 1070 if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) 1071 token_spec = PK_DEFAULT_PK11TOKEN; 1072 else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) 1073 token_spec = DEFAULT_NSS_TOKEN; 1074 1075 if (kfmt == KMF_FORMAT_PKCS12) { 1076 (void) get_pk12_password(&pk12cred); 1077 } 1078 1079 if ((kfmt == KMF_FORMAT_PKCS12 || kfmt == KMF_FORMAT_RAWKEY || 1080 (kfmt == KMF_FORMAT_PEM && (oclass & PK_KEY_OBJ))) && 1081 (kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS)) { 1082 (void) get_token_password(kstype, token_spec, &tokencred); 1083 } 1084 1085 if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 1086 cryptoerror(LOG_STDERR, gettext("Error initializing " 1087 "KMF: 0x%02x\n"), rv); 1088 goto end; 1089 } 1090 1091 switch (kstype) { 1092 case KMF_KEYSTORE_PK11TOKEN: 1093 if (kfmt == KMF_FORMAT_PKCS12) 1094 rv = pk_import_pk12_pk11( 1095 kmfhandle, &pk12cred, 1096 &tokencred, label, 1097 token_spec, filename); 1098 else if (oclass == PK_CERT_OBJ) 1099 rv = pk_import_cert( 1100 kmfhandle, kstype, 1101 label, token_spec, 1102 filename, 1103 NULL, NULL, NULL); 1104 else if (oclass == PK_CRL_OBJ) 1105 rv = pk_import_file_crl( 1106 kmfhandle, filename, 1107 crlfile, dir, okfmt); 1108 else if (kfmt == KMF_FORMAT_RAWKEY && 1109 oclass == PK_SYMKEY_OBJ) { 1110 rv = pk_import_rawkey(kmfhandle, 1111 kstype, token_spec, &tokencred, 1112 filename, label, 1113 keyAlg, senstr, extstr); 1114 } else if (kfmt == KMF_FORMAT_PEM || 1115 kfmt == KMF_FORMAT_PEM_KEYPAIR) { 1116 rv = pk_import_keys(kmfhandle, 1117 kstype, token_spec, &tokencred, 1118 filename, label, senstr, extstr); 1119 } else { 1120 rv = PK_ERR_USAGE; 1121 } 1122 break; 1123 case KMF_KEYSTORE_NSS: 1124 if (dir == NULL) 1125 dir = PK_DEFAULT_DIRECTORY; 1126 if (kfmt == KMF_FORMAT_PKCS12) 1127 rv = pk_import_pk12_nss( 1128 kmfhandle, &pk12cred, 1129 &tokencred, 1130 token_spec, dir, prefix, 1131 label, trustflags, filename); 1132 else if (oclass == PK_CERT_OBJ) { 1133 rv = pk_import_cert( 1134 kmfhandle, kstype, 1135 label, token_spec, 1136 filename, dir, prefix, trustflags); 1137 } else if (oclass == PK_CRL_OBJ) { 1138 rv = pk_import_nss_crl( 1139 kmfhandle, verify_crl_flag, 1140 filename, dir, prefix); 1141 } 1142 break; 1143 case KMF_KEYSTORE_OPENSSL: 1144 if (kfmt == KMF_FORMAT_PKCS12) 1145 rv = pk_import_pk12_files( 1146 kmfhandle, &pk12cred, 1147 filename, certfile, keyfile, 1148 dir, keydir, okfmt); 1149 else if (oclass == PK_CRL_OBJ) { 1150 rv = pk_import_file_crl( 1151 kmfhandle, filename, 1152 crlfile, dir, okfmt); 1153 } else 1154 /* 1155 * It doesn't make sense to import anything 1156 * else for the files plugin. 1157 */ 1158 return (PK_ERR_USAGE); 1159 break; 1160 default: 1161 rv = PK_ERR_USAGE; 1162 break; 1163 } 1164 1165 end: 1166 if (rv != KMF_OK) 1167 display_error(kmfhandle, rv, 1168 gettext("Error importing objects")); 1169 1170 if (tokencred.cred != NULL) 1171 free(tokencred.cred); 1172 1173 if (pk12cred.cred != NULL) 1174 free(pk12cred.cred); 1175 1176 (void) kmf_finalize(kmfhandle); 1177 1178 if (rv != KMF_OK) 1179 return (PK_ERR_USAGE); 1180 1181 return (0); 1182 } 1183