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 DIR_OPTION_CHECK(kstype, dir); 941 942 /* if PUBLIC or PRIVATE obj was given, the old syntax was used. */ 943 if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) && 944 kstype != KMF_KEYSTORE_PK11TOKEN) { 945 946 (void) fprintf(stderr, gettext("The objtype parameter " 947 "is only relevant if keystore=pkcs11\n")); 948 return (PK_ERR_USAGE); 949 } 950 951 /* 952 * You must specify a certlabel (cert label) when importing 953 * into NSS or PKCS#11. 954 */ 955 if (kstype == KMF_KEYSTORE_NSS && 956 (oclass != PK_CRL_OBJ) && EMPTYSTRING(label)) { 957 cryptoerror(LOG_STDERR, gettext("The 'label' argument " 958 "is required for this operation\n")); 959 return (PK_ERR_USAGE); 960 } 961 962 if ((rv = kmf_get_file_format(filename, &kfmt)) != KMF_OK) { 963 /* 964 * Allow for raw key data to be imported. 965 */ 966 if (rv == KMF_ERR_ENCODING) { 967 rv = KMF_OK; 968 kfmt = KMF_FORMAT_RAWKEY; 969 /* 970 * Set the object class only if it was not 971 * given on the command line or if it was 972 * specified as a symmetric key object. 973 */ 974 if (oclass == 0 || (oclass & PK_SYMKEY_OBJ)) { 975 oclass = PK_SYMKEY_OBJ; 976 } else { 977 cryptoerror(LOG_STDERR, gettext( 978 "The input file does not contain the " 979 "object type indicated on command " 980 "line.")); 981 return (KMF_ERR_BAD_PARAMETER); 982 } 983 } else { 984 cryptoerror(LOG_STDERR, 985 gettext("File format not recognized.")); 986 return (rv); 987 } 988 } 989 990 /* Check parameters for raw key import operation */ 991 if (kfmt == KMF_FORMAT_RAWKEY) { 992 if (keytype != NULL && 993 Str2SymKeyType(keytype, &keyAlg) != 0) { 994 cryptoerror(LOG_STDERR, 995 gettext("Unrecognized keytype(%s).\n"), keytype); 996 return (PK_ERR_USAGE); 997 } 998 if (senstr != NULL && extstr != NULL && 999 kstype != KMF_KEYSTORE_PK11TOKEN) { 1000 cryptoerror(LOG_STDERR, 1001 gettext("The sensitive or extractable option " 1002 "applies only when importing a key from a file " 1003 "into a PKCS#11 keystore.\n")); 1004 return (PK_ERR_USAGE); 1005 } 1006 } 1007 1008 /* If no objtype was given, treat it as a certificate */ 1009 if (oclass == 0 && (kfmt == KMF_FORMAT_ASN1 || 1010 kfmt == KMF_FORMAT_PEM)) 1011 oclass = PK_CERT_OBJ; 1012 1013 if (kstype == KMF_KEYSTORE_NSS) { 1014 if (oclass == PK_CRL_OBJ && 1015 (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) { 1016 cryptoerror(LOG_STDERR, gettext( 1017 "CRL data can only be imported as DER or " 1018 "PEM format")); 1019 return (PK_ERR_USAGE); 1020 } 1021 1022 if (oclass == PK_CERT_OBJ && 1023 (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) { 1024 cryptoerror(LOG_STDERR, gettext( 1025 "Certificates can only be imported as DER or " 1026 "PEM format")); 1027 return (PK_ERR_USAGE); 1028 } 1029 1030 /* we do not import private keys except in PKCS12 bundles */ 1031 if (oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)) { 1032 cryptoerror(LOG_STDERR, gettext( 1033 "Private key data can only be imported as part " 1034 "of a PKCS12 file.\n")); 1035 return (PK_ERR_USAGE); 1036 } 1037 } 1038 1039 if (kstype == KMF_KEYSTORE_OPENSSL && oclass != PK_CRL_OBJ) { 1040 if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) { 1041 cryptoerror(LOG_STDERR, gettext( 1042 "The 'outkey' and 'outcert' parameters " 1043 "are required for the import operation " 1044 "when the 'file' keystore is used.\n")); 1045 return (PK_ERR_USAGE); 1046 } 1047 } 1048 1049 if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) 1050 token_spec = PK_DEFAULT_PK11TOKEN; 1051 else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) 1052 token_spec = DEFAULT_NSS_TOKEN; 1053 1054 if (kfmt == KMF_FORMAT_PKCS12) { 1055 (void) get_pk12_password(&pk12cred); 1056 } 1057 1058 if ((kfmt == KMF_FORMAT_PKCS12 || kfmt == KMF_FORMAT_RAWKEY || 1059 (kfmt == KMF_FORMAT_PEM && (oclass & PK_KEY_OBJ))) && 1060 (kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS)) { 1061 (void) get_token_password(kstype, token_spec, &tokencred); 1062 } 1063 1064 if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 1065 cryptoerror(LOG_STDERR, gettext("Error initializing " 1066 "KMF: 0x%02x\n"), rv); 1067 goto end; 1068 } 1069 1070 switch (kstype) { 1071 case KMF_KEYSTORE_PK11TOKEN: 1072 if (kfmt == KMF_FORMAT_PKCS12) 1073 rv = pk_import_pk12_pk11( 1074 kmfhandle, &pk12cred, 1075 &tokencred, label, 1076 token_spec, filename); 1077 else if (oclass == PK_CERT_OBJ) 1078 rv = pk_import_cert( 1079 kmfhandle, kstype, 1080 label, token_spec, 1081 filename, 1082 NULL, NULL, NULL); 1083 else if (oclass == PK_CRL_OBJ) 1084 rv = pk_import_file_crl( 1085 kmfhandle, filename, 1086 crlfile, okfmt); 1087 else if (kfmt == KMF_FORMAT_RAWKEY && 1088 oclass == PK_SYMKEY_OBJ) { 1089 rv = pk_import_rawkey(kmfhandle, 1090 kstype, token_spec, &tokencred, 1091 filename, label, 1092 keyAlg, senstr, extstr); 1093 } else if (kfmt == KMF_FORMAT_PEM || 1094 kfmt == KMF_FORMAT_PEM_KEYPAIR) { 1095 rv = pk_import_keys(kmfhandle, 1096 kstype, token_spec, &tokencred, 1097 filename, label, senstr, extstr); 1098 } else { 1099 rv = PK_ERR_USAGE; 1100 } 1101 break; 1102 case KMF_KEYSTORE_NSS: 1103 if (dir == NULL) 1104 dir = PK_DEFAULT_DIRECTORY; 1105 if (kfmt == KMF_FORMAT_PKCS12) 1106 rv = pk_import_pk12_nss( 1107 kmfhandle, &pk12cred, 1108 &tokencred, 1109 token_spec, dir, prefix, 1110 label, trustflags, filename); 1111 else if (oclass == PK_CERT_OBJ) { 1112 rv = pk_import_cert( 1113 kmfhandle, kstype, 1114 label, token_spec, 1115 filename, dir, prefix, trustflags); 1116 } else if (oclass == PK_CRL_OBJ) { 1117 rv = pk_import_nss_crl( 1118 kmfhandle, verify_crl_flag, 1119 filename, dir, prefix); 1120 } 1121 break; 1122 case KMF_KEYSTORE_OPENSSL: 1123 if (kfmt == KMF_FORMAT_PKCS12) 1124 rv = pk_import_pk12_files( 1125 kmfhandle, &pk12cred, 1126 filename, certfile, keyfile, 1127 okfmt); 1128 else if (oclass == PK_CRL_OBJ) { 1129 rv = pk_import_file_crl( 1130 kmfhandle, filename, 1131 crlfile, okfmt); 1132 } else 1133 /* 1134 * It doesn't make sense to import anything 1135 * else for the files plugin. 1136 */ 1137 return (PK_ERR_USAGE); 1138 break; 1139 default: 1140 rv = PK_ERR_USAGE; 1141 break; 1142 } 1143 1144 end: 1145 if (rv != KMF_OK) 1146 display_error(kmfhandle, rv, 1147 gettext("Error importing objects")); 1148 1149 if (tokencred.cred != NULL) 1150 free(tokencred.cred); 1151 1152 if (pk12cred.cred != NULL) 1153 free(pk12cred.cred); 1154 1155 (void) kmf_finalize(kmfhandle); 1156 1157 if (rv != KMF_OK) 1158 return (PK_ERR_USAGE); 1159 1160 return (0); 1161 } 1162