1 /* pkcs12.c */ 2 #if !defined(NO_DES) && !defined(NO_SHA1) 3 4 /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL 5 * project 1999. 6 */ 7 /* ==================================================================== 8 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in 19 * the documentation and/or other materials provided with the 20 * distribution. 21 * 22 * 3. All advertising materials mentioning features or use of this 23 * software must display the following acknowledgment: 24 * "This product includes software developed by the OpenSSL Project 25 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 26 * 27 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 28 * endorse or promote products derived from this software without 29 * prior written permission. For written permission, please contact 30 * licensing@OpenSSL.org. 31 * 32 * 5. Products derived from this software may not be called "OpenSSL" 33 * nor may "OpenSSL" appear in their names without prior written 34 * permission of the OpenSSL Project. 35 * 36 * 6. Redistributions of any form whatsoever must retain the following 37 * acknowledgment: 38 * "This product includes software developed by the OpenSSL Project 39 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 42 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 44 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 45 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 46 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 47 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 48 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 49 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 50 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 51 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 52 * OF THE POSSIBILITY OF SUCH DAMAGE. 53 * ==================================================================== 54 * 55 * This product includes cryptographic software written by Eric Young 56 * (eay@cryptsoft.com). This product includes software written by Tim 57 * Hudson (tjh@cryptsoft.com). 58 * 59 */ 60 61 #include <stdio.h> 62 #include <stdlib.h> 63 #include <string.h> 64 #include "apps.h" 65 #include <openssl/crypto.h> 66 #include <openssl/err.h> 67 #include <openssl/pem.h> 68 #include <openssl/pkcs12.h> 69 70 #define PROG pkcs12_main 71 72 EVP_CIPHER *enc; 73 74 75 #define NOKEYS 0x1 76 #define NOCERTS 0x2 77 #define INFO 0x4 78 #define CLCERTS 0x8 79 #define CACERTS 0x10 80 81 int get_cert_chain(X509 *cert, STACK_OF(X509) **chain); 82 int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int passlen, int options, char *pempass); 83 int dump_certs_pkeys_bags(BIO *out, STACK *bags, char *pass, int passlen, int options, char *pempass); 84 int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass, int passlen, int options, char *pempass); 85 int print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst, char *name); 86 void hex_prin(BIO *out, unsigned char *buf, int len); 87 int alg_print(BIO *x, X509_ALGOR *alg); 88 int cert_load(BIO *in, STACK_OF(X509) *sk); 89 90 int MAIN(int, char **); 91 92 int MAIN(int argc, char **argv) 93 { 94 char *infile=NULL, *outfile=NULL, *keyname = NULL; 95 char *certfile=NULL; 96 BIO *in=NULL, *out = NULL, *inkey = NULL, *certsin = NULL; 97 char **args; 98 char *name = NULL; 99 PKCS12 *p12 = NULL; 100 char pass[50], macpass[50]; 101 int export_cert = 0; 102 int options = 0; 103 int chain = 0; 104 int badarg = 0; 105 int iter = PKCS12_DEFAULT_ITER; 106 int maciter = PKCS12_DEFAULT_ITER; 107 int twopass = 0; 108 int keytype = 0; 109 int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; 110 int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; 111 int ret = 1; 112 int macver = 1; 113 int noprompt = 0; 114 STACK *canames = NULL; 115 char *cpass = NULL, *mpass = NULL; 116 char *passargin = NULL, *passargout = NULL, *passarg = NULL; 117 char *passin = NULL, *passout = NULL; 118 char *inrand = NULL; 119 120 apps_startup(); 121 122 enc = EVP_des_ede3_cbc(); 123 if (bio_err == NULL ) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE); 124 125 args = argv + 1; 126 127 128 while (*args) { 129 if (*args[0] == '-') { 130 if (!strcmp (*args, "-nokeys")) options |= NOKEYS; 131 else if (!strcmp (*args, "-keyex")) keytype = KEY_EX; 132 else if (!strcmp (*args, "-keysig")) keytype = KEY_SIG; 133 else if (!strcmp (*args, "-nocerts")) options |= NOCERTS; 134 else if (!strcmp (*args, "-clcerts")) options |= CLCERTS; 135 else if (!strcmp (*args, "-cacerts")) options |= CACERTS; 136 else if (!strcmp (*args, "-noout")) options |= (NOKEYS|NOCERTS); 137 else if (!strcmp (*args, "-info")) options |= INFO; 138 else if (!strcmp (*args, "-chain")) chain = 1; 139 else if (!strcmp (*args, "-twopass")) twopass = 1; 140 else if (!strcmp (*args, "-nomacver")) macver = 0; 141 else if (!strcmp (*args, "-descert")) 142 cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; 143 else if (!strcmp (*args, "-export")) export_cert = 1; 144 else if (!strcmp (*args, "-des")) enc=EVP_des_cbc(); 145 #ifndef NO_IDEA 146 else if (!strcmp (*args, "-idea")) enc=EVP_idea_cbc(); 147 #endif 148 else if (!strcmp (*args, "-des3")) enc = EVP_des_ede3_cbc(); 149 else if (!strcmp (*args, "-noiter")) iter = 1; 150 else if (!strcmp (*args, "-maciter")) 151 maciter = PKCS12_DEFAULT_ITER; 152 else if (!strcmp (*args, "-nomaciter")) 153 maciter = 1; 154 else if (!strcmp (*args, "-nodes")) enc=NULL; 155 else if (!strcmp (*args, "-certpbe")) { 156 if (args[1]) { 157 args++; 158 cert_pbe=OBJ_txt2nid(*args); 159 if(cert_pbe == NID_undef) { 160 BIO_printf(bio_err, 161 "Unknown PBE algorithm %s\n", *args); 162 badarg = 1; 163 } 164 } else badarg = 1; 165 } else if (!strcmp (*args, "-keypbe")) { 166 if (args[1]) { 167 args++; 168 key_pbe=OBJ_txt2nid(*args); 169 if(key_pbe == NID_undef) { 170 BIO_printf(bio_err, 171 "Unknown PBE algorithm %s\n", *args); 172 badarg = 1; 173 } 174 } else badarg = 1; 175 } else if (!strcmp (*args, "-rand")) { 176 if (args[1]) { 177 args++; 178 inrand = *args; 179 } else badarg = 1; 180 } else if (!strcmp (*args, "-inkey")) { 181 if (args[1]) { 182 args++; 183 keyname = *args; 184 } else badarg = 1; 185 } else if (!strcmp (*args, "-certfile")) { 186 if (args[1]) { 187 args++; 188 certfile = *args; 189 } else badarg = 1; 190 } else if (!strcmp (*args, "-name")) { 191 if (args[1]) { 192 args++; 193 name = *args; 194 } else badarg = 1; 195 } else if (!strcmp (*args, "-caname")) { 196 if (args[1]) { 197 args++; 198 if (!canames) canames = sk_new(NULL); 199 sk_push(canames, *args); 200 } else badarg = 1; 201 } else if (!strcmp (*args, "-in")) { 202 if (args[1]) { 203 args++; 204 infile = *args; 205 } else badarg = 1; 206 } else if (!strcmp (*args, "-out")) { 207 if (args[1]) { 208 args++; 209 outfile = *args; 210 } else badarg = 1; 211 } else if (!strcmp(*args,"-passin")) { 212 if (args[1]) { 213 args++; 214 passargin = *args; 215 } else badarg = 1; 216 } else if (!strcmp(*args,"-passout")) { 217 if (args[1]) { 218 args++; 219 passargout = *args; 220 } else badarg = 1; 221 } else if (!strcmp (*args, "-password")) { 222 if (args[1]) { 223 args++; 224 passarg = *args; 225 noprompt = 1; 226 } else badarg = 1; 227 } else badarg = 1; 228 229 } else badarg = 1; 230 args++; 231 } 232 233 if (badarg) { 234 BIO_printf (bio_err, "Usage: pkcs12 [options]\n"); 235 BIO_printf (bio_err, "where options are\n"); 236 BIO_printf (bio_err, "-export output PKCS12 file\n"); 237 BIO_printf (bio_err, "-chain add certificate chain\n"); 238 BIO_printf (bio_err, "-inkey file private key if not infile\n"); 239 BIO_printf (bio_err, "-certfile f add all certs in f\n"); 240 BIO_printf (bio_err, "-name \"name\" use name as friendly name\n"); 241 BIO_printf (bio_err, "-caname \"nm\" use nm as CA friendly name (can be used more than once).\n"); 242 BIO_printf (bio_err, "-in infile input filename\n"); 243 BIO_printf (bio_err, "-out outfile output filename\n"); 244 BIO_printf (bio_err, "-noout don't output anything, just verify.\n"); 245 BIO_printf (bio_err, "-nomacver don't verify MAC.\n"); 246 BIO_printf (bio_err, "-nocerts don't output certificates.\n"); 247 BIO_printf (bio_err, "-clcerts only output client certificates.\n"); 248 BIO_printf (bio_err, "-cacerts only output CA certificates.\n"); 249 BIO_printf (bio_err, "-nokeys don't output private keys.\n"); 250 BIO_printf (bio_err, "-info give info about PKCS#12 structure.\n"); 251 BIO_printf (bio_err, "-des encrypt private keys with DES\n"); 252 BIO_printf (bio_err, "-des3 encrypt private keys with triple DES (default)\n"); 253 #ifndef NO_IDEA 254 BIO_printf (bio_err, "-idea encrypt private keys with idea\n"); 255 #endif 256 BIO_printf (bio_err, "-nodes don't encrypt private keys\n"); 257 BIO_printf (bio_err, "-noiter don't use encryption iteration\n"); 258 BIO_printf (bio_err, "-maciter use MAC iteration\n"); 259 BIO_printf (bio_err, "-twopass separate MAC, encryption passwords\n"); 260 BIO_printf (bio_err, "-descert encrypt PKCS#12 certificates with triple DES (default RC2-40)\n"); 261 BIO_printf (bio_err, "-certpbe alg specify certificate PBE algorithm (default RC2-40)\n"); 262 BIO_printf (bio_err, "-keypbe alg specify private key PBE algorithm (default 3DES)\n"); 263 BIO_printf (bio_err, "-keyex set MS key exchange type\n"); 264 BIO_printf (bio_err, "-keysig set MS key signature type\n"); 265 BIO_printf (bio_err, "-password p set import/export password source\n"); 266 BIO_printf (bio_err, "-passin p input file pass phrase source\n"); 267 BIO_printf (bio_err, "-passout p output file pass phrase source\n"); 268 BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); 269 BIO_printf(bio_err, " load the file (or the files in the directory) into\n"); 270 BIO_printf(bio_err, " the random number generator\n"); 271 goto end; 272 } 273 274 if(passarg) { 275 if(export_cert) passargout = passarg; 276 else passargin = passarg; 277 } 278 279 if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { 280 BIO_printf(bio_err, "Error getting passwords\n"); 281 goto end; 282 } 283 284 if(!cpass) { 285 if(export_cert) cpass = passout; 286 else cpass = passin; 287 } 288 289 if(cpass) { 290 mpass = cpass; 291 noprompt = 1; 292 } else { 293 cpass = pass; 294 mpass = macpass; 295 } 296 297 if(export_cert || inrand) { 298 app_RAND_load_file(NULL, bio_err, (inrand != NULL)); 299 if (inrand != NULL) 300 BIO_printf(bio_err,"%ld semi-random bytes loaded\n", 301 app_RAND_load_files(inrand)); 302 } 303 ERR_load_crypto_strings(); 304 305 #ifdef CRYPTO_MDEBUG 306 CRYPTO_push_info("read files"); 307 #endif 308 309 if (!infile) in = BIO_new_fp(stdin, BIO_NOCLOSE); 310 else in = BIO_new_file(infile, "rb"); 311 if (!in) { 312 BIO_printf(bio_err, "Error opening input file %s\n", 313 infile ? infile : "<stdin>"); 314 perror (infile); 315 goto end; 316 } 317 318 if (certfile) { 319 if(!(certsin = BIO_new_file(certfile, "r"))) { 320 BIO_printf(bio_err, "Can't open certificate file %s\n", certfile); 321 perror (certfile); 322 goto end; 323 } 324 } 325 326 if (keyname) { 327 if(!(inkey = BIO_new_file(keyname, "r"))) { 328 BIO_printf(bio_err, "Can't key certificate file %s\n", keyname); 329 perror (keyname); 330 goto end; 331 } 332 } 333 334 #ifdef CRYPTO_MDEBUG 335 CRYPTO_pop_info(); 336 CRYPTO_push_info("write files"); 337 #endif 338 339 if (!outfile) out = BIO_new_fp(stdout, BIO_NOCLOSE); 340 else out = BIO_new_file(outfile, "wb"); 341 if (!out) { 342 BIO_printf(bio_err, "Error opening output file %s\n", 343 outfile ? outfile : "<stdout>"); 344 perror (outfile); 345 goto end; 346 } 347 if (twopass) { 348 #ifdef CRYPTO_MDEBUG 349 CRYPTO_push_info("read MAC password"); 350 #endif 351 if(EVP_read_pw_string (macpass, 50, "Enter MAC Password:", export_cert)) 352 { 353 BIO_printf (bio_err, "Can't read Password\n"); 354 goto end; 355 } 356 #ifdef CRYPTO_MDEBUG 357 CRYPTO_pop_info(); 358 #endif 359 } 360 361 if (export_cert) { 362 EVP_PKEY *key; 363 STACK *bags, *safes; 364 PKCS12_SAFEBAG *bag; 365 PKCS8_PRIV_KEY_INFO *p8; 366 PKCS7 *authsafe; 367 X509 *ucert = NULL; 368 STACK_OF(X509) *certs=NULL; 369 char *catmp; 370 int i; 371 unsigned char keyid[EVP_MAX_MD_SIZE]; 372 unsigned int keyidlen = 0; 373 374 #ifdef CRYPTO_MDEBUG 375 CRYPTO_push_info("process -export_cert"); 376 #endif 377 key = PEM_read_bio_PrivateKey(inkey ? inkey : in, NULL, NULL, passin); 378 if (!inkey) (void) BIO_reset(in); 379 else BIO_free(inkey); 380 if (!key) { 381 BIO_printf (bio_err, "Error loading private key\n"); 382 ERR_print_errors(bio_err); 383 goto end; 384 } 385 386 certs = sk_X509_new(NULL); 387 388 /* Load in all certs in input file */ 389 if(!cert_load(in, certs)) { 390 BIO_printf(bio_err, "Error loading certificates from input\n"); 391 ERR_print_errors(bio_err); 392 goto end; 393 } 394 395 for(i = 0; i < sk_X509_num(certs); i++) { 396 ucert = sk_X509_value(certs, i); 397 if(X509_check_private_key(ucert, key)) { 398 X509_digest(ucert, EVP_sha1(), keyid, &keyidlen); 399 break; 400 } 401 } 402 403 if(!keyidlen) { 404 BIO_printf(bio_err, "No certificate matches private key\n"); 405 goto end; 406 } 407 408 bags = sk_new (NULL); 409 410 /* Add any more certificates asked for */ 411 if (certsin) { 412 if(!cert_load(certsin, certs)) { 413 BIO_printf(bio_err, "Error loading certificates from certfile\n"); 414 ERR_print_errors(bio_err); 415 goto end; 416 } 417 BIO_free(certsin); 418 } 419 420 /* If chaining get chain from user cert */ 421 if (chain) { 422 int vret; 423 STACK_OF(X509) *chain2; 424 vret = get_cert_chain (ucert, &chain2); 425 if (vret) { 426 BIO_printf (bio_err, "Error %s getting chain.\n", 427 X509_verify_cert_error_string(vret)); 428 goto end; 429 } 430 /* Exclude verified certificate */ 431 for (i = 1; i < sk_X509_num (chain2) ; i++) 432 sk_X509_push(certs, sk_X509_value (chain2, i)); 433 sk_X509_free(chain2); 434 435 } 436 437 /* We now have loads of certificates: include them all */ 438 for(i = 0; i < sk_X509_num(certs); i++) { 439 X509 *cert = NULL; 440 cert = sk_X509_value(certs, i); 441 bag = M_PKCS12_x5092certbag(cert); 442 /* If it matches private key set id */ 443 if(cert == ucert) { 444 if(name) PKCS12_add_friendlyname(bag, name, -1); 445 PKCS12_add_localkeyid(bag, keyid, keyidlen); 446 } else if((catmp = sk_shift(canames))) 447 PKCS12_add_friendlyname(bag, catmp, -1); 448 sk_push(bags, (char *)bag); 449 } 450 sk_X509_pop_free(certs, X509_free); 451 if (canames) sk_free(canames); 452 453 if(!noprompt && 454 EVP_read_pw_string(pass, 50, "Enter Export Password:", 1)) { 455 BIO_printf (bio_err, "Can't read Password\n"); 456 goto end; 457 } 458 if (!twopass) strcpy(macpass, pass); 459 /* Turn certbags into encrypted authsafe */ 460 authsafe = PKCS12_pack_p7encdata(cert_pbe, cpass, -1, NULL, 0, 461 iter, bags); 462 sk_pop_free(bags, PKCS12_SAFEBAG_free); 463 464 if (!authsafe) { 465 ERR_print_errors (bio_err); 466 goto end; 467 } 468 469 safes = sk_new (NULL); 470 sk_push (safes, (char *)authsafe); 471 472 /* Make a shrouded key bag */ 473 p8 = EVP_PKEY2PKCS8 (key); 474 EVP_PKEY_free(key); 475 if(keytype) PKCS8_add_keyusage(p8, keytype); 476 bag = PKCS12_MAKE_SHKEYBAG(key_pbe, cpass, -1, NULL, 0, iter, p8); 477 PKCS8_PRIV_KEY_INFO_free(p8); 478 if (name) PKCS12_add_friendlyname (bag, name, -1); 479 PKCS12_add_localkeyid (bag, keyid, keyidlen); 480 bags = sk_new(NULL); 481 sk_push (bags, (char *)bag); 482 /* Turn it into unencrypted safe bag */ 483 authsafe = PKCS12_pack_p7data (bags); 484 sk_pop_free(bags, PKCS12_SAFEBAG_free); 485 sk_push (safes, (char *)authsafe); 486 487 p12 = PKCS12_init (NID_pkcs7_data); 488 489 M_PKCS12_pack_authsafes (p12, safes); 490 491 sk_pop_free(safes, PKCS7_free); 492 493 PKCS12_set_mac (p12, mpass, -1, NULL, 0, maciter, NULL); 494 495 i2d_PKCS12_bio (out, p12); 496 497 PKCS12_free(p12); 498 499 ret = 0; 500 501 #ifdef CRYPTO_MDEBUG 502 CRYPTO_pop_info(); 503 #endif 504 goto end; 505 506 } 507 508 if (!(p12 = d2i_PKCS12_bio (in, NULL))) { 509 ERR_print_errors(bio_err); 510 goto end; 511 } 512 513 #ifdef CRYPTO_MDEBUG 514 CRYPTO_push_info("read import password"); 515 #endif 516 if(!noprompt && EVP_read_pw_string(pass, 50, "Enter Import Password:", 0)) { 517 BIO_printf (bio_err, "Can't read Password\n"); 518 goto end; 519 } 520 #ifdef CRYPTO_MDEBUG 521 CRYPTO_pop_info(); 522 #endif 523 524 if (!twopass) strcpy(macpass, pass); 525 526 if (options & INFO) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1); 527 if(macver) { 528 #ifdef CRYPTO_MDEBUG 529 CRYPTO_push_info("verify MAC"); 530 #endif 531 if (!PKCS12_verify_mac (p12, mpass, -1)) { 532 BIO_printf (bio_err, "Mac verify error: invalid password?\n"); 533 ERR_print_errors (bio_err); 534 goto end; 535 } else BIO_printf (bio_err, "MAC verified OK\n"); 536 #ifdef CRYPTO_MDEBUG 537 CRYPTO_pop_info(); 538 #endif 539 } 540 541 #ifdef CRYPTO_MDEBUG 542 CRYPTO_push_info("output keys and certificates"); 543 #endif 544 if (!dump_certs_keys_p12 (out, p12, cpass, -1, options, passout)) { 545 BIO_printf(bio_err, "Error outputting keys and certificates\n"); 546 ERR_print_errors (bio_err); 547 goto end; 548 } 549 #ifdef CRYPTO_MDEBUG 550 CRYPTO_pop_info(); 551 #endif 552 PKCS12_free(p12); 553 ret = 0; 554 end: 555 if(export_cert || inrand) app_RAND_write_file(NULL, bio_err); 556 #ifdef CRYPTO_MDEBUG 557 CRYPTO_remove_all_info(); 558 #endif 559 BIO_free(in); 560 BIO_free(out); 561 if(passin) Free(passin); 562 if(passout) Free(passout); 563 EXIT(ret); 564 } 565 566 int dump_certs_keys_p12 (BIO *out, PKCS12 *p12, char *pass, 567 int passlen, int options, char *pempass) 568 { 569 STACK *asafes, *bags; 570 int i, bagnid; 571 PKCS7 *p7; 572 if (!( asafes = M_PKCS12_unpack_authsafes (p12))) return 0; 573 for (i = 0; i < sk_num (asafes); i++) { 574 p7 = (PKCS7 *) sk_value (asafes, i); 575 bagnid = OBJ_obj2nid (p7->type); 576 if (bagnid == NID_pkcs7_data) { 577 bags = M_PKCS12_unpack_p7data (p7); 578 if (options & INFO) BIO_printf (bio_err, "PKCS7 Data\n"); 579 } else if (bagnid == NID_pkcs7_encrypted) { 580 if (options & INFO) { 581 BIO_printf (bio_err, "PKCS7 Encrypted data: "); 582 alg_print (bio_err, 583 p7->d.encrypted->enc_data->algorithm); 584 } 585 bags = M_PKCS12_unpack_p7encdata (p7, pass, passlen); 586 } else continue; 587 if (!bags) return 0; 588 if (!dump_certs_pkeys_bags (out, bags, pass, passlen, 589 options, pempass)) { 590 sk_pop_free (bags, PKCS12_SAFEBAG_free); 591 return 0; 592 } 593 sk_pop_free (bags, PKCS12_SAFEBAG_free); 594 } 595 sk_pop_free (asafes, PKCS7_free); 596 return 1; 597 } 598 599 int dump_certs_pkeys_bags (BIO *out, STACK *bags, char *pass, 600 int passlen, int options, char *pempass) 601 { 602 int i; 603 for (i = 0; i < sk_num (bags); i++) { 604 if (!dump_certs_pkeys_bag (out, 605 (PKCS12_SAFEBAG *)sk_value (bags, i), pass, passlen, 606 options, pempass)) return 0; 607 } 608 return 1; 609 } 610 611 int dump_certs_pkeys_bag (BIO *out, PKCS12_SAFEBAG *bag, char *pass, 612 int passlen, int options, char *pempass) 613 { 614 EVP_PKEY *pkey; 615 PKCS8_PRIV_KEY_INFO *p8; 616 X509 *x509; 617 618 switch (M_PKCS12_bag_type(bag)) 619 { 620 case NID_keyBag: 621 if (options & INFO) BIO_printf (bio_err, "Key bag\n"); 622 if (options & NOKEYS) return 1; 623 print_attribs (out, bag->attrib, "Bag Attributes"); 624 p8 = bag->value.keybag; 625 if (!(pkey = EVP_PKCS82PKEY (p8))) return 0; 626 print_attribs (out, p8->attributes, "Key Attributes"); 627 PEM_write_bio_PrivateKey (out, pkey, enc, NULL, 0, NULL, pempass); 628 EVP_PKEY_free(pkey); 629 break; 630 631 case NID_pkcs8ShroudedKeyBag: 632 if (options & INFO) { 633 BIO_printf (bio_err, "Shrouded Keybag: "); 634 alg_print (bio_err, bag->value.shkeybag->algor); 635 } 636 if (options & NOKEYS) return 1; 637 print_attribs (out, bag->attrib, "Bag Attributes"); 638 if (!(p8 = M_PKCS12_decrypt_skey (bag, pass, passlen))) 639 return 0; 640 if (!(pkey = EVP_PKCS82PKEY (p8))) return 0; 641 print_attribs (out, p8->attributes, "Key Attributes"); 642 PKCS8_PRIV_KEY_INFO_free(p8); 643 PEM_write_bio_PrivateKey (out, pkey, enc, NULL, 0, NULL, pempass); 644 EVP_PKEY_free(pkey); 645 break; 646 647 case NID_certBag: 648 if (options & INFO) BIO_printf (bio_err, "Certificate bag\n"); 649 if (options & NOCERTS) return 1; 650 if (PKCS12_get_attr(bag, NID_localKeyID)) { 651 if (options & CACERTS) return 1; 652 } else if (options & CLCERTS) return 1; 653 print_attribs (out, bag->attrib, "Bag Attributes"); 654 if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate ) 655 return 1; 656 if (!(x509 = M_PKCS12_certbag2x509(bag))) return 0; 657 dump_cert_text (out, x509); 658 PEM_write_bio_X509 (out, x509); 659 X509_free(x509); 660 break; 661 662 case NID_safeContentsBag: 663 if (options & INFO) BIO_printf (bio_err, "Safe Contents bag\n"); 664 print_attribs (out, bag->attrib, "Bag Attributes"); 665 return dump_certs_pkeys_bags (out, bag->value.safes, pass, 666 passlen, options, pempass); 667 668 default: 669 BIO_printf (bio_err, "Warning unsupported bag type: "); 670 i2a_ASN1_OBJECT (bio_err, bag->type); 671 BIO_printf (bio_err, "\n"); 672 return 1; 673 break; 674 } 675 return 1; 676 } 677 678 /* Given a single certificate return a verified chain or NULL if error */ 679 680 /* Hope this is OK .... */ 681 682 int get_cert_chain (X509 *cert, STACK_OF(X509) **chain) 683 { 684 X509_STORE *store; 685 X509_STORE_CTX store_ctx; 686 STACK_OF(X509) *chn; 687 int i; 688 689 store = X509_STORE_new (); 690 X509_STORE_set_default_paths (store); 691 X509_STORE_CTX_init(&store_ctx, store, cert, NULL); 692 if (X509_verify_cert(&store_ctx) <= 0) { 693 i = X509_STORE_CTX_get_error (&store_ctx); 694 goto err; 695 } 696 chn = X509_STORE_CTX_get1_chain(&store_ctx); 697 i = 0; 698 *chain = chn; 699 err: 700 X509_STORE_CTX_cleanup(&store_ctx); 701 X509_STORE_free(store); 702 703 return i; 704 } 705 706 int alg_print (BIO *x, X509_ALGOR *alg) 707 { 708 PBEPARAM *pbe; 709 unsigned char *p; 710 p = alg->parameter->value.sequence->data; 711 pbe = d2i_PBEPARAM (NULL, &p, alg->parameter->value.sequence->length); 712 BIO_printf (bio_err, "%s, Iteration %d\n", 713 OBJ_nid2ln(OBJ_obj2nid(alg->algorithm)), ASN1_INTEGER_get(pbe->iter)); 714 PBEPARAM_free (pbe); 715 return 0; 716 } 717 718 /* Load all certificates from a given file */ 719 720 int cert_load(BIO *in, STACK_OF(X509) *sk) 721 { 722 int ret; 723 X509 *cert; 724 ret = 0; 725 while((cert = PEM_read_bio_X509(in, NULL, NULL, NULL))) { 726 ret = 1; 727 sk_X509_push(sk, cert); 728 } 729 if(ret) ERR_clear_error(); 730 return ret; 731 } 732 733 /* Generalised attribute print: handle PKCS#8 and bag attributes */ 734 735 int print_attribs (BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst, char *name) 736 { 737 X509_ATTRIBUTE *attr; 738 ASN1_TYPE *av; 739 char *value; 740 int i, attr_nid; 741 if(!attrlst) { 742 BIO_printf(out, "%s: <No Attributes>\n", name); 743 return 1; 744 } 745 if(!sk_X509_ATTRIBUTE_num(attrlst)) { 746 BIO_printf(out, "%s: <Empty Attributes>\n", name); 747 return 1; 748 } 749 BIO_printf(out, "%s\n", name); 750 for(i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) { 751 attr = sk_X509_ATTRIBUTE_value(attrlst, i); 752 attr_nid = OBJ_obj2nid(attr->object); 753 BIO_printf(out, " "); 754 if(attr_nid == NID_undef) { 755 i2a_ASN1_OBJECT (out, attr->object); 756 BIO_printf(out, ": "); 757 } else BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid)); 758 759 if(sk_ASN1_TYPE_num(attr->value.set)) { 760 av = sk_ASN1_TYPE_value(attr->value.set, 0); 761 switch(av->type) { 762 case V_ASN1_BMPSTRING: 763 value = uni2asc(av->value.bmpstring->data, 764 av->value.bmpstring->length); 765 BIO_printf(out, "%s\n", value); 766 Free(value); 767 break; 768 769 case V_ASN1_OCTET_STRING: 770 hex_prin(out, av->value.bit_string->data, 771 av->value.bit_string->length); 772 BIO_printf(out, "\n"); 773 break; 774 775 case V_ASN1_BIT_STRING: 776 hex_prin(out, av->value.octet_string->data, 777 av->value.octet_string->length); 778 BIO_printf(out, "\n"); 779 break; 780 781 default: 782 BIO_printf(out, "<Unsupported tag %d>\n", av->type); 783 break; 784 } 785 } else BIO_printf(out, "<No Values>\n"); 786 } 787 return 1; 788 } 789 790 void hex_prin(BIO *out, unsigned char *buf, int len) 791 { 792 int i; 793 for (i = 0; i < len; i++) BIO_printf (out, "%02X ", buf[i]); 794 } 795 796 #endif 797