1 /* $OpenBSD: pkcs12.c,v 1.23 2022/09/14 16:31:36 tb Exp $ */ 2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3 * project. 4 */ 5 /* ==================================================================== 6 * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * licensing@OpenSSL.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 * 53 * This product includes cryptographic software written by Eric Young 54 * (eay@cryptsoft.com). This product includes software written by Tim 55 * Hudson (tjh@cryptsoft.com). 56 * 57 */ 58 59 #include <openssl/opensslconf.h> 60 61 #if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1) 62 63 #include <stdio.h> 64 #include <stdlib.h> 65 #include <string.h> 66 67 #include "apps.h" 68 69 #include <openssl/crypto.h> 70 #include <openssl/err.h> 71 #include <openssl/pem.h> 72 #include <openssl/pkcs12.h> 73 74 #define NOKEYS 0x1 75 #define NOCERTS 0x2 76 #define INFO 0x4 77 #define CLCERTS 0x8 78 #define CACERTS 0x10 79 80 static int get_cert_chain(X509 *cert, X509_STORE *store, 81 STACK_OF(X509) **chain); 82 static int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int passlen, 83 int options, char *pempass); 84 static int dump_certs_pkeys_bags(BIO *out, const STACK_OF(PKCS12_SAFEBAG) *bags, 85 char *pass, int passlen, int options, char *pempass); 86 static int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass, 87 int passlen, int options, char *pempass); 88 static int print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst, 89 const char *name); 90 static void hex_prin(BIO *out, unsigned char *buf, int len); 91 static int alg_print(BIO *x, const X509_ALGOR *alg); 92 static int set_pbe(BIO *err, int *ppbe, const char *str); 93 94 static struct { 95 int add_lmk; 96 char *CAfile; 97 STACK_OF(OPENSSL_STRING) *canames; 98 char *CApath; 99 int cert_pbe; 100 char *certfile; 101 int chain; 102 char *csp_name; 103 const EVP_CIPHER *enc; 104 int export_cert; 105 int key_pbe; 106 char *keyname; 107 int keytype; 108 char *infile; 109 int iter; 110 char *macalg; 111 int maciter; 112 int macver; 113 char *name; 114 int noprompt; 115 int options; 116 char *outfile; 117 char *passarg; 118 char *passargin; 119 char *passargout; 120 int twopass; 121 } pkcs12_config; 122 123 static int 124 pkcs12_opt_canames(char *arg) 125 { 126 if (pkcs12_config.canames == NULL && 127 (pkcs12_config.canames = sk_OPENSSL_STRING_new_null()) == NULL) 128 return (1); 129 130 if (!sk_OPENSSL_STRING_push(pkcs12_config.canames, arg)) 131 return (1); 132 133 return (0); 134 } 135 136 static int 137 pkcs12_opt_cert_pbe(char *arg) 138 { 139 return (!set_pbe(bio_err, &pkcs12_config.cert_pbe, arg)); 140 } 141 142 static int 143 pkcs12_opt_key_pbe(char *arg) 144 { 145 return (!set_pbe(bio_err, &pkcs12_config.key_pbe, arg)); 146 } 147 148 static int 149 pkcs12_opt_passarg(char *arg) 150 { 151 pkcs12_config.passarg = arg; 152 pkcs12_config.noprompt = 1; 153 return (0); 154 } 155 156 static const EVP_CIPHER *get_cipher_by_name(char *name) 157 { 158 if (name == NULL || strcmp(name, "") == 0) 159 return (NULL); 160 #ifndef OPENSSL_NO_AES 161 else if (strcmp(name, "aes128") == 0) 162 return EVP_aes_128_cbc(); 163 else if (strcmp(name, "aes192") == 0) 164 return EVP_aes_192_cbc(); 165 else if (strcmp(name, "aes256") == 0) 166 return EVP_aes_256_cbc(); 167 #endif 168 #ifndef OPENSSL_NO_CAMELLIA 169 else if (strcmp(name, "camellia128") == 0) 170 return EVP_camellia_128_cbc(); 171 else if (strcmp(name, "camellia192") == 0) 172 return EVP_camellia_192_cbc(); 173 else if (strcmp(name, "camellia256") == 0) 174 return EVP_camellia_256_cbc(); 175 #endif 176 #ifndef OPENSSL_NO_DES 177 else if (strcmp(name, "des") == 0) 178 return EVP_des_cbc(); 179 else if (strcmp(name, "des3") == 0) 180 return EVP_des_ede3_cbc(); 181 #endif 182 #ifndef OPENSSL_NO_IDEA 183 else if (strcmp(name, "idea") == 0) 184 return EVP_idea_cbc(); 185 #endif 186 else 187 return (NULL); 188 } 189 190 static int 191 pkcs12_opt_enc(int argc, char **argv, int *argsused) 192 { 193 char *name = argv[0]; 194 195 if (*name++ != '-') 196 return (1); 197 198 if (strcmp(name, "nodes") == 0) 199 pkcs12_config.enc = NULL; 200 else if ((pkcs12_config.enc = get_cipher_by_name(name)) == NULL) 201 return (1); 202 203 *argsused = 1; 204 return (0); 205 } 206 207 static const struct option pkcs12_options[] = { 208 #ifndef OPENSSL_NO_AES 209 { 210 .name = "aes128", 211 .desc = "Encrypt PEM output with CBC AES", 212 .type = OPTION_ARGV_FUNC, 213 .opt.argvfunc = pkcs12_opt_enc, 214 }, 215 { 216 .name = "aes192", 217 .desc = "Encrypt PEM output with CBC AES", 218 .type = OPTION_ARGV_FUNC, 219 .opt.argvfunc = pkcs12_opt_enc, 220 }, 221 { 222 .name = "aes256", 223 .desc = "Encrypt PEM output with CBC AES", 224 .type = OPTION_ARGV_FUNC, 225 .opt.argvfunc = pkcs12_opt_enc, 226 }, 227 #endif 228 #ifndef OPENSSL_NO_CAMELLIA 229 { 230 .name = "camellia128", 231 .desc = "Encrypt PEM output with CBC Camellia", 232 .type = OPTION_ARGV_FUNC, 233 .opt.argvfunc = pkcs12_opt_enc, 234 }, 235 { 236 .name = "camellia192", 237 .desc = "Encrypt PEM output with CBC Camellia", 238 .type = OPTION_ARGV_FUNC, 239 .opt.argvfunc = pkcs12_opt_enc, 240 }, 241 { 242 .name = "camellia256", 243 .desc = "Encrypt PEM output with CBC Camellia", 244 .type = OPTION_ARGV_FUNC, 245 .opt.argvfunc = pkcs12_opt_enc, 246 }, 247 #endif 248 { 249 .name = "des", 250 .desc = "Encrypt private keys with DES", 251 .type = OPTION_ARGV_FUNC, 252 .opt.argvfunc = pkcs12_opt_enc, 253 }, 254 { 255 .name = "des3", 256 .desc = "Encrypt private keys with triple DES (default)", 257 .type = OPTION_ARGV_FUNC, 258 .opt.argvfunc = pkcs12_opt_enc, 259 }, 260 #ifndef OPENSSL_NO_IDEA 261 { 262 .name = "idea", 263 .desc = "Encrypt private keys with IDEA", 264 .type = OPTION_ARGV_FUNC, 265 .opt.argvfunc = pkcs12_opt_enc, 266 }, 267 #endif 268 { 269 .name = "cacerts", 270 .desc = "Only output CA certificates", 271 .type = OPTION_VALUE_OR, 272 .opt.value = &pkcs12_config.options, 273 .value = CACERTS, 274 }, 275 { 276 .name = "CAfile", 277 .argname = "file", 278 .desc = "PEM format file of CA certificates", 279 .type = OPTION_ARG, 280 .opt.arg = &pkcs12_config.CAfile, 281 }, 282 { 283 .name = "caname", 284 .argname = "name", 285 .desc = "Use name as CA friendly name (can be used more than once)", 286 .type = OPTION_ARG_FUNC, 287 .opt.argfunc = pkcs12_opt_canames, 288 }, 289 { 290 .name = "CApath", 291 .argname = "directory", 292 .desc = "PEM format directory of CA certificates", 293 .type = OPTION_ARG, 294 .opt.arg = &pkcs12_config.CApath, 295 }, 296 { 297 .name = "certfile", 298 .argname = "file", 299 .desc = "Add all certs in file", 300 .type = OPTION_ARG, 301 .opt.arg = &pkcs12_config.certfile, 302 }, 303 { 304 .name = "certpbe", 305 .argname = "alg", 306 .desc = "Specify certificate PBE algorithm (default RC2-40)", 307 .type = OPTION_ARG_FUNC, 308 .opt.argfunc = pkcs12_opt_cert_pbe, 309 }, 310 { 311 .name = "chain", 312 .desc = "Add certificate chain", 313 .type = OPTION_FLAG, 314 .opt.flag = &pkcs12_config.chain, 315 }, 316 { 317 .name = "clcerts", 318 .desc = "Only output client certificates", 319 .type = OPTION_VALUE_OR, 320 .opt.value = &pkcs12_config.options, 321 .value = CLCERTS, 322 }, 323 { 324 .name = "CSP", 325 .argname = "name", 326 .desc = "Microsoft CSP name", 327 .type = OPTION_ARG, 328 .opt.arg = &pkcs12_config.csp_name, 329 }, 330 { 331 .name = "descert", 332 .desc = "Encrypt PKCS#12 certificates with triple DES (default RC2-40)", 333 .type = OPTION_VALUE, 334 .opt.value = &pkcs12_config.cert_pbe, 335 .value = NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 336 }, 337 { 338 .name = "export", 339 .desc = "Output PKCS#12 file", 340 .type = OPTION_FLAG, 341 .opt.flag = &pkcs12_config.export_cert, 342 }, 343 { 344 .name = "in", 345 .argname = "file", 346 .desc = "Input filename", 347 .type = OPTION_ARG, 348 .opt.arg = &pkcs12_config.infile, 349 }, 350 { 351 .name = "info", 352 .desc = "Give info about PKCS#12 structure", 353 .type = OPTION_VALUE_OR, 354 .opt.value = &pkcs12_config.options, 355 .value = INFO, 356 }, 357 { 358 .name = "inkey", 359 .argname = "file", 360 .desc = "Private key if not infile", 361 .type = OPTION_ARG, 362 .opt.arg = &pkcs12_config.keyname, 363 }, 364 { 365 .name = "keyex", 366 .desc = "Set MS key exchange type", 367 .type = OPTION_VALUE, 368 .opt.value = &pkcs12_config.keytype, 369 .value = KEY_EX, 370 }, 371 { 372 .name = "keypbe", 373 .argname = "alg", 374 .desc = "Specify private key PBE algorithm (default 3DES)", 375 .type = OPTION_ARG_FUNC, 376 .opt.argfunc = pkcs12_opt_key_pbe, 377 }, 378 { 379 .name = "keysig", 380 .desc = "Set MS key signature type", 381 .type = OPTION_VALUE, 382 .opt.value = &pkcs12_config.keytype, 383 .value = KEY_SIG, 384 }, 385 { 386 .name = "LMK", 387 .desc = "Add local machine keyset attribute to private key", 388 .type = OPTION_FLAG, 389 .opt.flag = &pkcs12_config.add_lmk, 390 }, 391 { 392 .name = "macalg", 393 .argname = "alg", 394 .desc = "Digest algorithm used in MAC (default SHA1)", 395 .type = OPTION_ARG, 396 .opt.arg = &pkcs12_config.macalg, 397 }, 398 { 399 .name = "maciter", 400 .desc = "Use MAC iteration", 401 .type = OPTION_VALUE, 402 .opt.value = &pkcs12_config.maciter, 403 .value = PKCS12_DEFAULT_ITER, 404 }, 405 { 406 .name = "name", 407 .argname = "name", 408 .desc = "Use name as friendly name", 409 .type = OPTION_ARG, 410 .opt.arg = &pkcs12_config.name, 411 }, 412 { 413 .name = "nocerts", 414 .desc = "Don't output certificates", 415 .type = OPTION_VALUE_OR, 416 .opt.value = &pkcs12_config.options, 417 .value = NOCERTS, 418 }, 419 { 420 .name = "nodes", 421 .desc = "Don't encrypt private keys", 422 .type = OPTION_ARGV_FUNC, 423 .opt.argvfunc = pkcs12_opt_enc, 424 }, 425 { 426 .name = "noiter", 427 .desc = "Don't use encryption iteration", 428 .type = OPTION_VALUE, 429 .opt.value = &pkcs12_config.iter, 430 .value = 1, 431 }, 432 { 433 .name = "nokeys", 434 .desc = "Don't output private keys", 435 .type = OPTION_VALUE_OR, 436 .opt.value = &pkcs12_config.options, 437 .value = NOKEYS, 438 }, 439 { 440 .name = "nomac", 441 .desc = "Don't generate MAC", 442 .type = OPTION_VALUE, 443 .opt.value = &pkcs12_config.maciter, 444 .value = -1, 445 }, 446 { 447 .name = "nomaciter", 448 .desc = "Don't use MAC iteration", 449 .type = OPTION_VALUE, 450 .opt.value = &pkcs12_config.maciter, 451 .value = 1, 452 }, 453 { 454 .name = "nomacver", 455 .desc = "Don't verify MAC", 456 .type = OPTION_VALUE, 457 .opt.value = &pkcs12_config.macver, 458 .value = 0, 459 }, 460 { 461 .name = "noout", 462 .desc = "Don't output anything, just verify", 463 .type = OPTION_VALUE_OR, 464 .opt.value = &pkcs12_config.options, 465 .value = (NOKEYS | NOCERTS), 466 }, 467 { 468 .name = "out", 469 .argname = "file", 470 .desc = "Output filename", 471 .type = OPTION_ARG, 472 .opt.arg = &pkcs12_config.outfile, 473 }, 474 { 475 .name = "passin", 476 .argname = "arg", 477 .desc = "Input file passphrase source", 478 .type = OPTION_ARG, 479 .opt.arg = &pkcs12_config.passargin, 480 }, 481 { 482 .name = "passout", 483 .argname = "arg", 484 .desc = "Output file passphrase source", 485 .type = OPTION_ARG, 486 .opt.arg = &pkcs12_config.passargout, 487 }, 488 { 489 .name = "password", 490 .argname = "arg", 491 .desc = "Set import/export password source", 492 .type = OPTION_ARG_FUNC, 493 .opt.argfunc = pkcs12_opt_passarg, 494 }, 495 { 496 .name = "twopass", 497 .desc = "Separate MAC, encryption passwords", 498 .type = OPTION_FLAG, 499 .opt.flag = &pkcs12_config.twopass, 500 }, 501 { NULL }, 502 }; 503 504 static void 505 pkcs12_usage(void) 506 { 507 fprintf(stderr, "usage: pkcs12 [-aes128 | -aes192 | -aes256 |"); 508 fprintf(stderr, " -camellia128 |\n"); 509 fprintf(stderr, " -camellia192 | -camellia256 | -des | -des3 |"); 510 fprintf(stderr, " -idea]\n"); 511 fprintf(stderr, " [-cacerts] [-CAfile file] [-caname name]\n"); 512 fprintf(stderr, " [-CApath directory] [-certfile file]"); 513 fprintf(stderr, " [-certpbe alg]\n"); 514 fprintf(stderr, " [-chain] [-clcerts] [-CSP name] [-descert]"); 515 fprintf(stderr, " [-export]\n"); 516 fprintf(stderr, " [-in file] [-info] [-inkey file] [-keyex]"); 517 fprintf(stderr, " [-keypbe alg]\n"); 518 fprintf(stderr, " [-keysig] [-LMK] [-macalg alg] [-maciter]"); 519 fprintf(stderr, " [-name name]\n"); 520 fprintf(stderr, " [-nocerts] [-nodes] [-noiter] [-nokeys]"); 521 fprintf(stderr, " [-nomac]\n"); 522 fprintf(stderr, " [-nomaciter] [-nomacver] [-noout] [-out file]\n"); 523 fprintf(stderr, " [-passin arg] [-passout arg] [-password arg]"); 524 fprintf(stderr, " [-twopass]\n\n"); 525 options_usage(pkcs12_options); 526 fprintf(stderr, "\n"); 527 } 528 529 int 530 pkcs12_main(int argc, char **argv) 531 { 532 BIO *in = NULL, *out = NULL; 533 PKCS12 *p12 = NULL; 534 char pass[50], macpass[50]; 535 int ret = 1; 536 char *cpass = NULL, *mpass = NULL; 537 char *passin = NULL, *passout = NULL; 538 539 if (single_execution) { 540 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) { 541 perror("pledge"); 542 exit(1); 543 } 544 } 545 546 memset(&pkcs12_config, 0, sizeof(pkcs12_config)); 547 pkcs12_config.cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; 548 pkcs12_config.enc = EVP_des_ede3_cbc(); 549 pkcs12_config.iter = PKCS12_DEFAULT_ITER; 550 pkcs12_config.key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; 551 pkcs12_config.maciter = PKCS12_DEFAULT_ITER; 552 pkcs12_config.macver = 1; 553 554 if (options_parse(argc, argv, pkcs12_options, NULL, NULL) != 0) { 555 pkcs12_usage(); 556 goto end; 557 } 558 559 if (pkcs12_config.passarg != NULL) { 560 if (pkcs12_config.export_cert) 561 pkcs12_config.passargout = pkcs12_config.passarg; 562 else 563 pkcs12_config.passargin = pkcs12_config.passarg; 564 } 565 if (!app_passwd(bio_err, pkcs12_config.passargin, 566 pkcs12_config.passargout, &passin, &passout)) { 567 BIO_printf(bio_err, "Error getting passwords\n"); 568 goto end; 569 } 570 if (cpass == NULL) { 571 if (pkcs12_config.export_cert) 572 cpass = passout; 573 else 574 cpass = passin; 575 } 576 if (cpass != NULL) { 577 mpass = cpass; 578 pkcs12_config.noprompt = 1; 579 } else { 580 cpass = pass; 581 mpass = macpass; 582 } 583 584 if (pkcs12_config.infile == NULL) 585 in = BIO_new_fp(stdin, BIO_NOCLOSE); 586 else 587 in = BIO_new_file(pkcs12_config.infile, "rb"); 588 if (in == NULL) { 589 BIO_printf(bio_err, "Error opening input file %s\n", 590 pkcs12_config.infile ? pkcs12_config.infile : "<stdin>"); 591 perror(pkcs12_config.infile); 592 goto end; 593 } 594 595 if (pkcs12_config.outfile == NULL) { 596 out = BIO_new_fp(stdout, BIO_NOCLOSE); 597 } else 598 out = BIO_new_file(pkcs12_config.outfile, "wb"); 599 if (out == NULL) { 600 BIO_printf(bio_err, "Error opening output file %s\n", 601 pkcs12_config.outfile ? pkcs12_config.outfile : "<stdout>"); 602 perror(pkcs12_config.outfile); 603 goto end; 604 } 605 if (pkcs12_config.twopass) { 606 if (EVP_read_pw_string(macpass, sizeof macpass, 607 "Enter MAC Password:", pkcs12_config.export_cert)) { 608 BIO_printf(bio_err, "Can't read Password\n"); 609 goto end; 610 } 611 } 612 if (pkcs12_config.export_cert) { 613 EVP_PKEY *key = NULL; 614 X509 *ucert = NULL, *x = NULL; 615 STACK_OF(X509) *certs = NULL; 616 const EVP_MD *macmd = NULL; 617 unsigned char *catmp = NULL; 618 int i; 619 620 if ((pkcs12_config.options & (NOCERTS | NOKEYS)) == 621 (NOCERTS | NOKEYS)) { 622 BIO_printf(bio_err, "Nothing to do!\n"); 623 goto export_end; 624 } 625 if (pkcs12_config.options & NOCERTS) 626 pkcs12_config.chain = 0; 627 628 if (!(pkcs12_config.options & NOKEYS)) { 629 key = load_key(bio_err, pkcs12_config.keyname ? 630 pkcs12_config.keyname : pkcs12_config.infile, 631 FORMAT_PEM, 1, passin, "private key"); 632 if (!key) 633 goto export_end; 634 } 635 636 /* Load in all certs in input file */ 637 if (!(pkcs12_config.options & NOCERTS)) { 638 certs = load_certs(bio_err, pkcs12_config.infile, 639 FORMAT_PEM, NULL, "certificates"); 640 if (certs == NULL) 641 goto export_end; 642 643 if (key != NULL) { 644 /* Look for matching private key */ 645 for (i = 0; i < sk_X509_num(certs); i++) { 646 x = sk_X509_value(certs, i); 647 if (X509_check_private_key(x, key)) { 648 ucert = x; 649 /* Zero keyid and alias */ 650 X509_keyid_set1(ucert, NULL, 0); 651 X509_alias_set1(ucert, NULL, 0); 652 /* Remove from list */ 653 (void) sk_X509_delete(certs, i); 654 break; 655 } 656 } 657 if (ucert == NULL) { 658 BIO_printf(bio_err, 659 "No certificate matches private key\n"); 660 goto export_end; 661 } 662 } 663 } 664 665 /* Add any more certificates asked for */ 666 if (pkcs12_config.certfile != NULL) { 667 STACK_OF(X509) *morecerts = NULL; 668 if ((morecerts = load_certs(bio_err, 669 pkcs12_config.certfile, FORMAT_PEM, NULL, 670 "certificates from certfile")) == NULL) 671 goto export_end; 672 while (sk_X509_num(morecerts) > 0) 673 sk_X509_push(certs, sk_X509_shift(morecerts)); 674 sk_X509_free(morecerts); 675 } 676 677 678 /* If chaining get chain from user cert */ 679 if (pkcs12_config.chain) { 680 int vret; 681 STACK_OF(X509) *chain2; 682 X509_STORE *store = X509_STORE_new(); 683 if (store == NULL) { 684 BIO_printf(bio_err, 685 "Memory allocation error\n"); 686 goto export_end; 687 } 688 if (!X509_STORE_load_locations(store, 689 pkcs12_config.CAfile, pkcs12_config.CApath)) 690 X509_STORE_set_default_paths(store); 691 692 vret = get_cert_chain(ucert, store, &chain2); 693 X509_STORE_free(store); 694 695 if (vret == X509_V_OK) { 696 /* Exclude verified certificate */ 697 for (i = 1; i < sk_X509_num(chain2); i++) 698 sk_X509_push(certs, sk_X509_value( 699 chain2, i)); 700 /* Free first certificate */ 701 X509_free(sk_X509_value(chain2, 0)); 702 sk_X509_free(chain2); 703 } else { 704 if (vret != X509_V_ERR_UNSPECIFIED) 705 BIO_printf(bio_err, 706 "Error %s getting chain.\n", 707 X509_verify_cert_error_string( 708 vret)); 709 else 710 ERR_print_errors(bio_err); 711 goto export_end; 712 } 713 } 714 /* Add any CA names */ 715 716 for (i = 0; i < sk_OPENSSL_STRING_num(pkcs12_config.canames); 717 i++) { 718 catmp = (unsigned char *) sk_OPENSSL_STRING_value( 719 pkcs12_config.canames, i); 720 X509_alias_set1(sk_X509_value(certs, i), catmp, -1); 721 } 722 723 if (pkcs12_config.csp_name != NULL && key != NULL) 724 EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name, 725 MBSTRING_ASC, 726 (unsigned char *) pkcs12_config.csp_name, -1); 727 728 if (pkcs12_config.add_lmk && key != NULL) 729 EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, 730 -1); 731 732 if (!pkcs12_config.noprompt && 733 EVP_read_pw_string(pass, sizeof pass, 734 "Enter Export Password:", 1)) { 735 BIO_printf(bio_err, "Can't read Password\n"); 736 goto export_end; 737 } 738 if (!pkcs12_config.twopass) 739 strlcpy(macpass, pass, sizeof macpass); 740 741 742 p12 = PKCS12_create(cpass, pkcs12_config.name, key, ucert, 743 certs, pkcs12_config.key_pbe, pkcs12_config.cert_pbe, 744 pkcs12_config.iter, -1, pkcs12_config.keytype); 745 746 if (p12 == NULL) { 747 ERR_print_errors(bio_err); 748 goto export_end; 749 } 750 if (pkcs12_config.macalg != NULL) { 751 macmd = EVP_get_digestbyname(pkcs12_config.macalg); 752 if (macmd == NULL) { 753 BIO_printf(bio_err, 754 "Unknown digest algorithm %s\n", 755 pkcs12_config.macalg); 756 } 757 } 758 if (pkcs12_config.maciter != -1) 759 PKCS12_set_mac(p12, mpass, -1, NULL, 0, 760 pkcs12_config.maciter, macmd); 761 762 i2d_PKCS12_bio(out, p12); 763 764 ret = 0; 765 766 export_end: 767 EVP_PKEY_free(key); 768 sk_X509_pop_free(certs, X509_free); 769 X509_free(ucert); 770 771 goto end; 772 773 } 774 if ((p12 = d2i_PKCS12_bio(in, NULL)) == NULL) { 775 ERR_print_errors(bio_err); 776 goto end; 777 } 778 if (!pkcs12_config.noprompt && EVP_read_pw_string(pass, sizeof pass, 779 "Enter Import Password:", 0)) { 780 BIO_printf(bio_err, "Can't read Password\n"); 781 goto end; 782 } 783 784 if (!pkcs12_config.twopass) 785 strlcpy(macpass, pass, sizeof macpass); 786 787 if ((pkcs12_config.options & INFO) != 0 && PKCS12_mac_present(p12)) { 788 const ASN1_INTEGER *iter; 789 790 PKCS12_get0_mac(NULL, NULL, NULL, &iter, p12); 791 BIO_printf(bio_err, "MAC Iteration %ld\n", 792 iter != NULL ? ASN1_INTEGER_get(iter) : 1); 793 } 794 if (pkcs12_config.macver) { 795 /* If we enter empty password try no password first */ 796 if (!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) { 797 /* If mac and crypto pass the same set it to NULL too */ 798 if (!pkcs12_config.twopass) 799 cpass = NULL; 800 } else if (!PKCS12_verify_mac(p12, mpass, -1)) { 801 BIO_printf(bio_err, 802 "Mac verify error: invalid password?\n"); 803 ERR_print_errors(bio_err); 804 goto end; 805 } 806 BIO_printf(bio_err, "MAC verified OK\n"); 807 } 808 if (!dump_certs_keys_p12(out, p12, cpass, -1, pkcs12_config.options, 809 passout)) { 810 BIO_printf(bio_err, "Error outputting keys and certificates\n"); 811 ERR_print_errors(bio_err); 812 goto end; 813 } 814 ret = 0; 815 end: 816 PKCS12_free(p12); 817 BIO_free(in); 818 BIO_free_all(out); 819 sk_OPENSSL_STRING_free(pkcs12_config.canames); 820 free(passin); 821 free(passout); 822 823 return (ret); 824 } 825 826 static int 827 dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int passlen, int options, 828 char *pempass) 829 { 830 STACK_OF(PKCS7) *asafes = NULL; 831 STACK_OF(PKCS12_SAFEBAG) *bags; 832 int i, bagnid; 833 int ret = 0; 834 PKCS7 *p7; 835 836 if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL) 837 return 0; 838 for (i = 0; i < sk_PKCS7_num(asafes); i++) { 839 p7 = sk_PKCS7_value(asafes, i); 840 bagnid = OBJ_obj2nid(p7->type); 841 if (bagnid == NID_pkcs7_data) { 842 bags = PKCS12_unpack_p7data(p7); 843 if (options & INFO) 844 BIO_printf(bio_err, "PKCS7 Data\n"); 845 } else if (bagnid == NID_pkcs7_encrypted) { 846 if (options & INFO) { 847 BIO_printf(bio_err, "PKCS7 Encrypted data: "); 848 alg_print(bio_err, 849 p7->d.encrypted->enc_data->algorithm); 850 } 851 bags = PKCS12_unpack_p7encdata(p7, pass, passlen); 852 } else 853 continue; 854 if (bags == NULL) 855 goto err; 856 if (!dump_certs_pkeys_bags(out, bags, pass, passlen, 857 options, pempass)) { 858 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 859 goto err; 860 } 861 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 862 bags = NULL; 863 } 864 ret = 1; 865 866 err: 867 sk_PKCS7_pop_free(asafes, PKCS7_free); 868 return ret; 869 } 870 871 static int 872 dump_certs_pkeys_bags(BIO *out, const STACK_OF(PKCS12_SAFEBAG) *bags, 873 char *pass, int passlen, int options, char *pempass) 874 { 875 int i; 876 877 for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { 878 if (!dump_certs_pkeys_bag(out, 879 sk_PKCS12_SAFEBAG_value(bags, i), 880 pass, passlen, 881 options, pempass)) 882 return 0; 883 } 884 return 1; 885 } 886 887 static int 888 dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bag, char *pass, int passlen, 889 int options, char *pempass) 890 { 891 EVP_PKEY *pkey; 892 const STACK_OF(X509_ATTRIBUTE) *attrs; 893 X509 *x509; 894 895 attrs = PKCS12_SAFEBAG_get0_attrs(bag); 896 897 switch (PKCS12_SAFEBAG_get_nid(bag)) { 898 case NID_keyBag: 899 { 900 const PKCS8_PRIV_KEY_INFO *p8; 901 902 if (options & INFO) 903 BIO_printf(bio_err, "Key bag\n"); 904 if (options & NOKEYS) 905 return 1; 906 print_attribs(out, attrs, "Bag Attributes"); 907 if ((p8 = PKCS12_SAFEBAG_get0_p8inf(bag)) == NULL) 908 return 0; 909 if ((pkey = EVP_PKCS82PKEY(p8)) == NULL) 910 return 0; 911 print_attribs(out, PKCS8_pkey_get0_attrs(p8), "Key Attributes"); 912 PEM_write_bio_PrivateKey(out, pkey, pkcs12_config.enc, NULL, 0, 913 NULL, pempass); 914 EVP_PKEY_free(pkey); 915 break; 916 } 917 918 case NID_pkcs8ShroudedKeyBag: 919 { 920 PKCS8_PRIV_KEY_INFO *p8; 921 922 if (options & INFO) { 923 const X509_SIG *tp8; 924 const X509_ALGOR *tp8alg; 925 926 BIO_printf(bio_err, "Shrouded Keybag: "); 927 if ((tp8 = PKCS12_SAFEBAG_get0_pkcs8(bag)) == NULL) 928 return 0; 929 X509_SIG_get0(tp8, &tp8alg, NULL); 930 alg_print(bio_err, tp8alg); 931 } 932 if (options & NOKEYS) 933 return 1; 934 print_attribs(out, attrs, "Bag Attributes"); 935 if ((p8 = PKCS12_decrypt_skey(bag, pass, passlen)) == NULL) 936 return 0; 937 if ((pkey = EVP_PKCS82PKEY(p8)) == NULL) { 938 PKCS8_PRIV_KEY_INFO_free(p8); 939 return 0; 940 } 941 print_attribs(out, PKCS8_pkey_get0_attrs(p8), "Key Attributes"); 942 PKCS8_PRIV_KEY_INFO_free(p8); 943 PEM_write_bio_PrivateKey(out, pkey, pkcs12_config.enc, NULL, 0, 944 NULL, pempass); 945 EVP_PKEY_free(pkey); 946 break; 947 } 948 949 case NID_certBag: 950 if (options & INFO) 951 BIO_printf(bio_err, "Certificate bag\n"); 952 if (options & NOCERTS) 953 return 1; 954 if (PKCS12_SAFEBAG_get0_attr(bag, NID_localKeyID) != NULL) { 955 if (options & CACERTS) 956 return 1; 957 } else if (options & CLCERTS) 958 return 1; 959 print_attribs(out, attrs, "Bag Attributes"); 960 if (PKCS12_SAFEBAG_get_bag_nid(bag) != NID_x509Certificate) 961 return 1; 962 if ((x509 = PKCS12_certbag2x509(bag)) == NULL) 963 return 0; 964 dump_cert_text(out, x509); 965 PEM_write_bio_X509(out, x509); 966 X509_free(x509); 967 break; 968 969 case NID_safeContentsBag: 970 if (options & INFO) 971 BIO_printf(bio_err, "Safe Contents bag\n"); 972 print_attribs(out, attrs, "Bag Attributes"); 973 return dump_certs_pkeys_bags(out, PKCS12_SAFEBAG_get0_safes(bag), 974 pass, passlen, options, pempass); 975 976 default: 977 BIO_printf(bio_err, "Warning unsupported bag type: "); 978 i2a_ASN1_OBJECT(bio_err, PKCS12_SAFEBAG_get0_type(bag)); 979 BIO_printf(bio_err, "\n"); 980 return 1; 981 break; 982 } 983 return 1; 984 } 985 986 /* Given a single certificate return a verified chain or NULL if error */ 987 static int 988 get_cert_chain(X509 *cert, X509_STORE *store, STACK_OF(X509) **out_chain) 989 { 990 X509_STORE_CTX *store_ctx = NULL; 991 STACK_OF(X509) *chain = NULL; 992 int ret = X509_V_ERR_UNSPECIFIED; 993 994 if ((store_ctx = X509_STORE_CTX_new()) == NULL) 995 goto err; 996 if (!X509_STORE_CTX_init(store_ctx, store, cert, NULL)) 997 goto err; 998 999 if (X509_verify_cert(store_ctx) > 0) { 1000 if ((chain = X509_STORE_CTX_get1_chain(store_ctx)) == NULL) 1001 goto err; 1002 } 1003 ret = X509_STORE_CTX_get_error(store_ctx); 1004 1005 err: 1006 X509_STORE_CTX_free(store_ctx); 1007 *out_chain = chain; 1008 1009 return ret; 1010 } 1011 1012 static int 1013 alg_print(BIO *x, const X509_ALGOR *alg) 1014 { 1015 PBEPARAM *pbe; 1016 const unsigned char *p; 1017 1018 p = alg->parameter->value.sequence->data; 1019 pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length); 1020 if (pbe == NULL) 1021 return 1; 1022 BIO_printf(bio_err, "%s, Iteration %ld\n", 1023 OBJ_nid2ln(OBJ_obj2nid(alg->algorithm)), 1024 ASN1_INTEGER_get(pbe->iter)); 1025 PBEPARAM_free(pbe); 1026 return 1; 1027 } 1028 1029 /* Generalised attribute print: handle PKCS#8 and bag attributes */ 1030 static void 1031 print_attribute(BIO *out, const ASN1_TYPE *av) 1032 { 1033 char *value; 1034 1035 switch (av->type) { 1036 case V_ASN1_BMPSTRING: 1037 value = OPENSSL_uni2asc( 1038 av->value.bmpstring->data, 1039 av->value.bmpstring->length); 1040 BIO_printf(out, "%s\n", value); 1041 free(value); 1042 break; 1043 1044 case V_ASN1_OCTET_STRING: 1045 hex_prin(out, av->value.octet_string->data, 1046 av->value.octet_string->length); 1047 BIO_printf(out, "\n"); 1048 break; 1049 1050 case V_ASN1_BIT_STRING: 1051 hex_prin(out, av->value.bit_string->data, 1052 av->value.bit_string->length); 1053 BIO_printf(out, "\n"); 1054 break; 1055 1056 default: 1057 BIO_printf(out, "<Unsupported tag %d>\n", 1058 av->type); 1059 break; 1060 } 1061 } 1062 1063 static int 1064 print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst, 1065 const char *name) 1066 { 1067 X509_ATTRIBUTE *attr; 1068 ASN1_TYPE *av; 1069 int i, j, attr_nid; 1070 1071 if (attrlst == NULL) { 1072 BIO_printf(out, "%s: <No Attributes>\n", name); 1073 return 1; 1074 } 1075 if (!sk_X509_ATTRIBUTE_num(attrlst)) { 1076 BIO_printf(out, "%s: <Empty Attributes>\n", name); 1077 return 1; 1078 } 1079 BIO_printf(out, "%s\n", name); 1080 for (i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) { 1081 ASN1_OBJECT *obj; 1082 1083 attr = sk_X509_ATTRIBUTE_value(attrlst, i); 1084 obj = X509_ATTRIBUTE_get0_object(attr); 1085 attr_nid = OBJ_obj2nid(X509_ATTRIBUTE_get0_object(attr)); 1086 BIO_printf(out, " "); 1087 if (attr_nid == NID_undef) { 1088 i2a_ASN1_OBJECT(out, obj); 1089 BIO_printf(out, ": "); 1090 } else 1091 BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid)); 1092 1093 if (X509_ATTRIBUTE_count(attr)) { 1094 for (j = 0; j < X509_ATTRIBUTE_count(attr); j++) { 1095 av = X509_ATTRIBUTE_get0_type(attr, j); 1096 print_attribute(out, av); 1097 } 1098 } else 1099 BIO_printf(out, "<No Values>\n"); 1100 } 1101 return 1; 1102 } 1103 1104 static void 1105 hex_prin(BIO *out, unsigned char *buf, int len) 1106 { 1107 int i; 1108 1109 for (i = 0; i < len; i++) 1110 BIO_printf(out, "%02X ", buf[i]); 1111 } 1112 1113 static int 1114 set_pbe(BIO *err, int *ppbe, const char *str) 1115 { 1116 if (str == NULL) 1117 return 0; 1118 if (strcmp(str, "NONE") == 0) { 1119 *ppbe = -1; 1120 return 1; 1121 } 1122 *ppbe = OBJ_txt2nid(str); 1123 if (*ppbe == NID_undef) { 1124 BIO_printf(bio_err, "Unknown PBE algorithm %s\n", str); 1125 return 0; 1126 } 1127 return 1; 1128 } 1129 1130 #endif 1131