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