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