00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 #include <openssl/opensslconf.h>
00060 #if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)
00061
00062 #include <stdio.h>
00063 #include <stdlib.h>
00064 #include <string.h>
00065 #include "apps.h"
00066 #include <openssl/crypto.h>
00067 #include <openssl/err.h>
00068 #include <openssl/pem.h>
00069 #include <openssl/pkcs12.h>
00070
00071 #define PROG pkcs12_main
00072
00073 const EVP_CIPHER *enc;
00074
00075
00076 #define NOKEYS 0x1
00077 #define NOCERTS 0x2
00078 #define INFO 0x4
00079 #define CLCERTS 0x8
00080 #define CACERTS 0x10
00081
00082 int get_cert_chain (X509 *cert, X509_STORE *store, STACK_OF(X509) **chain);
00083 int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int passlen, int options, char *pempass);
00084 int dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, char *pass,
00085 int passlen, int options, char *pempass);
00086 int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass, int passlen, int options, char *pempass);
00087 int print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,const char *name);
00088 void hex_prin(BIO *out, unsigned char *buf, int len);
00089 int alg_print(BIO *x, X509_ALGOR *alg);
00090 int cert_load(BIO *in, STACK_OF(X509) *sk);
00091
00092 int MAIN(int, char **);
00093
00094 int MAIN(int argc, char **argv)
00095 {
00096 ENGINE *e = NULL;
00097 char *infile=NULL, *outfile=NULL, *keyname = NULL;
00098 char *certfile=NULL;
00099 BIO *in=NULL, *out = NULL;
00100 char **args;
00101 char *name = NULL;
00102 char *csp_name = NULL;
00103 PKCS12 *p12 = NULL;
00104 char pass[50], macpass[50];
00105 int export_cert = 0;
00106 int options = 0;
00107 int chain = 0;
00108 int badarg = 0;
00109 int iter = PKCS12_DEFAULT_ITER;
00110 int maciter = PKCS12_DEFAULT_ITER;
00111 int twopass = 0;
00112 int keytype = 0;
00113 int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
00114 int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
00115 int ret = 1;
00116 int macver = 1;
00117 int noprompt = 0;
00118 STACK *canames = NULL;
00119 char *cpass = NULL, *mpass = NULL;
00120 char *passargin = NULL, *passargout = NULL, *passarg = NULL;
00121 char *passin = NULL, *passout = NULL;
00122 char *inrand = NULL;
00123 char *CApath = NULL, *CAfile = NULL;
00124 #ifndef OPENSSL_NO_ENGINE
00125 char *engine=NULL;
00126 #endif
00127
00128 apps_startup();
00129
00130 enc = EVP_des_ede3_cbc();
00131 if (bio_err == NULL ) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
00132
00133 if (!load_config(bio_err, NULL))
00134 goto end;
00135
00136 args = argv + 1;
00137
00138
00139 while (*args) {
00140 if (*args[0] == '-') {
00141 if (!strcmp (*args, "-nokeys")) options |= NOKEYS;
00142 else if (!strcmp (*args, "-keyex")) keytype = KEY_EX;
00143 else if (!strcmp (*args, "-keysig")) keytype = KEY_SIG;
00144 else if (!strcmp (*args, "-nocerts")) options |= NOCERTS;
00145 else if (!strcmp (*args, "-clcerts")) options |= CLCERTS;
00146 else if (!strcmp (*args, "-cacerts")) options |= CACERTS;
00147 else if (!strcmp (*args, "-noout")) options |= (NOKEYS|NOCERTS);
00148 else if (!strcmp (*args, "-info")) options |= INFO;
00149 else if (!strcmp (*args, "-chain")) chain = 1;
00150 else if (!strcmp (*args, "-twopass")) twopass = 1;
00151 else if (!strcmp (*args, "-nomacver")) macver = 0;
00152 else if (!strcmp (*args, "-descert"))
00153 cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
00154 else if (!strcmp (*args, "-export")) export_cert = 1;
00155 else if (!strcmp (*args, "-des")) enc=EVP_des_cbc();
00156 #ifndef OPENSSL_NO_IDEA
00157 else if (!strcmp (*args, "-idea")) enc=EVP_idea_cbc();
00158 #endif
00159 else if (!strcmp (*args, "-des3")) enc = EVP_des_ede3_cbc();
00160 #ifndef OPENSSL_NO_AES
00161 else if (!strcmp(*args,"-aes128")) enc=EVP_aes_128_cbc();
00162 else if (!strcmp(*args,"-aes192")) enc=EVP_aes_192_cbc();
00163 else if (!strcmp(*args,"-aes256")) enc=EVP_aes_256_cbc();
00164 #endif
00165 else if (!strcmp (*args, "-noiter")) iter = 1;
00166 else if (!strcmp (*args, "-maciter"))
00167 maciter = PKCS12_DEFAULT_ITER;
00168 else if (!strcmp (*args, "-nomaciter"))
00169 maciter = 1;
00170 else if (!strcmp (*args, "-nomac"))
00171 maciter = -1;
00172 else if (!strcmp (*args, "-nodes")) enc=NULL;
00173 else if (!strcmp (*args, "-certpbe")) {
00174 if (args[1]) {
00175 args++;
00176 if (!strcmp(*args, "NONE"))
00177 cert_pbe = -1;
00178 cert_pbe=OBJ_txt2nid(*args);
00179 if(cert_pbe == NID_undef) {
00180 BIO_printf(bio_err,
00181 "Unknown PBE algorithm %s\n", *args);
00182 badarg = 1;
00183 }
00184 } else badarg = 1;
00185 } else if (!strcmp (*args, "-keypbe")) {
00186 if (args[1]) {
00187 args++;
00188 if (!strcmp(*args, "NONE"))
00189 key_pbe = -1;
00190 else
00191 key_pbe=OBJ_txt2nid(*args);
00192 if(key_pbe == NID_undef) {
00193 BIO_printf(bio_err,
00194 "Unknown PBE algorithm %s\n", *args);
00195 badarg = 1;
00196 }
00197 } else badarg = 1;
00198 } else if (!strcmp (*args, "-rand")) {
00199 if (args[1]) {
00200 args++;
00201 inrand = *args;
00202 } else badarg = 1;
00203 } else if (!strcmp (*args, "-inkey")) {
00204 if (args[1]) {
00205 args++;
00206 keyname = *args;
00207 } else badarg = 1;
00208 } else if (!strcmp (*args, "-certfile")) {
00209 if (args[1]) {
00210 args++;
00211 certfile = *args;
00212 } else badarg = 1;
00213 } else if (!strcmp (*args, "-name")) {
00214 if (args[1]) {
00215 args++;
00216 name = *args;
00217 } else badarg = 1;
00218 } else if (!strcmp (*args, "-CSP")) {
00219 if (args[1]) {
00220 args++;
00221 csp_name = *args;
00222 } else badarg = 1;
00223 } else if (!strcmp (*args, "-caname")) {
00224 if (args[1]) {
00225 args++;
00226 if (!canames) canames = sk_new_null();
00227 sk_push(canames, *args);
00228 } else badarg = 1;
00229 } else if (!strcmp (*args, "-in")) {
00230 if (args[1]) {
00231 args++;
00232 infile = *args;
00233 } else badarg = 1;
00234 } else if (!strcmp (*args, "-out")) {
00235 if (args[1]) {
00236 args++;
00237 outfile = *args;
00238 } else badarg = 1;
00239 } else if (!strcmp(*args,"-passin")) {
00240 if (args[1]) {
00241 args++;
00242 passargin = *args;
00243 } else badarg = 1;
00244 } else if (!strcmp(*args,"-passout")) {
00245 if (args[1]) {
00246 args++;
00247 passargout = *args;
00248 } else badarg = 1;
00249 } else if (!strcmp (*args, "-password")) {
00250 if (args[1]) {
00251 args++;
00252 passarg = *args;
00253 noprompt = 1;
00254 } else badarg = 1;
00255 } else if (!strcmp(*args,"-CApath")) {
00256 if (args[1]) {
00257 args++;
00258 CApath = *args;
00259 } else badarg = 1;
00260 } else if (!strcmp(*args,"-CAfile")) {
00261 if (args[1]) {
00262 args++;
00263 CAfile = *args;
00264 } else badarg = 1;
00265 #ifndef OPENSSL_NO_ENGINE
00266 } else if (!strcmp(*args,"-engine")) {
00267 if (args[1]) {
00268 args++;
00269 engine = *args;
00270 } else badarg = 1;
00271 #endif
00272 } else badarg = 1;
00273
00274 } else badarg = 1;
00275 args++;
00276 }
00277
00278 if (badarg) {
00279 BIO_printf (bio_err, "Usage: pkcs12 [options]\n");
00280 BIO_printf (bio_err, "where options are\n");
00281 BIO_printf (bio_err, "-export output PKCS12 file\n");
00282 BIO_printf (bio_err, "-chain add certificate chain\n");
00283 BIO_printf (bio_err, "-inkey file private key if not infile\n");
00284 BIO_printf (bio_err, "-certfile f add all certs in f\n");
00285 BIO_printf (bio_err, "-CApath arg - PEM format directory of CA's\n");
00286 BIO_printf (bio_err, "-CAfile arg - PEM format file of CA's\n");
00287 BIO_printf (bio_err, "-name \"name\" use name as friendly name\n");
00288 BIO_printf (bio_err, "-caname \"nm\" use nm as CA friendly name (can be used more than once).\n");
00289 BIO_printf (bio_err, "-in infile input filename\n");
00290 BIO_printf (bio_err, "-out outfile output filename\n");
00291 BIO_printf (bio_err, "-noout don't output anything, just verify.\n");
00292 BIO_printf (bio_err, "-nomacver don't verify MAC.\n");
00293 BIO_printf (bio_err, "-nocerts don't output certificates.\n");
00294 BIO_printf (bio_err, "-clcerts only output client certificates.\n");
00295 BIO_printf (bio_err, "-cacerts only output CA certificates.\n");
00296 BIO_printf (bio_err, "-nokeys don't output private keys.\n");
00297 BIO_printf (bio_err, "-info give info about PKCS#12 structure.\n");
00298 BIO_printf (bio_err, "-des encrypt private keys with DES\n");
00299 BIO_printf (bio_err, "-des3 encrypt private keys with triple DES (default)\n");
00300 #ifndef OPENSSL_NO_IDEA
00301 BIO_printf (bio_err, "-idea encrypt private keys with idea\n");
00302 #endif
00303 #ifndef OPENSSL_NO_AES
00304 BIO_printf (bio_err, "-aes128, -aes192, -aes256\n");
00305 BIO_printf (bio_err, " encrypt PEM output with cbc aes\n");
00306 #endif
00307 BIO_printf (bio_err, "-nodes don't encrypt private keys\n");
00308 BIO_printf (bio_err, "-noiter don't use encryption iteration\n");
00309 BIO_printf (bio_err, "-maciter use MAC iteration\n");
00310 BIO_printf (bio_err, "-twopass separate MAC, encryption passwords\n");
00311 BIO_printf (bio_err, "-descert encrypt PKCS#12 certificates with triple DES (default RC2-40)\n");
00312 BIO_printf (bio_err, "-certpbe alg specify certificate PBE algorithm (default RC2-40)\n");
00313 BIO_printf (bio_err, "-keypbe alg specify private key PBE algorithm (default 3DES)\n");
00314 BIO_printf (bio_err, "-keyex set MS key exchange type\n");
00315 BIO_printf (bio_err, "-keysig set MS key signature type\n");
00316 BIO_printf (bio_err, "-password p set import/export password source\n");
00317 BIO_printf (bio_err, "-passin p input file pass phrase source\n");
00318 BIO_printf (bio_err, "-passout p output file pass phrase source\n");
00319 #ifndef OPENSSL_NO_ENGINE
00320 BIO_printf (bio_err, "-engine e use engine e, possibly a hardware device.\n");
00321 #endif
00322 BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
00323 BIO_printf(bio_err, " load the file (or the files in the directory) into\n");
00324 BIO_printf(bio_err, " the random number generator\n");
00325 goto end;
00326 }
00327
00328 #ifndef OPENSSL_NO_ENGINE
00329 e = setup_engine(bio_err, engine, 0);
00330 #endif
00331
00332 if(passarg) {
00333 if(export_cert) passargout = passarg;
00334 else passargin = passarg;
00335 }
00336
00337 if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
00338 BIO_printf(bio_err, "Error getting passwords\n");
00339 goto end;
00340 }
00341
00342 if(!cpass) {
00343 if(export_cert) cpass = passout;
00344 else cpass = passin;
00345 }
00346
00347 if(cpass) {
00348 mpass = cpass;
00349 noprompt = 1;
00350 } else {
00351 cpass = pass;
00352 mpass = macpass;
00353 }
00354
00355 if(export_cert || inrand) {
00356 app_RAND_load_file(NULL, bio_err, (inrand != NULL));
00357 if (inrand != NULL)
00358 BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
00359 app_RAND_load_files(inrand));
00360 }
00361 ERR_load_crypto_strings();
00362
00363 #ifdef CRYPTO_MDEBUG
00364 CRYPTO_push_info("read files");
00365 #endif
00366
00367 if (!infile) in = BIO_new_fp(stdin, BIO_NOCLOSE);
00368 else in = BIO_new_file(infile, "rb");
00369 if (!in) {
00370 BIO_printf(bio_err, "Error opening input file %s\n",
00371 infile ? infile : "<stdin>");
00372 perror (infile);
00373 goto end;
00374 }
00375
00376 #ifdef CRYPTO_MDEBUG
00377 CRYPTO_pop_info();
00378 CRYPTO_push_info("write files");
00379 #endif
00380
00381 if (!outfile) {
00382 out = BIO_new_fp(stdout, BIO_NOCLOSE);
00383 #ifdef OPENSSL_SYS_VMS
00384 {
00385 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
00386 out = BIO_push(tmpbio, out);
00387 }
00388 #endif
00389 } else out = BIO_new_file(outfile, "wb");
00390 if (!out) {
00391 BIO_printf(bio_err, "Error opening output file %s\n",
00392 outfile ? outfile : "<stdout>");
00393 perror (outfile);
00394 goto end;
00395 }
00396 if (twopass) {
00397 #ifdef CRYPTO_MDEBUG
00398 CRYPTO_push_info("read MAC password");
00399 #endif
00400 if(EVP_read_pw_string (macpass, sizeof macpass, "Enter MAC Password:", export_cert))
00401 {
00402 BIO_printf (bio_err, "Can't read Password\n");
00403 goto end;
00404 }
00405 #ifdef CRYPTO_MDEBUG
00406 CRYPTO_pop_info();
00407 #endif
00408 }
00409
00410 if (export_cert) {
00411 EVP_PKEY *key = NULL;
00412 X509 *ucert = NULL, *x = NULL;
00413 STACK_OF(X509) *certs=NULL;
00414 unsigned char *catmp = NULL;
00415 int i;
00416
00417 if ((options & (NOCERTS|NOKEYS)) == (NOCERTS|NOKEYS))
00418 {
00419 BIO_printf(bio_err, "Nothing to do!\n");
00420 goto export_end;
00421 }
00422
00423 if (options & NOCERTS)
00424 chain = 0;
00425
00426 #ifdef CRYPTO_MDEBUG
00427 CRYPTO_push_info("process -export_cert");
00428 CRYPTO_push_info("reading private key");
00429 #endif
00430 if (!(options & NOKEYS))
00431 {
00432 key = load_key(bio_err, keyname ? keyname : infile,
00433 FORMAT_PEM, 1, passin, e, "private key");
00434 if (!key)
00435 goto export_end;
00436 }
00437
00438 #ifdef CRYPTO_MDEBUG
00439 CRYPTO_pop_info();
00440 CRYPTO_push_info("reading certs from input");
00441 #endif
00442
00443
00444 if(!(options & NOCERTS))
00445 {
00446 certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e,
00447 "certificates");
00448 if (!certs)
00449 goto export_end;
00450
00451 if (key)
00452 {
00453
00454 for(i = 0; i < sk_X509_num(certs); i++)
00455 {
00456 x = sk_X509_value(certs, i);
00457 if(X509_check_private_key(x, key))
00458 {
00459 ucert = x;
00460
00461 X509_keyid_set1(ucert, NULL, 0);
00462 X509_alias_set1(ucert, NULL, 0);
00463
00464 sk_X509_delete(certs, i);
00465 break;
00466 }
00467 }
00468 if (!ucert)
00469 {
00470 BIO_printf(bio_err, "No certificate matches private key\n");
00471 goto export_end;
00472 }
00473 }
00474
00475 }
00476
00477 #ifdef CRYPTO_MDEBUG
00478 CRYPTO_pop_info();
00479 CRYPTO_push_info("reading certs from input 2");
00480 #endif
00481
00482
00483 if(certfile)
00484 {
00485 STACK_OF(X509) *morecerts=NULL;
00486 if(!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM,
00487 NULL, e,
00488 "certificates from certfile")))
00489 goto export_end;
00490 while(sk_X509_num(morecerts) > 0)
00491 sk_X509_push(certs, sk_X509_shift(morecerts));
00492 sk_X509_free(morecerts);
00493 }
00494
00495 #ifdef CRYPTO_MDEBUG
00496 CRYPTO_pop_info();
00497 CRYPTO_push_info("reading certs from certfile");
00498 #endif
00499
00500 #ifdef CRYPTO_MDEBUG
00501 CRYPTO_pop_info();
00502 CRYPTO_push_info("building chain");
00503 #endif
00504
00505
00506 if (chain) {
00507 int vret;
00508 STACK_OF(X509) *chain2;
00509 X509_STORE *store = X509_STORE_new();
00510 if (!store)
00511 {
00512 BIO_printf (bio_err, "Memory allocation error\n");
00513 goto export_end;
00514 }
00515 if (!X509_STORE_load_locations(store, CAfile, CApath))
00516 X509_STORE_set_default_paths (store);
00517
00518 vret = get_cert_chain (ucert, store, &chain2);
00519 X509_STORE_free(store);
00520
00521 if (!vret) {
00522
00523 for (i = 1; i < sk_X509_num (chain2) ; i++)
00524 sk_X509_push(certs, sk_X509_value (chain2, i));
00525
00526 X509_free(sk_X509_value(chain2, 0));
00527 sk_X509_free(chain2);
00528 } else {
00529 BIO_printf (bio_err, "Error %s getting chain.\n",
00530 X509_verify_cert_error_string(vret));
00531 goto export_end;
00532 }
00533 }
00534
00535
00536
00537 for (i = 0; i < sk_num(canames); i++)
00538 {
00539 catmp = (unsigned char *)sk_value(canames, i);
00540 X509_alias_set1(sk_X509_value(certs, i), catmp, -1);
00541 }
00542
00543 if (csp_name && key)
00544 EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name,
00545 MBSTRING_ASC, (unsigned char *)csp_name, -1);
00546
00547
00548 #ifdef CRYPTO_MDEBUG
00549 CRYPTO_pop_info();
00550 CRYPTO_push_info("reading password");
00551 #endif
00552
00553 if(!noprompt &&
00554 EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:", 1))
00555 {
00556 BIO_printf (bio_err, "Can't read Password\n");
00557 goto export_end;
00558 }
00559 if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass);
00560
00561 #ifdef CRYPTO_MDEBUG
00562 CRYPTO_pop_info();
00563 CRYPTO_push_info("creating PKCS#12 structure");
00564 #endif
00565
00566 p12 = PKCS12_create(cpass, name, key, ucert, certs,
00567 key_pbe, cert_pbe, iter, -1, keytype);
00568
00569 if (!p12)
00570 {
00571 ERR_print_errors (bio_err);
00572 goto export_end;
00573 }
00574
00575 if (maciter != -1)
00576 PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, NULL);
00577
00578 #ifdef CRYPTO_MDEBUG
00579 CRYPTO_pop_info();
00580 CRYPTO_push_info("writing pkcs12");
00581 #endif
00582
00583 i2d_PKCS12_bio(out, p12);
00584
00585 ret = 0;
00586
00587 export_end:
00588 #ifdef CRYPTO_MDEBUG
00589 CRYPTO_pop_info();
00590 CRYPTO_pop_info();
00591 CRYPTO_push_info("process -export_cert: freeing");
00592 #endif
00593
00594 if (key) EVP_PKEY_free(key);
00595 if (certs) sk_X509_pop_free(certs, X509_free);
00596 if (ucert) X509_free(ucert);
00597
00598 #ifdef CRYPTO_MDEBUG
00599 CRYPTO_pop_info();
00600 #endif
00601 goto end;
00602
00603 }
00604
00605 if (!(p12 = d2i_PKCS12_bio (in, NULL))) {
00606 ERR_print_errors(bio_err);
00607 goto end;
00608 }
00609
00610 #ifdef CRYPTO_MDEBUG
00611 CRYPTO_push_info("read import password");
00612 #endif
00613 if(!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:", 0)) {
00614 BIO_printf (bio_err, "Can't read Password\n");
00615 goto end;
00616 }
00617 #ifdef CRYPTO_MDEBUG
00618 CRYPTO_pop_info();
00619 #endif
00620
00621 if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass);
00622
00623 if (options & INFO) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1);
00624 if(macver) {
00625 #ifdef CRYPTO_MDEBUG
00626 CRYPTO_push_info("verify MAC");
00627 #endif
00628
00629 if(!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) {
00630
00631 if(!twopass) cpass = NULL;
00632 } else if (!PKCS12_verify_mac(p12, mpass, -1)) {
00633 BIO_printf (bio_err, "Mac verify error: invalid password?\n");
00634 ERR_print_errors (bio_err);
00635 goto end;
00636 }
00637 BIO_printf (bio_err, "MAC verified OK\n");
00638 #ifdef CRYPTO_MDEBUG
00639 CRYPTO_pop_info();
00640 #endif
00641 }
00642
00643 #ifdef CRYPTO_MDEBUG
00644 CRYPTO_push_info("output keys and certificates");
00645 #endif
00646 if (!dump_certs_keys_p12 (out, p12, cpass, -1, options, passout)) {
00647 BIO_printf(bio_err, "Error outputting keys and certificates\n");
00648 ERR_print_errors (bio_err);
00649 goto end;
00650 }
00651 #ifdef CRYPTO_MDEBUG
00652 CRYPTO_pop_info();
00653 #endif
00654 ret = 0;
00655 end:
00656 if (p12) PKCS12_free(p12);
00657 if(export_cert || inrand) app_RAND_write_file(NULL, bio_err);
00658 #ifdef CRYPTO_MDEBUG
00659 CRYPTO_remove_all_info();
00660 #endif
00661 BIO_free(in);
00662 BIO_free_all(out);
00663 if (canames) sk_free(canames);
00664 if(passin) OPENSSL_free(passin);
00665 if(passout) OPENSSL_free(passout);
00666 apps_shutdown();
00667 OPENSSL_EXIT(ret);
00668 }
00669
00670 int dump_certs_keys_p12 (BIO *out, PKCS12 *p12, char *pass,
00671 int passlen, int options, char *pempass)
00672 {
00673 STACK_OF(PKCS7) *asafes = NULL;
00674 STACK_OF(PKCS12_SAFEBAG) *bags;
00675 int i, bagnid;
00676 int ret = 0;
00677 PKCS7 *p7;
00678
00679 if (!( asafes = PKCS12_unpack_authsafes(p12))) return 0;
00680 for (i = 0; i < sk_PKCS7_num (asafes); i++) {
00681 p7 = sk_PKCS7_value (asafes, i);
00682 bagnid = OBJ_obj2nid (p7->type);
00683 if (bagnid == NID_pkcs7_data) {
00684 bags = PKCS12_unpack_p7data(p7);
00685 if (options & INFO) BIO_printf (bio_err, "PKCS7 Data\n");
00686 } else if (bagnid == NID_pkcs7_encrypted) {
00687 if (options & INFO) {
00688 BIO_printf(bio_err, "PKCS7 Encrypted data: ");
00689 alg_print(bio_err,
00690 p7->d.encrypted->enc_data->algorithm);
00691 }
00692 bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
00693 } else continue;
00694 if (!bags) goto err;
00695 if (!dump_certs_pkeys_bags (out, bags, pass, passlen,
00696 options, pempass)) {
00697 sk_PKCS12_SAFEBAG_pop_free (bags, PKCS12_SAFEBAG_free);
00698 goto err;
00699 }
00700 sk_PKCS12_SAFEBAG_pop_free (bags, PKCS12_SAFEBAG_free);
00701 bags = NULL;
00702 }
00703 ret = 1;
00704
00705 err:
00706
00707 if (asafes)
00708 sk_PKCS7_pop_free (asafes, PKCS7_free);
00709 return ret;
00710 }
00711
00712 int dump_certs_pkeys_bags (BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags,
00713 char *pass, int passlen, int options, char *pempass)
00714 {
00715 int i;
00716 for (i = 0; i < sk_PKCS12_SAFEBAG_num (bags); i++) {
00717 if (!dump_certs_pkeys_bag (out,
00718 sk_PKCS12_SAFEBAG_value (bags, i),
00719 pass, passlen,
00720 options, pempass))
00721 return 0;
00722 }
00723 return 1;
00724 }
00725
00726 int dump_certs_pkeys_bag (BIO *out, PKCS12_SAFEBAG *bag, char *pass,
00727 int passlen, int options, char *pempass)
00728 {
00729 EVP_PKEY *pkey;
00730 PKCS8_PRIV_KEY_INFO *p8;
00731 X509 *x509;
00732
00733 switch (M_PKCS12_bag_type(bag))
00734 {
00735 case NID_keyBag:
00736 if (options & INFO) BIO_printf (bio_err, "Key bag\n");
00737 if (options & NOKEYS) return 1;
00738 print_attribs (out, bag->attrib, "Bag Attributes");
00739 p8 = bag->value.keybag;
00740 if (!(pkey = EVP_PKCS82PKEY (p8))) return 0;
00741 print_attribs (out, p8->attributes, "Key Attributes");
00742 PEM_write_bio_PrivateKey (out, pkey, enc, NULL, 0, NULL, pempass);
00743 EVP_PKEY_free(pkey);
00744 break;
00745
00746 case NID_pkcs8ShroudedKeyBag:
00747 if (options & INFO) {
00748 BIO_printf (bio_err, "Shrouded Keybag: ");
00749 alg_print (bio_err, bag->value.shkeybag->algor);
00750 }
00751 if (options & NOKEYS) return 1;
00752 print_attribs (out, bag->attrib, "Bag Attributes");
00753 if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen)))
00754 return 0;
00755 if (!(pkey = EVP_PKCS82PKEY (p8))) {
00756 PKCS8_PRIV_KEY_INFO_free(p8);
00757 return 0;
00758 }
00759 print_attribs (out, p8->attributes, "Key Attributes");
00760 PKCS8_PRIV_KEY_INFO_free(p8);
00761 PEM_write_bio_PrivateKey (out, pkey, enc, NULL, 0, NULL, pempass);
00762 EVP_PKEY_free(pkey);
00763 break;
00764
00765 case NID_certBag:
00766 if (options & INFO) BIO_printf (bio_err, "Certificate bag\n");
00767 if (options & NOCERTS) return 1;
00768 if (PKCS12_get_attr(bag, NID_localKeyID)) {
00769 if (options & CACERTS) return 1;
00770 } else if (options & CLCERTS) return 1;
00771 print_attribs (out, bag->attrib, "Bag Attributes");
00772 if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate )
00773 return 1;
00774 if (!(x509 = PKCS12_certbag2x509(bag))) return 0;
00775 dump_cert_text (out, x509);
00776 PEM_write_bio_X509 (out, x509);
00777 X509_free(x509);
00778 break;
00779
00780 case NID_safeContentsBag:
00781 if (options & INFO) BIO_printf (bio_err, "Safe Contents bag\n");
00782 print_attribs (out, bag->attrib, "Bag Attributes");
00783 return dump_certs_pkeys_bags (out, bag->value.safes, pass,
00784 passlen, options, pempass);
00785
00786 default:
00787 BIO_printf (bio_err, "Warning unsupported bag type: ");
00788 i2a_ASN1_OBJECT (bio_err, bag->type);
00789 BIO_printf (bio_err, "\n");
00790 return 1;
00791 break;
00792 }
00793 return 1;
00794 }
00795
00796
00797
00798
00799
00800 int get_cert_chain (X509 *cert, X509_STORE *store, STACK_OF(X509) **chain)
00801 {
00802 X509_STORE_CTX store_ctx;
00803 STACK_OF(X509) *chn;
00804 int i;
00805
00806
00807
00808
00809 X509_STORE_CTX_init(&store_ctx, store, cert, NULL);
00810 if (X509_verify_cert(&store_ctx) <= 0) {
00811 i = X509_STORE_CTX_get_error (&store_ctx);
00812 goto err;
00813 }
00814 chn = X509_STORE_CTX_get1_chain(&store_ctx);
00815 i = 0;
00816 *chain = chn;
00817 err:
00818 X509_STORE_CTX_cleanup(&store_ctx);
00819
00820 return i;
00821 }
00822
00823 int alg_print (BIO *x, X509_ALGOR *alg)
00824 {
00825 PBEPARAM *pbe;
00826 const unsigned char *p;
00827 p = alg->parameter->value.sequence->data;
00828 pbe = d2i_PBEPARAM (NULL, &p, alg->parameter->value.sequence->length);
00829 BIO_printf (bio_err, "%s, Iteration %ld\n",
00830 OBJ_nid2ln(OBJ_obj2nid(alg->algorithm)),
00831 ASN1_INTEGER_get(pbe->iter));
00832 PBEPARAM_free (pbe);
00833 return 0;
00834 }
00835
00836
00837
00838 int cert_load(BIO *in, STACK_OF(X509) *sk)
00839 {
00840 int ret;
00841 X509 *cert;
00842 ret = 0;
00843 #ifdef CRYPTO_MDEBUG
00844 CRYPTO_push_info("cert_load(): reading one cert");
00845 #endif
00846 while((cert = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
00847 #ifdef CRYPTO_MDEBUG
00848 CRYPTO_pop_info();
00849 #endif
00850 ret = 1;
00851 sk_X509_push(sk, cert);
00852 #ifdef CRYPTO_MDEBUG
00853 CRYPTO_push_info("cert_load(): reading one cert");
00854 #endif
00855 }
00856 #ifdef CRYPTO_MDEBUG
00857 CRYPTO_pop_info();
00858 #endif
00859 if(ret) ERR_clear_error();
00860 return ret;
00861 }
00862
00863
00864
00865 int print_attribs (BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,const char *name)
00866 {
00867 X509_ATTRIBUTE *attr;
00868 ASN1_TYPE *av;
00869 char *value;
00870 int i, attr_nid;
00871 if(!attrlst) {
00872 BIO_printf(out, "%s: <No Attributes>\n", name);
00873 return 1;
00874 }
00875 if(!sk_X509_ATTRIBUTE_num(attrlst)) {
00876 BIO_printf(out, "%s: <Empty Attributes>\n", name);
00877 return 1;
00878 }
00879 BIO_printf(out, "%s\n", name);
00880 for(i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) {
00881 attr = sk_X509_ATTRIBUTE_value(attrlst, i);
00882 attr_nid = OBJ_obj2nid(attr->object);
00883 BIO_printf(out, " ");
00884 if(attr_nid == NID_undef) {
00885 i2a_ASN1_OBJECT (out, attr->object);
00886 BIO_printf(out, ": ");
00887 } else BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid));
00888
00889 if(sk_ASN1_TYPE_num(attr->value.set)) {
00890 av = sk_ASN1_TYPE_value(attr->value.set, 0);
00891 switch(av->type) {
00892 case V_ASN1_BMPSTRING:
00893 value = uni2asc(av->value.bmpstring->data,
00894 av->value.bmpstring->length);
00895 BIO_printf(out, "%s\n", value);
00896 OPENSSL_free(value);
00897 break;
00898
00899 case V_ASN1_OCTET_STRING:
00900 hex_prin(out, av->value.octet_string->data,
00901 av->value.octet_string->length);
00902 BIO_printf(out, "\n");
00903 break;
00904
00905 case V_ASN1_BIT_STRING:
00906 hex_prin(out, av->value.bit_string->data,
00907 av->value.bit_string->length);
00908 BIO_printf(out, "\n");
00909 break;
00910
00911 default:
00912 BIO_printf(out, "<Unsupported tag %d>\n", av->type);
00913 break;
00914 }
00915 } else BIO_printf(out, "<No Values>\n");
00916 }
00917 return 1;
00918 }
00919
00920 void hex_prin(BIO *out, unsigned char *buf, int len)
00921 {
00922 int i;
00923 for (i = 0; i < len; i++) BIO_printf (out, "%02X ", buf[i]);
00924 }
00925
00926 #endif