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 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * Copyright 2012 Milan Jurik. All rights reserved. 25 */ 26 27 /* 28 * This file implements the import operation for this tool. 29 * The basic flow of the process is to decrypt the PKCS#12 30 * input file if it has a password, parse the elements in 31 * the file, find the soft token, log into it, import the 32 * PKCS#11 objects into the soft token, and log out. 33 */ 34 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <string.h> 38 #include <ctype.h> 39 #include <errno.h> 40 #include <fcntl.h> 41 #include <sys/types.h> 42 #include <sys/stat.h> 43 #include "common.h" 44 45 #include <kmfapi.h> 46 47 #define NEW_ATTRLIST(a, n) \ 48 { \ 49 a = (KMF_ATTRIBUTE *)malloc(n * sizeof (KMF_ATTRIBUTE)); \ 50 if (a == NULL) { \ 51 rv = KMF_ERR_MEMORY; \ 52 goto end; \ 53 } \ 54 (void) memset(a, 0, n * sizeof (KMF_ATTRIBUTE)); \ 55 } 56 57 static KMF_RETURN 58 pk_import_pk12_files(KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *cred, 59 char *outfile, char *certfile, char *keyfile, 60 KMF_ENCODE_FORMAT outformat) 61 { 62 KMF_RETURN rv = KMF_OK; 63 KMF_X509_DER_CERT *certs = NULL; 64 KMF_RAW_KEY_DATA *keys = NULL; 65 int ncerts = 0; 66 int nkeys = 0; 67 int i; 68 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 69 KMF_ATTRIBUTE *attrlist = NULL; 70 int numattr = 0; 71 72 rv = kmf_import_objects(kmfhandle, outfile, cred, 73 &certs, &ncerts, &keys, &nkeys); 74 75 if (rv == KMF_OK) { 76 (void) printf(gettext("Found %d certificate(s) and %d " 77 "key(s) in %s\n"), ncerts, nkeys, outfile); 78 } 79 80 if (rv == KMF_OK && ncerts > 0) { 81 char newcertfile[MAXPATHLEN]; 82 83 NEW_ATTRLIST(attrlist, (3 + (3 * ncerts))); 84 85 kmf_set_attr_at_index(attrlist, numattr, 86 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 87 numattr++; 88 89 kmf_set_attr_at_index(attrlist, numattr, 90 KMF_ENCODE_FORMAT_ATTR, &outformat, sizeof (outformat)); 91 numattr++; 92 93 for (i = 0; rv == KMF_OK && i < ncerts; i++) { 94 int num = numattr; 95 96 /* 97 * If storing more than 1 cert, gotta change 98 * the name so we don't overwrite the previous one. 99 * Just append a _# to the name. 100 */ 101 if (i > 0) { 102 (void) snprintf(newcertfile, 103 sizeof (newcertfile), "%s_%d", certfile, i); 104 105 kmf_set_attr_at_index(attrlist, num, 106 KMF_CERT_FILENAME_ATTR, newcertfile, 107 strlen(newcertfile)); 108 num++; 109 } else { 110 kmf_set_attr_at_index(attrlist, num, 111 KMF_CERT_FILENAME_ATTR, certfile, 112 strlen(certfile)); 113 num++; 114 } 115 116 if (certs[i].kmf_private.label != NULL) { 117 kmf_set_attr_at_index(attrlist, num, 118 KMF_CERT_LABEL_ATTR, 119 certs[i].kmf_private.label, 120 strlen(certs[i].kmf_private.label)); 121 num++; 122 } 123 kmf_set_attr_at_index(attrlist, num, 124 KMF_CERT_DATA_ATTR, &certs[i].certificate, 125 sizeof (KMF_DATA)); 126 num++; 127 rv = kmf_store_cert(kmfhandle, num, attrlist); 128 } 129 free(attrlist); 130 } 131 if (rv == KMF_OK && nkeys > 0) { 132 char newkeyfile[MAXPATHLEN]; 133 numattr = 0; 134 NEW_ATTRLIST(attrlist, (4 + (4 * nkeys))); 135 136 kmf_set_attr_at_index(attrlist, numattr, 137 KMF_KEYSTORE_TYPE_ATTR, &kstype, 138 sizeof (kstype)); 139 numattr++; 140 141 kmf_set_attr_at_index(attrlist, numattr, 142 KMF_ENCODE_FORMAT_ATTR, &outformat, 143 sizeof (outformat)); 144 numattr++; 145 146 if (cred != NULL && cred->credlen > 0) { 147 kmf_set_attr_at_index(attrlist, numattr, 148 KMF_CREDENTIAL_ATTR, cred, 149 sizeof (KMF_CREDENTIAL)); 150 numattr++; 151 } 152 153 /* The order of certificates and keys should match */ 154 for (i = 0; rv == KMF_OK && i < nkeys; i++) { 155 int num = numattr; 156 157 if (i > 0) { 158 (void) snprintf(newkeyfile, 159 sizeof (newkeyfile), "%s_%d", keyfile, i); 160 161 kmf_set_attr_at_index(attrlist, num, 162 KMF_KEY_FILENAME_ATTR, newkeyfile, 163 strlen(newkeyfile)); 164 num++; 165 } else { 166 kmf_set_attr_at_index(attrlist, num, 167 KMF_KEY_FILENAME_ATTR, keyfile, 168 strlen(keyfile)); 169 num++; 170 } 171 172 if (i < ncerts) { 173 kmf_set_attr_at_index(attrlist, num, 174 KMF_CERT_DATA_ATTR, &certs[i], 175 sizeof (KMF_CERT_DATA_ATTR)); 176 num++; 177 } 178 179 kmf_set_attr_at_index(attrlist, num, 180 KMF_RAW_KEY_ATTR, &keys[i], 181 sizeof (KMF_RAW_KEY_DATA)); 182 num++; 183 184 rv = kmf_store_key(kmfhandle, num, attrlist); 185 } 186 free(attrlist); 187 } 188 end: 189 /* 190 * Cleanup memory. 191 */ 192 if (certs) { 193 for (i = 0; i < ncerts; i++) 194 kmf_free_kmf_cert(kmfhandle, &certs[i]); 195 free(certs); 196 } 197 if (keys) { 198 for (i = 0; i < nkeys; i++) 199 kmf_free_raw_key(&keys[i]); 200 free(keys); 201 } 202 203 204 return (rv); 205 } 206 207 208 static KMF_RETURN 209 pk_import_pk12_nss( 210 KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *kmfcred, 211 KMF_CREDENTIAL *tokencred, 212 char *token_spec, char *dir, char *prefix, 213 char *nickname, char *trustflags, char *filename) 214 { 215 KMF_RETURN rv = KMF_OK; 216 KMF_X509_DER_CERT *certs = NULL; 217 KMF_RAW_KEY_DATA *keys = NULL; 218 int ncerts = 0; 219 int nkeys = 0; 220 int i; 221 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; 222 KMF_ATTRIBUTE *attrlist = NULL; 223 int numattr = 0; 224 225 rv = configure_nss(kmfhandle, dir, prefix); 226 if (rv != KMF_OK) 227 return (rv); 228 229 rv = kmf_import_objects(kmfhandle, filename, kmfcred, 230 &certs, &ncerts, &keys, &nkeys); 231 232 if (rv == KMF_OK) 233 (void) printf(gettext("Found %d certificate(s) and %d " 234 "key(s) in %s\n"), ncerts, nkeys, filename); 235 236 if (rv == KMF_OK) { 237 numattr = 0; 238 NEW_ATTRLIST(attrlist, (4 + (2 * nkeys))); 239 240 kmf_set_attr_at_index(attrlist, numattr, 241 KMF_KEYSTORE_TYPE_ATTR, &kstype, 242 sizeof (kstype)); 243 numattr++; 244 245 if (token_spec != NULL) { 246 kmf_set_attr_at_index(attrlist, numattr, 247 KMF_TOKEN_LABEL_ATTR, token_spec, 248 strlen(token_spec)); 249 numattr++; 250 } 251 252 if (nickname != NULL) { 253 kmf_set_attr_at_index(attrlist, numattr, 254 KMF_KEYLABEL_ATTR, nickname, 255 strlen(nickname)); 256 numattr++; 257 } 258 259 if (tokencred->credlen > 0) { 260 kmf_set_attr_at_index(attrlist, numattr, 261 KMF_CREDENTIAL_ATTR, tokencred, 262 sizeof (KMF_CREDENTIAL)); 263 numattr++; 264 } 265 266 /* The order of certificates and keys should match */ 267 for (i = 0; i < nkeys; i++) { 268 int num = numattr; 269 270 if (i < ncerts) { 271 kmf_set_attr_at_index(attrlist, num, 272 KMF_CERT_DATA_ATTR, &certs[i], 273 sizeof (KMF_DATA)); 274 num++; 275 } 276 277 kmf_set_attr_at_index(attrlist, num, 278 KMF_RAW_KEY_ATTR, &keys[i], 279 sizeof (KMF_RAW_KEY_DATA)); 280 num++; 281 282 rv = kmf_store_key(kmfhandle, num, attrlist); 283 } 284 free(attrlist); 285 attrlist = NULL; 286 } 287 288 if (rv == KMF_OK) { 289 numattr = 0; 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 } 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 char *kmferrstr = NULL; 964 KMF_RETURN rv2; 965 /* 966 * Allow for raw key data to be imported. 967 */ 968 if (rv == KMF_ERR_ENCODING) { 969 rv = KMF_OK; 970 kfmt = KMF_FORMAT_RAWKEY; 971 /* 972 * Set the object class only if it was not 973 * given on the command line or if it was 974 * specified as a symmetric key object. 975 */ 976 if (oclass == 0 || (oclass & PK_SYMKEY_OBJ)) { 977 oclass = PK_SYMKEY_OBJ; 978 } else { 979 cryptoerror(LOG_STDERR, gettext( 980 "The input file does not contain the " 981 "object type indicated on command " 982 "line.")); 983 return (KMF_ERR_BAD_PARAMETER); 984 } 985 } else { 986 if (rv == KMF_ERR_OPEN_FILE) { 987 cryptoerror(LOG_STDERR, 988 gettext("Cannot open file (%s)\n."), 989 filename); 990 } else { 991 rv2 = kmf_get_kmf_error_str(rv, &kmferrstr); 992 if (rv2 == KMF_OK && kmferrstr) { 993 cryptoerror(LOG_STDERR, 994 gettext("libkmf error: %s"), 995 kmferrstr); 996 kmf_free_str(kmferrstr); 997 } 998 } 999 return (rv); 1000 } 1001 } 1002 1003 /* Check parameters for raw key import operation */ 1004 if (kfmt == KMF_FORMAT_RAWKEY) { 1005 if (keytype != NULL && 1006 Str2SymKeyType(keytype, &keyAlg) != 0) { 1007 cryptoerror(LOG_STDERR, 1008 gettext("Unrecognized keytype(%s).\n"), keytype); 1009 return (PK_ERR_USAGE); 1010 } 1011 if (senstr != NULL && extstr != NULL && 1012 kstype != KMF_KEYSTORE_PK11TOKEN) { 1013 cryptoerror(LOG_STDERR, 1014 gettext("The sensitive or extractable option " 1015 "applies only when importing a key from a file " 1016 "into a PKCS#11 keystore.\n")); 1017 return (PK_ERR_USAGE); 1018 } 1019 } 1020 1021 /* If no objtype was given, treat it as a certificate */ 1022 if (oclass == 0 && (kfmt == KMF_FORMAT_ASN1 || 1023 kfmt == KMF_FORMAT_PEM)) 1024 oclass = PK_CERT_OBJ; 1025 1026 if (kstype == KMF_KEYSTORE_NSS) { 1027 if (oclass == PK_CRL_OBJ && 1028 (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) { 1029 cryptoerror(LOG_STDERR, gettext( 1030 "CRL data can only be imported as DER or " 1031 "PEM format")); 1032 return (PK_ERR_USAGE); 1033 } 1034 1035 if (oclass == PK_CERT_OBJ && 1036 (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) { 1037 cryptoerror(LOG_STDERR, gettext( 1038 "Certificates can only be imported as DER or " 1039 "PEM format")); 1040 return (PK_ERR_USAGE); 1041 } 1042 1043 /* we do not import private keys except in PKCS12 bundles */ 1044 if (oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)) { 1045 cryptoerror(LOG_STDERR, gettext( 1046 "Private key data can only be imported as part " 1047 "of a PKCS12 file.\n")); 1048 return (PK_ERR_USAGE); 1049 } 1050 } 1051 1052 if (kstype == KMF_KEYSTORE_OPENSSL && oclass != PK_CRL_OBJ) { 1053 if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) { 1054 cryptoerror(LOG_STDERR, gettext( 1055 "The 'outkey' and 'outcert' parameters " 1056 "are required for the import operation " 1057 "when the 'file' keystore is used.\n")); 1058 return (PK_ERR_USAGE); 1059 } 1060 } 1061 1062 if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) 1063 token_spec = PK_DEFAULT_PK11TOKEN; 1064 else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) 1065 token_spec = DEFAULT_NSS_TOKEN; 1066 1067 if (kfmt == KMF_FORMAT_PKCS12) { 1068 (void) get_pk12_password(&pk12cred); 1069 } 1070 1071 if ((kfmt == KMF_FORMAT_PKCS12 || kfmt == KMF_FORMAT_RAWKEY || 1072 (kfmt == KMF_FORMAT_PEM && (oclass & PK_KEY_OBJ))) && 1073 (kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS)) { 1074 (void) get_token_password(kstype, token_spec, &tokencred); 1075 } 1076 1077 if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 1078 cryptoerror(LOG_STDERR, gettext("Error initializing " 1079 "KMF: 0x%02x\n"), rv); 1080 goto end; 1081 } 1082 1083 switch (kstype) { 1084 case KMF_KEYSTORE_PK11TOKEN: 1085 if (kfmt == KMF_FORMAT_PKCS12) 1086 rv = pk_import_pk12_pk11( 1087 kmfhandle, &pk12cred, 1088 &tokencred, label, 1089 token_spec, filename); 1090 else if (oclass == PK_CERT_OBJ) 1091 rv = pk_import_cert( 1092 kmfhandle, kstype, 1093 label, token_spec, 1094 filename, 1095 NULL, NULL, NULL); 1096 else if (oclass == PK_CRL_OBJ) 1097 rv = pk_import_file_crl( 1098 kmfhandle, filename, 1099 crlfile, okfmt); 1100 else if (kfmt == KMF_FORMAT_RAWKEY && 1101 oclass == PK_SYMKEY_OBJ) { 1102 rv = pk_import_rawkey(kmfhandle, 1103 kstype, token_spec, &tokencred, 1104 filename, label, 1105 keyAlg, senstr, extstr); 1106 } else if (kfmt == KMF_FORMAT_PEM || 1107 kfmt == KMF_FORMAT_PEM_KEYPAIR) { 1108 rv = pk_import_keys(kmfhandle, 1109 kstype, token_spec, &tokencred, 1110 filename, label, senstr, extstr); 1111 } else { 1112 rv = PK_ERR_USAGE; 1113 } 1114 break; 1115 case KMF_KEYSTORE_NSS: 1116 if (dir == NULL) 1117 dir = PK_DEFAULT_DIRECTORY; 1118 if (kfmt == KMF_FORMAT_PKCS12) 1119 rv = pk_import_pk12_nss( 1120 kmfhandle, &pk12cred, 1121 &tokencred, 1122 token_spec, dir, prefix, 1123 label, trustflags, filename); 1124 else if (oclass == PK_CERT_OBJ) { 1125 rv = pk_import_cert( 1126 kmfhandle, kstype, 1127 label, token_spec, 1128 filename, dir, prefix, trustflags); 1129 } else if (oclass == PK_CRL_OBJ) { 1130 rv = pk_import_nss_crl( 1131 kmfhandle, verify_crl_flag, 1132 filename, dir, prefix); 1133 } 1134 break; 1135 case KMF_KEYSTORE_OPENSSL: 1136 if (kfmt == KMF_FORMAT_PKCS12) 1137 rv = pk_import_pk12_files( 1138 kmfhandle, &pk12cred, 1139 filename, certfile, keyfile, 1140 okfmt); 1141 else if (oclass == PK_CRL_OBJ) { 1142 rv = pk_import_file_crl( 1143 kmfhandle, filename, 1144 crlfile, okfmt); 1145 } else 1146 /* 1147 * It doesn't make sense to import anything 1148 * else for the files plugin. 1149 */ 1150 return (PK_ERR_USAGE); 1151 break; 1152 default: 1153 rv = PK_ERR_USAGE; 1154 break; 1155 } 1156 1157 end: 1158 if (rv != KMF_OK) 1159 display_error(kmfhandle, rv, 1160 gettext("Error importing objects")); 1161 1162 if (tokencred.cred != NULL) 1163 free(tokencred.cred); 1164 1165 if (pk12cred.cred != NULL) 1166 free(pk12cred.cred); 1167 1168 (void) kmf_finalize(kmfhandle); 1169 1170 if (rv != KMF_OK) 1171 return (PK_ERR_USAGE); 1172 1173 return (0); 1174 } 1175