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 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 int i = 0; 380 381 if (kstype == KMF_KEYSTORE_PK11TOKEN) { 382 rv = select_token(kmfhandle, token_spec, FALSE); 383 } else if (kstype == KMF_KEYSTORE_NSS) { 384 rv = configure_nss(kmfhandle, dir, prefix); 385 } 386 if (rv != KMF_OK) 387 return (rv); 388 389 kmf_set_attr_at_index(attrlist, i, 390 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (KMF_KEYSTORE_TYPE)); 391 i++; 392 393 kmf_set_attr_at_index(attrlist, i, KMF_CERT_FILENAME_ATTR, 394 filename, strlen(filename)); 395 i++; 396 397 if (label != NULL) { 398 kmf_set_attr_at_index(attrlist, i, KMF_CERT_LABEL_ATTR, 399 label, strlen(label)); 400 i++; 401 } 402 403 if (kstype == KMF_KEYSTORE_NSS) { 404 if (trustflags != NULL) { 405 kmf_set_attr_at_index(attrlist, i, KMF_TRUSTFLAG_ATTR, 406 trustflags, strlen(trustflags)); 407 i++; 408 } 409 410 if (token_spec != NULL) { 411 kmf_set_attr_at_index(attrlist, i, 412 KMF_TOKEN_LABEL_ATTR, 413 token_spec, strlen(token_spec)); 414 i++; 415 } 416 } 417 418 rv = kmf_import_cert(kmfhandle, i, attrlist); 419 return (rv); 420 } 421 422 static KMF_RETURN 423 pk_import_file_crl(void *kmfhandle, 424 char *infile, 425 char *outfile, 426 char *outdir, 427 KMF_ENCODE_FORMAT outfmt) 428 { 429 int numattr = 0; 430 KMF_ATTRIBUTE attrlist[8]; 431 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 432 433 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 434 &kstype, sizeof (kstype)); 435 numattr++; 436 if (infile) { 437 kmf_set_attr_at_index(attrlist, numattr, 438 KMF_CRL_FILENAME_ATTR, infile, strlen(infile)); 439 numattr++; 440 } 441 if (outdir) { 442 kmf_set_attr_at_index(attrlist, numattr, 443 KMF_DIRPATH_ATTR, outdir, strlen(outdir)); 444 numattr++; 445 } 446 if (outfile) { 447 kmf_set_attr_at_index(attrlist, numattr, 448 KMF_CRL_OUTFILE_ATTR, outfile, strlen(outfile)); 449 numattr++; 450 } 451 kmf_set_attr_at_index(attrlist, numattr, 452 KMF_ENCODE_FORMAT_ATTR, &outfmt, sizeof (outfmt)); 453 numattr++; 454 455 return (kmf_import_crl(kmfhandle, numattr, attrlist)); 456 } 457 458 static KMF_RETURN 459 pk_import_nss_crl(void *kmfhandle, 460 boolean_t verify_crl_flag, 461 char *infile, 462 char *outdir, 463 char *prefix) 464 { 465 KMF_RETURN rv; 466 int numattr = 0; 467 KMF_ATTRIBUTE attrlist[4]; 468 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; 469 470 rv = configure_nss(kmfhandle, outdir, prefix); 471 if (rv != KMF_OK) 472 return (rv); 473 474 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 475 &kstype, sizeof (kstype)); 476 numattr++; 477 if (infile) { 478 kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_FILENAME_ATTR, 479 infile, strlen(infile)); 480 numattr++; 481 } 482 kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_CHECK_ATTR, 483 &verify_crl_flag, sizeof (verify_crl_flag)); 484 numattr++; 485 486 return (kmf_import_crl(kmfhandle, numattr, attrlist)); 487 488 } 489 490 static KMF_RETURN 491 pk_import_pk12_pk11( 492 KMF_HANDLE_T kmfhandle, 493 KMF_CREDENTIAL *p12cred, 494 KMF_CREDENTIAL *tokencred, 495 char *label, char *token_spec, 496 char *filename) 497 { 498 KMF_RETURN rv = KMF_OK; 499 KMF_X509_DER_CERT *certs = NULL; 500 KMF_RAW_KEY_DATA *keys = NULL; 501 int ncerts = 0; 502 int nkeys = 0; 503 int i; 504 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 505 KMF_ATTRIBUTE *attrlist = NULL; 506 int numattr = 0; 507 508 rv = select_token(kmfhandle, token_spec, FALSE); 509 510 if (rv != KMF_OK) { 511 return (rv); 512 } 513 514 rv = kmf_import_objects(kmfhandle, filename, p12cred, 515 &certs, &ncerts, &keys, &nkeys); 516 517 if (rv == KMF_OK) { 518 NEW_ATTRLIST(attrlist, (3 + (2 * nkeys))); 519 520 kmf_set_attr_at_index(attrlist, numattr, 521 KMF_KEYSTORE_TYPE_ATTR, &kstype, 522 sizeof (kstype)); 523 numattr++; 524 525 if (label != NULL) { 526 kmf_set_attr_at_index(attrlist, numattr, 527 KMF_KEYLABEL_ATTR, label, 528 strlen(label)); 529 numattr++; 530 } 531 532 if (tokencred != NULL && tokencred->credlen > 0) { 533 kmf_set_attr_at_index(attrlist, numattr, 534 KMF_CREDENTIAL_ATTR, tokencred, 535 sizeof (KMF_CREDENTIAL)); 536 numattr++; 537 } 538 539 /* The order of certificates and keys should match */ 540 for (i = 0; i < nkeys; i++) { 541 int num = numattr; 542 543 if (i < ncerts) { 544 kmf_set_attr_at_index(attrlist, num, 545 KMF_CERT_DATA_ATTR, &certs[i].certificate, 546 sizeof (KMF_DATA)); 547 num++; 548 } 549 550 kmf_set_attr_at_index(attrlist, num, 551 KMF_RAW_KEY_ATTR, &keys[i], 552 sizeof (KMF_RAW_KEY_DATA)); 553 num++; 554 555 rv = kmf_store_key(kmfhandle, num, attrlist); 556 557 } 558 free(attrlist); 559 } 560 561 if (rv == KMF_OK) { 562 numattr = 0; 563 NEW_ATTRLIST(attrlist, (1 + (2 * ncerts))); 564 565 (void) printf(gettext("Found %d certificate(s) and %d " 566 "key(s) in %s\n"), ncerts, nkeys, filename); 567 568 kmf_set_attr_at_index(attrlist, numattr, 569 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 570 numattr++; 571 572 for (i = 0; rv == KMF_OK && i < ncerts; i++) { 573 int num = numattr; 574 if (certs[i].kmf_private.label != NULL) { 575 kmf_set_attr_at_index(attrlist, num, 576 KMF_CERT_LABEL_ATTR, 577 certs[i].kmf_private.label, 578 strlen(certs[i].kmf_private.label)); 579 num++; 580 } else if (i == 0 && label != NULL) { 581 kmf_set_attr_at_index(attrlist, num, 582 KMF_CERT_LABEL_ATTR, label, strlen(label)); 583 num++; 584 } 585 586 kmf_set_attr_at_index(attrlist, num, 587 KMF_CERT_DATA_ATTR, &certs[i].certificate, 588 sizeof (KMF_DATA)); 589 num++; 590 591 rv = kmf_store_cert(kmfhandle, num, attrlist); 592 } 593 free(attrlist); 594 } 595 596 end: 597 /* 598 * Cleanup memory. 599 */ 600 if (certs) { 601 for (i = 0; i < ncerts; i++) 602 kmf_free_kmf_cert(kmfhandle, &certs[i]); 603 free(certs); 604 } 605 if (keys) { 606 for (i = 0; i < nkeys; i++) 607 kmf_free_raw_key(&keys[i]); 608 free(keys); 609 } 610 611 return (rv); 612 } 613 614 /*ARGSUSED*/ 615 static KMF_RETURN 616 pk_import_keys(KMF_HANDLE_T kmfhandle, 617 KMF_KEYSTORE_TYPE kstype, char *token_spec, 618 KMF_CREDENTIAL *cred, char *filename, 619 char *label, char *senstr, char *extstr) 620 { 621 KMF_RETURN rv = KMF_OK; 622 KMF_ATTRIBUTE attrlist[16]; 623 KMF_KEYSTORE_TYPE fileks = KMF_KEYSTORE_OPENSSL; 624 int numattr = 0; 625 KMF_KEY_HANDLE key; 626 KMF_RAW_KEY_DATA rawkey; 627 KMF_KEY_CLASS class = KMF_ASYM_PRI; 628 int numkeys = 1; 629 630 if (kstype == KMF_KEYSTORE_PK11TOKEN) { 631 rv = select_token(kmfhandle, token_spec, FALSE); 632 } 633 if (rv != KMF_OK) 634 return (rv); 635 /* 636 * First, set up to read the keyfile using the FILE plugin 637 * mechanisms. 638 */ 639 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 640 &fileks, sizeof (fileks)); 641 numattr++; 642 643 kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, 644 &numkeys, sizeof (numkeys)); 645 numattr++; 646 647 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 648 &key, sizeof (key)); 649 numattr++; 650 651 kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR, 652 &rawkey, sizeof (rawkey)); 653 numattr++; 654 655 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR, 656 &class, sizeof (class)); 657 numattr++; 658 659 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR, 660 filename, strlen(filename)); 661 numattr++; 662 663 rv = kmf_find_key(kmfhandle, numattr, attrlist); 664 if (rv == KMF_OK) { 665 numattr = 0; 666 667 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 668 &kstype, sizeof (kstype)); 669 numattr++; 670 671 if (cred != NULL && cred->credlen > 0) { 672 kmf_set_attr_at_index(attrlist, numattr, 673 KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL)); 674 numattr++; 675 } 676 677 if (label != NULL) { 678 kmf_set_attr_at_index(attrlist, numattr, 679 KMF_KEYLABEL_ATTR, label, strlen(label)); 680 numattr++; 681 } 682 683 kmf_set_attr_at_index(attrlist, numattr, 684 KMF_RAW_KEY_ATTR, &rawkey, sizeof (rawkey)); 685 numattr++; 686 687 rv = kmf_store_key(kmfhandle, numattr, attrlist); 688 if (rv == KMF_OK) { 689 (void) printf(gettext("Importing %d keys\n"), numkeys); 690 } 691 692 kmf_free_kmf_key(kmfhandle, &key); 693 kmf_free_raw_key(&rawkey); 694 } else { 695 cryptoerror(LOG_STDERR, 696 gettext("Failed to load key from file (%s)\n"), 697 filename); 698 } 699 return (rv); 700 } 701 702 static KMF_RETURN 703 pk_import_rawkey(KMF_HANDLE_T kmfhandle, 704 KMF_KEYSTORE_TYPE kstype, char *token, 705 KMF_CREDENTIAL *cred, 706 char *filename, char *label, KMF_KEY_ALG keyAlg, 707 char *senstr, char *extstr) 708 { 709 KMF_RETURN rv = KMF_OK; 710 KMF_ATTRIBUTE attrlist[16]; 711 int numattr = 0; 712 uint32_t keylen; 713 boolean_t sensitive = B_FALSE; 714 boolean_t not_extractable = B_FALSE; 715 KMF_DATA keydata = {NULL, 0}; 716 KMF_KEY_HANDLE rawkey; 717 718 rv = kmf_read_input_file(kmfhandle, filename, &keydata); 719 if (rv != KMF_OK) 720 return (rv); 721 722 rv = select_token(kmfhandle, token, FALSE); 723 724 if (rv != KMF_OK) { 725 return (rv); 726 } 727 if (senstr != NULL) { 728 if (tolower(senstr[0]) == 'y') 729 sensitive = B_TRUE; 730 else if (tolower(senstr[0]) == 'n') 731 sensitive = B_FALSE; 732 else { 733 cryptoerror(LOG_STDERR, 734 gettext("Incorrect sensitive option value.\n")); 735 return (KMF_ERR_BAD_PARAMETER); 736 } 737 } 738 739 if (extstr != NULL) { 740 if (tolower(extstr[0]) == 'y') 741 not_extractable = B_FALSE; 742 else if (tolower(extstr[0]) == 'n') 743 not_extractable = B_TRUE; 744 else { 745 cryptoerror(LOG_STDERR, 746 gettext("Incorrect extractable option value.\n")); 747 return (KMF_ERR_BAD_PARAMETER); 748 } 749 } 750 kmf_set_attr_at_index(attrlist, numattr, 751 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 752 numattr++; 753 754 kmf_set_attr_at_index(attrlist, numattr, 755 KMF_KEY_HANDLE_ATTR, &rawkey, sizeof (rawkey)); 756 numattr++; 757 758 kmf_set_attr_at_index(attrlist, numattr, 759 KMF_KEYALG_ATTR, &keyAlg, sizeof (KMF_KEY_ALG)); 760 numattr++; 761 762 kmf_set_attr_at_index(attrlist, numattr, 763 KMF_KEY_DATA_ATTR, keydata.Data, keydata.Length); 764 numattr++; 765 766 /* Key length is given in bits not bytes */ 767 keylen = keydata.Length * 8; 768 kmf_set_attr_at_index(attrlist, numattr, 769 KMF_KEYLENGTH_ATTR, &keylen, sizeof (keydata.Length)); 770 numattr++; 771 772 kmf_set_attr_at_index(attrlist, numattr, 773 KMF_SENSITIVE_BOOL_ATTR, &sensitive, sizeof (sensitive)); 774 numattr++; 775 776 kmf_set_attr_at_index(attrlist, numattr, 777 KMF_NON_EXTRACTABLE_BOOL_ATTR, ¬_extractable, 778 sizeof (not_extractable)); 779 numattr++; 780 781 if (label != NULL) { 782 kmf_set_attr_at_index(attrlist, numattr, 783 KMF_KEYLABEL_ATTR, label, strlen(label)); 784 numattr++; 785 } 786 if (cred != NULL && cred->credlen > 0) { 787 kmf_set_attr_at_index(attrlist, numattr, 788 KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL)); 789 numattr++; 790 } 791 rv = kmf_create_sym_key(kmfhandle, numattr, attrlist); 792 793 return (rv); 794 } 795 796 /* 797 * Import objects from into KMF repositories. 798 */ 799 int 800 pk_import(int argc, char *argv[]) 801 { 802 int opt; 803 extern int optind_av; 804 extern char *optarg_av; 805 char *token_spec = NULL; 806 char *filename = NULL; 807 char *keyfile = NULL; 808 char *certfile = NULL; 809 char *crlfile = NULL; 810 char *label = NULL; 811 char *dir = NULL; 812 char *keydir = NULL; 813 char *prefix = NULL; 814 char *trustflags = NULL; 815 char *verify_crl = NULL; 816 char *keytype = "generic"; 817 char *senstr = NULL; 818 char *extstr = NULL; 819 boolean_t verify_crl_flag = B_FALSE; 820 int oclass = 0; 821 KMF_KEYSTORE_TYPE kstype = 0; 822 KMF_ENCODE_FORMAT kfmt = 0; 823 KMF_ENCODE_FORMAT okfmt = KMF_FORMAT_ASN1; 824 KMF_RETURN rv = KMF_OK; 825 KMF_CREDENTIAL pk12cred = { NULL, 0 }; 826 KMF_CREDENTIAL tokencred = { NULL, 0 }; 827 KMF_HANDLE_T kmfhandle = NULL; 828 KMF_KEY_ALG keyAlg = KMF_GENERIC_SECRET; 829 830 /* Parse command line options. Do NOT i18n/l10n. */ 831 while ((opt = getopt_av(argc, argv, 832 "T:(token)i:(infile)" 833 "k:(keystore)y:(objtype)" 834 "d:(dir)p:(prefix)" 835 "n:(certlabel)N:(label)" 836 "K:(outkey)c:(outcert)" 837 "v:(verifycrl)l:(outcrl)" 838 "E:(keytype)s:(sensitive)x:(extractable)" 839 "t:(trust)D:(keydir)F:(outformat)")) != EOF) { 840 if (EMPTYSTRING(optarg_av)) 841 return (PK_ERR_USAGE); 842 switch (opt) { 843 case 'T': /* token specifier */ 844 if (token_spec) 845 return (PK_ERR_USAGE); 846 token_spec = optarg_av; 847 break; 848 case 'c': /* output cert file name */ 849 if (certfile) 850 return (PK_ERR_USAGE); 851 certfile = optarg_av; 852 break; 853 case 'l': /* output CRL file name */ 854 if (crlfile) 855 return (PK_ERR_USAGE); 856 crlfile = optarg_av; 857 break; 858 case 'K': /* output key file name */ 859 if (keyfile) 860 return (PK_ERR_USAGE); 861 keyfile = optarg_av; 862 break; 863 case 'i': /* input file name */ 864 if (filename) 865 return (PK_ERR_USAGE); 866 filename = optarg_av; 867 break; 868 case 'k': 869 kstype = KS2Int(optarg_av); 870 if (kstype == 0) 871 return (PK_ERR_USAGE); 872 break; 873 case 'y': 874 oclass = OT2Int(optarg_av); 875 if (oclass == -1) 876 return (PK_ERR_USAGE); 877 break; 878 case 'd': 879 dir = optarg_av; 880 break; 881 case 'D': 882 keydir = optarg_av; 883 break; 884 case 'p': 885 if (prefix) 886 return (PK_ERR_USAGE); 887 prefix = optarg_av; 888 break; 889 case 'n': 890 case 'N': 891 if (label) 892 return (PK_ERR_USAGE); 893 label = optarg_av; 894 break; 895 case 'F': 896 okfmt = Str2Format(optarg_av); 897 if (okfmt == KMF_FORMAT_UNDEF) 898 return (PK_ERR_USAGE); 899 break; 900 case 't': 901 if (trustflags) 902 return (PK_ERR_USAGE); 903 trustflags = optarg_av; 904 break; 905 case 'v': 906 verify_crl = optarg_av; 907 if (tolower(verify_crl[0]) == 'y') 908 verify_crl_flag = B_TRUE; 909 else if (tolower(verify_crl[0]) == 'n') 910 verify_crl_flag = B_FALSE; 911 else 912 return (PK_ERR_USAGE); 913 break; 914 case 'E': 915 keytype = optarg_av; 916 break; 917 case 's': 918 if (senstr) 919 return (PK_ERR_USAGE); 920 senstr = optarg_av; 921 break; 922 case 'x': 923 if (extstr) 924 return (PK_ERR_USAGE); 925 extstr = optarg_av; 926 break; 927 default: 928 return (PK_ERR_USAGE); 929 break; 930 } 931 } 932 933 /* Assume keystore = PKCS#11 if not specified */ 934 if (kstype == 0) 935 kstype = KMF_KEYSTORE_PK11TOKEN; 936 937 /* Filename arg is required. */ 938 if (EMPTYSTRING(filename)) { 939 cryptoerror(LOG_STDERR, gettext("The 'infile' parameter" 940 "is required for the import operation.\n")); 941 return (PK_ERR_USAGE); 942 } 943 944 /* No additional args allowed. */ 945 argc -= optind_av; 946 argv += optind_av; 947 if (argc) 948 return (PK_ERR_USAGE); 949 950 /* if PUBLIC or PRIVATE obj was given, the old syntax was used. */ 951 if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) && 952 kstype != KMF_KEYSTORE_PK11TOKEN) { 953 954 (void) fprintf(stderr, gettext("The objtype parameter " 955 "is only relevant if keystore=pkcs11\n")); 956 return (PK_ERR_USAGE); 957 } 958 959 /* 960 * You must specify a certlabel (cert label) when importing 961 * into NSS or PKCS#11. 962 */ 963 if (kstype == KMF_KEYSTORE_NSS && 964 (oclass != PK_CRL_OBJ) && EMPTYSTRING(label)) { 965 cryptoerror(LOG_STDERR, gettext("The 'label' argument " 966 "is required for this operation\n")); 967 return (PK_ERR_USAGE); 968 } 969 970 if ((rv = kmf_get_file_format(filename, &kfmt)) != KMF_OK) { 971 /* 972 * Allow for raw key data to be imported. 973 */ 974 if (rv == KMF_ERR_ENCODING) { 975 rv = KMF_OK; 976 kfmt = KMF_FORMAT_RAWKEY; 977 /* 978 * Set the object class only if it was not 979 * given on the command line or if it was 980 * specified as a symmetric key object. 981 */ 982 if (oclass == 0 || (oclass & PK_SYMKEY_OBJ)) { 983 oclass = PK_SYMKEY_OBJ; 984 } else { 985 cryptoerror(LOG_STDERR, gettext( 986 "The input file does not contain the " 987 "object type indicated on command " 988 "line.")); 989 return (KMF_ERR_BAD_PARAMETER); 990 } 991 } else { 992 cryptoerror(LOG_STDERR, 993 gettext("File format not recognized.")); 994 return (rv); 995 } 996 } 997 998 /* Check parameters for raw key import operation */ 999 if (kfmt == KMF_FORMAT_RAWKEY) { 1000 if (keytype != NULL && 1001 Str2SymKeyType(keytype, &keyAlg) != 0) { 1002 cryptoerror(LOG_STDERR, 1003 gettext("Unrecognized keytype(%s).\n"), keytype); 1004 return (PK_ERR_USAGE); 1005 } 1006 if (senstr != NULL && extstr != NULL && 1007 kstype != KMF_KEYSTORE_PK11TOKEN) { 1008 cryptoerror(LOG_STDERR, 1009 gettext("The sensitive or extractable option " 1010 "applies only when importing a key from a file " 1011 "into a PKCS#11 keystore.\n")); 1012 return (PK_ERR_USAGE); 1013 } 1014 } 1015 1016 /* If no objtype was given, treat it as a certificate */ 1017 if (oclass == 0 && (kfmt == KMF_FORMAT_ASN1 || 1018 kfmt == KMF_FORMAT_PEM)) 1019 oclass = PK_CERT_OBJ; 1020 1021 if (kstype == KMF_KEYSTORE_NSS) { 1022 if (oclass == PK_CRL_OBJ && 1023 (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) { 1024 cryptoerror(LOG_STDERR, gettext( 1025 "CRL data can only be imported as DER or " 1026 "PEM format")); 1027 return (PK_ERR_USAGE); 1028 } 1029 1030 if (oclass == PK_CERT_OBJ && 1031 (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) { 1032 cryptoerror(LOG_STDERR, gettext( 1033 "Certificates can only be imported as DER or " 1034 "PEM format")); 1035 return (PK_ERR_USAGE); 1036 } 1037 1038 /* we do not import private keys except in PKCS12 bundles */ 1039 if (oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)) { 1040 cryptoerror(LOG_STDERR, gettext( 1041 "Private key data can only be imported as part " 1042 "of a PKCS12 file.\n")); 1043 return (PK_ERR_USAGE); 1044 } 1045 } 1046 1047 if (kstype == KMF_KEYSTORE_OPENSSL && oclass != PK_CRL_OBJ) { 1048 if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) { 1049 cryptoerror(LOG_STDERR, gettext( 1050 "The 'outkey' and 'outcert' parameters " 1051 "are required for the import operation " 1052 "when the 'file' keystore is used.\n")); 1053 return (PK_ERR_USAGE); 1054 } 1055 } 1056 1057 if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) 1058 token_spec = PK_DEFAULT_PK11TOKEN; 1059 else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) 1060 token_spec = DEFAULT_NSS_TOKEN; 1061 1062 if (kfmt == KMF_FORMAT_PKCS12) { 1063 (void) get_pk12_password(&pk12cred); 1064 } 1065 1066 if ((kfmt == KMF_FORMAT_PKCS12 || kfmt == KMF_FORMAT_RAWKEY || 1067 (kfmt == KMF_FORMAT_PEM && (oclass & PK_KEY_OBJ))) && 1068 (kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS)) { 1069 (void) get_token_password(kstype, token_spec, &tokencred); 1070 } 1071 1072 if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 1073 cryptoerror(LOG_STDERR, gettext("Error initializing " 1074 "KMF: 0x%02x\n"), rv); 1075 goto end; 1076 } 1077 1078 switch (kstype) { 1079 case KMF_KEYSTORE_PK11TOKEN: 1080 if (kfmt == KMF_FORMAT_PKCS12) 1081 rv = pk_import_pk12_pk11( 1082 kmfhandle, &pk12cred, 1083 &tokencred, label, 1084 token_spec, filename); 1085 else if (oclass == PK_CERT_OBJ) 1086 rv = pk_import_cert( 1087 kmfhandle, kstype, 1088 label, token_spec, 1089 filename, 1090 NULL, NULL, NULL); 1091 else if (oclass == PK_CRL_OBJ) 1092 rv = pk_import_file_crl( 1093 kmfhandle, filename, 1094 crlfile, dir, okfmt); 1095 else if (kfmt == KMF_FORMAT_RAWKEY && 1096 oclass == PK_SYMKEY_OBJ) { 1097 rv = pk_import_rawkey(kmfhandle, 1098 kstype, token_spec, &tokencred, 1099 filename, label, 1100 keyAlg, senstr, extstr); 1101 } else if (kfmt == KMF_FORMAT_PEM || 1102 kfmt == KMF_FORMAT_PEM_KEYPAIR) { 1103 rv = pk_import_keys(kmfhandle, 1104 kstype, token_spec, &tokencred, 1105 filename, label, senstr, extstr); 1106 } else { 1107 rv = PK_ERR_USAGE; 1108 } 1109 break; 1110 case KMF_KEYSTORE_NSS: 1111 if (dir == NULL) 1112 dir = PK_DEFAULT_DIRECTORY; 1113 if (kfmt == KMF_FORMAT_PKCS12) 1114 rv = pk_import_pk12_nss( 1115 kmfhandle, &pk12cred, 1116 &tokencred, 1117 token_spec, dir, prefix, 1118 label, trustflags, filename); 1119 else if (oclass == PK_CERT_OBJ) { 1120 rv = pk_import_cert( 1121 kmfhandle, kstype, 1122 label, token_spec, 1123 filename, dir, prefix, trustflags); 1124 } else if (oclass == PK_CRL_OBJ) { 1125 rv = pk_import_nss_crl( 1126 kmfhandle, verify_crl_flag, 1127 filename, dir, prefix); 1128 } 1129 break; 1130 case KMF_KEYSTORE_OPENSSL: 1131 if (kfmt == KMF_FORMAT_PKCS12) 1132 rv = pk_import_pk12_files( 1133 kmfhandle, &pk12cred, 1134 filename, certfile, keyfile, 1135 dir, keydir, okfmt); 1136 else if (oclass == PK_CRL_OBJ) { 1137 rv = pk_import_file_crl( 1138 kmfhandle, filename, 1139 crlfile, dir, okfmt); 1140 } else 1141 /* 1142 * It doesn't make sense to import anything 1143 * else for the files plugin. 1144 */ 1145 return (PK_ERR_USAGE); 1146 break; 1147 default: 1148 rv = PK_ERR_USAGE; 1149 break; 1150 } 1151 1152 end: 1153 if (rv != KMF_OK) 1154 display_error(kmfhandle, rv, 1155 gettext("Error importing objects")); 1156 1157 if (tokencred.cred != NULL) 1158 free(tokencred.cred); 1159 1160 if (pk12cred.cred != NULL) 1161 free(pk12cred.cred); 1162 1163 (void) kmf_finalize(kmfhandle); 1164 1165 if (rv != KMF_OK) 1166 return (PK_ERR_USAGE); 1167 1168 return (0); 1169 } 1170