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 static KMF_RETURN 560 pk_import_keys(KMF_HANDLE_T kmfhandle, 561 KMF_KEYSTORE_TYPE kstype, char *token_spec, 562 KMF_CREDENTIAL *cred, char *filename, 563 char *label, char *senstr, char *extstr) 564 { 565 KMF_RETURN rv = KMF_OK; 566 KMF_ATTRIBUTE attrlist[16]; 567 KMF_KEYSTORE_TYPE fileks = KMF_KEYSTORE_OPENSSL; 568 int numattr = 0; 569 KMF_KEY_HANDLE key; 570 KMF_RAW_KEY_DATA rawkey; 571 KMF_KEY_CLASS class = KMF_ASYM_PRI; 572 int numkeys = 1; 573 574 if (kstype == KMF_KEYSTORE_PK11TOKEN) { 575 rv = select_token(kmfhandle, token_spec, FALSE); 576 } 577 if (rv != KMF_OK) 578 return (rv); 579 /* 580 * First, set up to read the keyfile using the FILE plugin 581 * mechanisms. 582 */ 583 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 584 &fileks, sizeof (fileks)); 585 numattr++; 586 587 kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, 588 &numkeys, sizeof (numkeys)); 589 numattr++; 590 591 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 592 &key, sizeof (key)); 593 numattr++; 594 595 kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR, 596 &rawkey, sizeof (rawkey)); 597 numattr++; 598 599 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR, 600 &class, sizeof (class)); 601 numattr++; 602 603 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR, 604 filename, strlen(filename)); 605 numattr++; 606 607 rv = kmf_find_key(kmfhandle, numattr, attrlist); 608 if (rv == KMF_OK) { 609 numattr = 0; 610 611 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 612 &kstype, sizeof (kstype)); 613 numattr++; 614 615 if (cred != NULL && cred->credlen > 0) { 616 kmf_set_attr_at_index(attrlist, numattr, 617 KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL)); 618 numattr++; 619 } 620 621 if (label != NULL) { 622 kmf_set_attr_at_index(attrlist, numattr, 623 KMF_KEYLABEL_ATTR, label, strlen(label)); 624 numattr++; 625 } 626 627 kmf_set_attr_at_index(attrlist, numattr, 628 KMF_RAW_KEY_ATTR, &rawkey, sizeof (rawkey)); 629 numattr++; 630 631 rv = kmf_store_key(kmfhandle, numattr, attrlist); 632 if (rv == KMF_OK) { 633 printf(gettext("Importing %d keys\n"), numkeys); 634 } 635 636 kmf_free_kmf_key(kmfhandle, &key); 637 kmf_free_raw_key(&rawkey); 638 } else { 639 cryptoerror(LOG_STDERR, 640 gettext("Failed to load key from file (%s)\n"), 641 filename); 642 } 643 return (rv); 644 } 645 646 static KMF_RETURN 647 pk_import_rawkey(KMF_HANDLE_T kmfhandle, 648 KMF_KEYSTORE_TYPE kstype, char *token, 649 KMF_CREDENTIAL *cred, 650 char *filename, char *label, KMF_KEY_ALG keyAlg, 651 char *senstr, char *extstr) 652 { 653 KMF_RETURN rv = KMF_OK; 654 KMF_ATTRIBUTE attrlist[16]; 655 int numattr = 0; 656 uint32_t keylen; 657 boolean_t sensitive = B_FALSE; 658 boolean_t not_extractable = B_FALSE; 659 KMF_DATA keydata = {NULL, 0}; 660 KMF_KEY_HANDLE rawkey; 661 662 rv = kmf_read_input_file(kmfhandle, filename, &keydata); 663 if (rv != KMF_OK) 664 return (rv); 665 666 rv = select_token(kmfhandle, token, FALSE); 667 668 if (rv != KMF_OK) { 669 return (rv); 670 } 671 if (senstr != NULL) { 672 if (tolower(senstr[0]) == 'y') 673 sensitive = B_TRUE; 674 else if (tolower(senstr[0]) == 'n') 675 sensitive = B_FALSE; 676 else { 677 cryptoerror(LOG_STDERR, 678 gettext("Incorrect sensitive option value.\n")); 679 return (KMF_ERR_BAD_PARAMETER); 680 } 681 } 682 683 if (extstr != NULL) { 684 if (tolower(extstr[0]) == 'y') 685 not_extractable = B_FALSE; 686 else if (tolower(extstr[0]) == 'n') 687 not_extractable = B_TRUE; 688 else { 689 cryptoerror(LOG_STDERR, 690 gettext("Incorrect extractable option value.\n")); 691 return (KMF_ERR_BAD_PARAMETER); 692 } 693 } 694 kmf_set_attr_at_index(attrlist, numattr, 695 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 696 numattr++; 697 698 kmf_set_attr_at_index(attrlist, numattr, 699 KMF_KEY_HANDLE_ATTR, &rawkey, sizeof (rawkey)); 700 numattr++; 701 702 kmf_set_attr_at_index(attrlist, numattr, 703 KMF_KEYALG_ATTR, &keyAlg, sizeof (KMF_KEY_ALG)); 704 numattr++; 705 706 kmf_set_attr_at_index(attrlist, numattr, 707 KMF_KEY_DATA_ATTR, keydata.Data, keydata.Length); 708 numattr++; 709 710 /* Key length is given in bits not bytes */ 711 keylen = keydata.Length * 8; 712 kmf_set_attr_at_index(attrlist, numattr, 713 KMF_KEYLENGTH_ATTR, &keylen, sizeof (keydata.Length)); 714 numattr++; 715 716 kmf_set_attr_at_index(attrlist, numattr, 717 KMF_SENSITIVE_BOOL_ATTR, &sensitive, sizeof (sensitive)); 718 numattr++; 719 720 kmf_set_attr_at_index(attrlist, numattr, 721 KMF_NON_EXTRACTABLE_BOOL_ATTR, ¬_extractable, 722 sizeof (not_extractable)); 723 numattr++; 724 725 if (label != NULL) { 726 kmf_set_attr_at_index(attrlist, numattr, 727 KMF_KEYLABEL_ATTR, label, strlen(label)); 728 numattr++; 729 } 730 if (cred != NULL && cred->credlen > 0) { 731 kmf_set_attr_at_index(attrlist, numattr, 732 KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL)); 733 numattr++; 734 } 735 rv = kmf_create_sym_key(kmfhandle, numattr, attrlist); 736 737 return (rv); 738 } 739 740 /* 741 * Import objects from into KMF repositories. 742 */ 743 int 744 pk_import(int argc, char *argv[]) 745 { 746 int opt; 747 extern int optind_av; 748 extern char *optarg_av; 749 char *token_spec = NULL; 750 char *filename = NULL; 751 char *keyfile = NULL; 752 char *certfile = NULL; 753 char *crlfile = NULL; 754 char *label = NULL; 755 char *dir = NULL; 756 char *keydir = NULL; 757 char *prefix = NULL; 758 char *trustflags = NULL; 759 char *verify_crl = NULL; 760 char *keytype = "generic"; 761 char *senstr = NULL; 762 char *extstr = NULL; 763 boolean_t verify_crl_flag = B_FALSE; 764 int oclass = 0; 765 KMF_KEYSTORE_TYPE kstype = 0; 766 KMF_ENCODE_FORMAT kfmt = 0; 767 KMF_ENCODE_FORMAT okfmt = KMF_FORMAT_ASN1; 768 KMF_RETURN rv = KMF_OK; 769 KMF_CREDENTIAL pk12cred = { NULL, 0 }; 770 KMF_CREDENTIAL tokencred = { NULL, 0 }; 771 KMF_HANDLE_T kmfhandle = NULL; 772 KMF_KEY_ALG keyAlg = KMF_GENERIC_SECRET; 773 774 /* Parse command line options. Do NOT i18n/l10n. */ 775 while ((opt = getopt_av(argc, argv, 776 "T:(token)i:(infile)" 777 "k:(keystore)y:(objtype)" 778 "d:(dir)p:(prefix)" 779 "n:(certlabel)N:(label)" 780 "K:(outkey)c:(outcert)" 781 "v:(verifycrl)l:(outcrl)" 782 "E:(keytype)s:(sensitive)x:(extractable)" 783 "t:(trust)D:(keydir)F:(outformat)")) != EOF) { 784 if (EMPTYSTRING(optarg_av)) 785 return (PK_ERR_USAGE); 786 switch (opt) { 787 case 'T': /* token specifier */ 788 if (token_spec) 789 return (PK_ERR_USAGE); 790 token_spec = optarg_av; 791 break; 792 case 'c': /* output cert file name */ 793 if (certfile) 794 return (PK_ERR_USAGE); 795 certfile = optarg_av; 796 break; 797 case 'l': /* output CRL file name */ 798 if (crlfile) 799 return (PK_ERR_USAGE); 800 crlfile = optarg_av; 801 break; 802 case 'K': /* output key file name */ 803 if (keyfile) 804 return (PK_ERR_USAGE); 805 keyfile = optarg_av; 806 break; 807 case 'i': /* input file name */ 808 if (filename) 809 return (PK_ERR_USAGE); 810 filename = optarg_av; 811 break; 812 case 'k': 813 kstype = KS2Int(optarg_av); 814 if (kstype == 0) 815 return (PK_ERR_USAGE); 816 break; 817 case 'y': 818 oclass = OT2Int(optarg_av); 819 if (oclass == -1) 820 return (PK_ERR_USAGE); 821 break; 822 case 'd': 823 dir = optarg_av; 824 break; 825 case 'D': 826 keydir = optarg_av; 827 break; 828 case 'p': 829 if (prefix) 830 return (PK_ERR_USAGE); 831 prefix = optarg_av; 832 break; 833 case 'n': 834 case 'N': 835 if (label) 836 return (PK_ERR_USAGE); 837 label = optarg_av; 838 break; 839 case 'F': 840 okfmt = Str2Format(optarg_av); 841 if (okfmt == KMF_FORMAT_UNDEF) 842 return (PK_ERR_USAGE); 843 break; 844 case 't': 845 if (trustflags) 846 return (PK_ERR_USAGE); 847 trustflags = optarg_av; 848 break; 849 case 'v': 850 verify_crl = optarg_av; 851 if (tolower(verify_crl[0]) == 'y') 852 verify_crl_flag = B_TRUE; 853 else if (tolower(verify_crl[0]) == 'n') 854 verify_crl_flag = B_FALSE; 855 else 856 return (PK_ERR_USAGE); 857 break; 858 case 'E': 859 keytype = optarg_av; 860 break; 861 case 's': 862 if (senstr) 863 return (PK_ERR_USAGE); 864 senstr = optarg_av; 865 break; 866 case 'x': 867 if (extstr) 868 return (PK_ERR_USAGE); 869 extstr = optarg_av; 870 break; 871 default: 872 return (PK_ERR_USAGE); 873 break; 874 } 875 } 876 877 /* Assume keystore = PKCS#11 if not specified */ 878 if (kstype == 0) 879 kstype = KMF_KEYSTORE_PK11TOKEN; 880 881 /* Filename arg is required. */ 882 if (EMPTYSTRING(filename)) { 883 cryptoerror(LOG_STDERR, gettext("The 'infile' parameter" 884 "is required for the import operation.\n")); 885 return (PK_ERR_USAGE); 886 } 887 888 /* No additional args allowed. */ 889 argc -= optind_av; 890 argv += optind_av; 891 if (argc) 892 return (PK_ERR_USAGE); 893 894 /* if PUBLIC or PRIVATE obj was given, the old syntax was used. */ 895 if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) && 896 kstype != KMF_KEYSTORE_PK11TOKEN) { 897 898 (void) fprintf(stderr, gettext("The objtype parameter " 899 "is only relevant if keystore=pkcs11\n")); 900 return (PK_ERR_USAGE); 901 } 902 903 /* 904 * You must specify a certlabel (cert label) when importing 905 * into NSS or PKCS#11. 906 */ 907 if (kstype == KMF_KEYSTORE_NSS && 908 (oclass != PK_CRL_OBJ) && EMPTYSTRING(label)) { 909 cryptoerror(LOG_STDERR, gettext("The 'label' argument " 910 "is required for this operation\n")); 911 return (PK_ERR_USAGE); 912 } 913 914 if ((rv = kmf_get_file_format(filename, &kfmt)) != KMF_OK) { 915 /* 916 * Allow for raw key data to be imported. 917 */ 918 if (rv == KMF_ERR_ENCODING) { 919 rv = KMF_OK; 920 kfmt = KMF_FORMAT_RAWKEY; 921 /* 922 * Set the object class only if it was not 923 * given on the command line or if it was 924 * specified as a symmetric key object. 925 */ 926 if (oclass == 0 || (oclass & PK_SYMKEY_OBJ)) { 927 oclass = PK_SYMKEY_OBJ; 928 } else { 929 cryptoerror(LOG_STDERR, gettext( 930 "The input file does not contain the " 931 "object type indicated on command " 932 "line.")); 933 return (KMF_ERR_BAD_PARAMETER); 934 } 935 } else { 936 cryptoerror(LOG_STDERR, 937 gettext("File format not recognized.")); 938 return (rv); 939 } 940 } 941 942 /* Check parameters for raw key import operation */ 943 if (kfmt == KMF_FORMAT_RAWKEY) { 944 if (keytype != NULL && 945 Str2SymKeyType(keytype, &keyAlg) != 0) { 946 cryptoerror(LOG_STDERR, 947 gettext("Unrecognized keytype(%s).\n"), keytype); 948 return (PK_ERR_USAGE); 949 } 950 if (senstr != NULL && extstr != NULL && 951 kstype != KMF_KEYSTORE_PK11TOKEN) { 952 cryptoerror(LOG_STDERR, 953 gettext("The sensitive or extractable option " 954 "applies only when importing a key from a file " 955 "into a PKCS#11 keystore.\n")); 956 return (PK_ERR_USAGE); 957 } 958 } 959 960 /* If no objtype was given, treat it as a certificate */ 961 if (oclass == 0 && (kfmt == KMF_FORMAT_ASN1 || 962 kfmt == KMF_FORMAT_PEM)) 963 oclass = PK_CERT_OBJ; 964 965 if (kstype == KMF_KEYSTORE_NSS) { 966 if (oclass == PK_CRL_OBJ && 967 (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) { 968 cryptoerror(LOG_STDERR, gettext( 969 "CRL data can only be imported as DER or " 970 "PEM format")); 971 return (PK_ERR_USAGE); 972 } 973 974 if (oclass == PK_CERT_OBJ && 975 (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) { 976 cryptoerror(LOG_STDERR, gettext( 977 "Certificates can only be imported as DER or " 978 "PEM format")); 979 return (PK_ERR_USAGE); 980 } 981 982 /* we do not import private keys except in PKCS12 bundles */ 983 if (oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)) { 984 cryptoerror(LOG_STDERR, gettext( 985 "Private key data can only be imported as part " 986 "of a PKCS12 file.\n")); 987 return (PK_ERR_USAGE); 988 } 989 } 990 991 if (kstype == KMF_KEYSTORE_OPENSSL && oclass != PK_CRL_OBJ) { 992 if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) { 993 cryptoerror(LOG_STDERR, gettext( 994 "The 'outkey' and 'outcert' parameters " 995 "are required for the import operation " 996 "when the 'file' keystore is used.\n")); 997 return (PK_ERR_USAGE); 998 } 999 } 1000 1001 if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) 1002 token_spec = PK_DEFAULT_PK11TOKEN; 1003 else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) 1004 token_spec = DEFAULT_NSS_TOKEN; 1005 1006 if (kfmt == KMF_FORMAT_PKCS12) { 1007 (void) get_pk12_password(&pk12cred); 1008 } 1009 1010 if ((kfmt == KMF_FORMAT_PKCS12 || kfmt == KMF_FORMAT_RAWKEY || 1011 (kfmt == KMF_FORMAT_PEM && (oclass & PK_KEY_OBJ))) && 1012 (kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS)) { 1013 (void) get_token_password(kstype, token_spec, &tokencred); 1014 } 1015 1016 if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 1017 cryptoerror(LOG_STDERR, gettext("Error initializing " 1018 "KMF: 0x%02x\n"), rv); 1019 goto end; 1020 } 1021 1022 switch (kstype) { 1023 case KMF_KEYSTORE_PK11TOKEN: 1024 if (kfmt == KMF_FORMAT_PKCS12) 1025 rv = pk_import_pk12_pk11( 1026 kmfhandle, &pk12cred, 1027 &tokencred, label, 1028 token_spec, filename); 1029 else if (oclass == PK_CERT_OBJ) 1030 rv = pk_import_cert( 1031 kmfhandle, kstype, 1032 label, token_spec, 1033 filename, 1034 NULL, NULL, NULL); 1035 else if (oclass == PK_CRL_OBJ) 1036 rv = pk_import_file_crl( 1037 kmfhandle, filename, 1038 crlfile, dir, okfmt); 1039 else if (kfmt == KMF_FORMAT_RAWKEY && 1040 oclass == PK_SYMKEY_OBJ) { 1041 rv = pk_import_rawkey(kmfhandle, 1042 kstype, token_spec, &tokencred, 1043 filename, label, 1044 keyAlg, senstr, extstr); 1045 } else if (kfmt == KMF_FORMAT_PEM || 1046 kfmt == KMF_FORMAT_PEM_KEYPAIR) { 1047 rv = pk_import_keys(kmfhandle, 1048 kstype, token_spec, &tokencred, 1049 filename, label, senstr, extstr); 1050 } else { 1051 rv = PK_ERR_USAGE; 1052 } 1053 break; 1054 case KMF_KEYSTORE_NSS: 1055 if (dir == NULL) 1056 dir = PK_DEFAULT_DIRECTORY; 1057 if (kfmt == KMF_FORMAT_PKCS12) 1058 rv = pk_import_pk12_nss( 1059 kmfhandle, &pk12cred, 1060 &tokencred, 1061 token_spec, dir, prefix, 1062 label, trustflags, filename); 1063 else if (oclass == PK_CERT_OBJ) { 1064 rv = pk_import_cert( 1065 kmfhandle, kstype, 1066 label, token_spec, 1067 filename, dir, prefix, trustflags); 1068 } else if (oclass == PK_CRL_OBJ) { 1069 rv = pk_import_nss_crl( 1070 kmfhandle, verify_crl_flag, 1071 filename, dir, prefix); 1072 } 1073 break; 1074 case KMF_KEYSTORE_OPENSSL: 1075 if (kfmt == KMF_FORMAT_PKCS12) 1076 rv = pk_import_pk12_files( 1077 kmfhandle, &pk12cred, 1078 filename, certfile, keyfile, 1079 dir, keydir, okfmt); 1080 else if (oclass == PK_CRL_OBJ) { 1081 rv = pk_import_file_crl( 1082 kmfhandle, filename, 1083 crlfile, dir, okfmt); 1084 } else 1085 /* 1086 * It doesn't make sense to import anything 1087 * else for the files plugin. 1088 */ 1089 return (PK_ERR_USAGE); 1090 break; 1091 default: 1092 rv = PK_ERR_USAGE; 1093 break; 1094 } 1095 1096 end: 1097 if (rv != KMF_OK) 1098 display_error(kmfhandle, rv, 1099 gettext("Error importing objects")); 1100 1101 if (tokencred.cred != NULL) 1102 free(tokencred.cred); 1103 1104 if (pk12cred.cred != NULL) 1105 free(pk12cred.cred); 1106 1107 (void) kmf_finalize(kmfhandle); 1108 1109 if (rv != KMF_OK) 1110 return (PK_ERR_USAGE); 1111 1112 return (0); 1113 } 1114