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