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