Home | History | Annotate | Download | only in apps
      1 /* pkcs12.c */
      2 /* Written by Dr Stephen N Henson (steve (at) 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 (at) 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 (at) cryptsoft.com).  This product includes software written by Tim
     55  * Hudson (tjh (at) cryptsoft.com).
     56  *
     57  */
     58 
     59 #include <openssl/opensslconf.h>
     60 #if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)
     61 
     62 #include <stdio.h>
     63 #include <stdlib.h>
     64 #include <string.h>
     65 #include "apps.h"
     66 #include <openssl/crypto.h>
     67 #include <openssl/err.h>
     68 #include <openssl/pem.h>
     69 #include <openssl/pkcs12.h>
     70 
     71 #define PROG pkcs12_main
     72 
     73 const EVP_CIPHER *enc;
     74 
     75 
     76 #define NOKEYS		0x1
     77 #define NOCERTS 	0x2
     78 #define INFO		0x4
     79 #define CLCERTS		0x8
     80 #define CACERTS		0x10
     81 
     82 int get_cert_chain (X509 *cert, X509_STORE *store, STACK_OF(X509) **chain);
     83 int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int passlen, int options, char *pempass);
     84 int dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, char *pass,
     85 			  int passlen, int options, char *pempass);
     86 int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass, int passlen, int options, char *pempass);
     87 int print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,const char *name);
     88 void hex_prin(BIO *out, unsigned char *buf, int len);
     89 int alg_print(BIO *x, X509_ALGOR *alg);
     90 int cert_load(BIO *in, STACK_OF(X509) *sk);
     91 static int set_pbe(BIO *err, int *ppbe, const char *str);
     92 
     93 int MAIN(int, char **);
     94 
     95 int MAIN(int argc, char **argv)
     96 {
     97     ENGINE *e = NULL;
     98     char *infile=NULL, *outfile=NULL, *keyname = NULL;
     99     char *certfile=NULL;
    100     BIO *in=NULL, *out = NULL;
    101     char **args;
    102     char *name = NULL;
    103     char *csp_name = NULL;
    104     int add_lmk = 0;
    105     PKCS12 *p12 = NULL;
    106     char pass[50], macpass[50];
    107     int export_cert = 0;
    108     int options = 0;
    109     int chain = 0;
    110     int badarg = 0;
    111     int iter = PKCS12_DEFAULT_ITER;
    112     int maciter = PKCS12_DEFAULT_ITER;
    113     int twopass = 0;
    114     int keytype = 0;
    115     int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
    116     int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
    117     int ret = 1;
    118     int macver = 1;
    119     int noprompt = 0;
    120     STACK_OF(OPENSSL_STRING) *canames = NULL;
    121     char *cpass = NULL, *mpass = NULL;
    122     char *passargin = NULL, *passargout = NULL, *passarg = NULL;
    123     char *passin = NULL, *passout = NULL;
    124     char *inrand = NULL;
    125     char *macalg = NULL;
    126     char *CApath = NULL, *CAfile = NULL;
    127 #ifndef OPENSSL_NO_ENGINE
    128     char *engine=NULL;
    129 #endif
    130 
    131     apps_startup();
    132 
    133     enc = EVP_des_ede3_cbc();
    134     if (bio_err == NULL ) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
    135 
    136 	if (!load_config(bio_err, NULL))
    137 		goto end;
    138 
    139     args = argv + 1;
    140 
    141 
    142     while (*args) {
    143 	if (*args[0] == '-') {
    144 		if (!strcmp (*args, "-nokeys")) options |= NOKEYS;
    145 		else if (!strcmp (*args, "-keyex")) keytype = KEY_EX;
    146 		else if (!strcmp (*args, "-keysig")) keytype = KEY_SIG;
    147 		else if (!strcmp (*args, "-nocerts")) options |= NOCERTS;
    148 		else if (!strcmp (*args, "-clcerts")) options |= CLCERTS;
    149 		else if (!strcmp (*args, "-cacerts")) options |= CACERTS;
    150 		else if (!strcmp (*args, "-noout")) options |= (NOKEYS|NOCERTS);
    151 		else if (!strcmp (*args, "-info")) options |= INFO;
    152 		else if (!strcmp (*args, "-chain")) chain = 1;
    153 		else if (!strcmp (*args, "-twopass")) twopass = 1;
    154 		else if (!strcmp (*args, "-nomacver")) macver = 0;
    155 		else if (!strcmp (*args, "-descert"))
    156     			cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
    157 		else if (!strcmp (*args, "-export")) export_cert = 1;
    158 		else if (!strcmp (*args, "-des")) enc=EVP_des_cbc();
    159 		else if (!strcmp (*args, "-des3")) enc = EVP_des_ede3_cbc();
    160 #ifndef OPENSSL_NO_IDEA
    161 		else if (!strcmp (*args, "-idea")) enc=EVP_idea_cbc();
    162 #endif
    163 #ifndef OPENSSL_NO_SEED
    164 		else if (!strcmp(*args, "-seed")) enc=EVP_seed_cbc();
    165 #endif
    166 #ifndef OPENSSL_NO_AES
    167 		else if (!strcmp(*args,"-aes128")) enc=EVP_aes_128_cbc();
    168 		else if (!strcmp(*args,"-aes192")) enc=EVP_aes_192_cbc();
    169 		else if (!strcmp(*args,"-aes256")) enc=EVP_aes_256_cbc();
    170 #endif
    171 #ifndef OPENSSL_NO_CAMELLIA
    172 		else if (!strcmp(*args,"-camellia128")) enc=EVP_camellia_128_cbc();
    173 		else if (!strcmp(*args,"-camellia192")) enc=EVP_camellia_192_cbc();
    174 		else if (!strcmp(*args,"-camellia256")) enc=EVP_camellia_256_cbc();
    175 #endif
    176 		else if (!strcmp (*args, "-noiter")) iter = 1;
    177 		else if (!strcmp (*args, "-maciter"))
    178 					 maciter = PKCS12_DEFAULT_ITER;
    179 		else if (!strcmp (*args, "-nomaciter"))
    180 					 maciter = 1;
    181 		else if (!strcmp (*args, "-nomac"))
    182 					 maciter = -1;
    183 		else if (!strcmp (*args, "-macalg"))
    184 		    if (args[1]) {
    185 			args++;
    186 			macalg = *args;
    187 		    } else badarg = 1;
    188 		else if (!strcmp (*args, "-nodes")) enc=NULL;
    189 		else if (!strcmp (*args, "-certpbe")) {
    190 			if (!set_pbe(bio_err, &cert_pbe, *++args))
    191 				badarg = 1;
    192 		} else if (!strcmp (*args, "-keypbe")) {
    193 			if (!set_pbe(bio_err, &key_pbe, *++args))
    194 				badarg = 1;
    195 		} else if (!strcmp (*args, "-rand")) {
    196 		    if (args[1]) {
    197 			args++;
    198 			inrand = *args;
    199 		    } else badarg = 1;
    200 		} else if (!strcmp (*args, "-inkey")) {
    201 		    if (args[1]) {
    202 			args++;
    203 			keyname = *args;
    204 		    } else badarg = 1;
    205 		} else if (!strcmp (*args, "-certfile")) {
    206 		    if (args[1]) {
    207 			args++;
    208 			certfile = *args;
    209 		    } else badarg = 1;
    210 		} else if (!strcmp (*args, "-name")) {
    211 		    if (args[1]) {
    212 			args++;
    213 			name = *args;
    214 		    } else badarg = 1;
    215 		} else if (!strcmp (*args, "-LMK"))
    216 			add_lmk = 1;
    217 		else if (!strcmp (*args, "-CSP")) {
    218 		    if (args[1]) {
    219 			args++;
    220 			csp_name = *args;
    221 		    } else badarg = 1;
    222 		} else if (!strcmp (*args, "-caname")) {
    223 		    if (args[1]) {
    224 			args++;
    225 			if (!canames) canames = sk_OPENSSL_STRING_new_null();
    226 			sk_OPENSSL_STRING_push(canames, *args);
    227 		    } else badarg = 1;
    228 		} else if (!strcmp (*args, "-in")) {
    229 		    if (args[1]) {
    230 			args++;
    231 			infile = *args;
    232 		    } else badarg = 1;
    233 		} else if (!strcmp (*args, "-out")) {
    234 		    if (args[1]) {
    235 			args++;
    236 			outfile = *args;
    237 		    } else badarg = 1;
    238 		} else if (!strcmp(*args,"-passin")) {
    239 		    if (args[1]) {
    240 			args++;
    241 			passargin = *args;
    242 		    } else badarg = 1;
    243 		} else if (!strcmp(*args,"-passout")) {
    244 		    if (args[1]) {
    245 			args++;
    246 			passargout = *args;
    247 		    } else badarg = 1;
    248 		} else if (!strcmp (*args, "-password")) {
    249 		    if (args[1]) {
    250 			args++;
    251 			passarg = *args;
    252 		    	noprompt = 1;
    253 		    } else badarg = 1;
    254 		} else if (!strcmp(*args,"-CApath")) {
    255 		    if (args[1]) {
    256 			args++;
    257 			CApath = *args;
    258 		    } else badarg = 1;
    259 		} else if (!strcmp(*args,"-CAfile")) {
    260 		    if (args[1]) {
    261 			args++;
    262 			CAfile = *args;
    263 		    } else badarg = 1;
    264 #ifndef OPENSSL_NO_ENGINE
    265 		} else if (!strcmp(*args,"-engine")) {
    266 		    if (args[1]) {
    267 			args++;
    268 			engine = *args;
    269 		    } else badarg = 1;
    270 #endif
    271 		} else badarg = 1;
    272 
    273 	} else badarg = 1;
    274 	args++;
    275     }
    276 
    277     if (badarg) {
    278 	BIO_printf (bio_err, "Usage: pkcs12 [options]\n");
    279 	BIO_printf (bio_err, "where options are\n");
    280 	BIO_printf (bio_err, "-export       output PKCS12 file\n");
    281 	BIO_printf (bio_err, "-chain        add certificate chain\n");
    282 	BIO_printf (bio_err, "-inkey file   private key if not infile\n");
    283 	BIO_printf (bio_err, "-certfile f   add all certs in f\n");
    284 	BIO_printf (bio_err, "-CApath arg   - PEM format directory of CA's\n");
    285 	BIO_printf (bio_err, "-CAfile arg   - PEM format file of CA's\n");
    286 	BIO_printf (bio_err, "-name \"name\"  use name as friendly name\n");
    287 	BIO_printf (bio_err, "-caname \"nm\"  use nm as CA friendly name (can be used more than once).\n");
    288 	BIO_printf (bio_err, "-in  infile   input filename\n");
    289 	BIO_printf (bio_err, "-out outfile  output filename\n");
    290 	BIO_printf (bio_err, "-noout        don't output anything, just verify.\n");
    291 	BIO_printf (bio_err, "-nomacver     don't verify MAC.\n");
    292 	BIO_printf (bio_err, "-nocerts      don't output certificates.\n");
    293 	BIO_printf (bio_err, "-clcerts      only output client certificates.\n");
    294 	BIO_printf (bio_err, "-cacerts      only output CA certificates.\n");
    295 	BIO_printf (bio_err, "-nokeys       don't output private keys.\n");
    296 	BIO_printf (bio_err, "-info         give info about PKCS#12 structure.\n");
    297 	BIO_printf (bio_err, "-des          encrypt private keys with DES\n");
    298 	BIO_printf (bio_err, "-des3         encrypt private keys with triple DES (default)\n");
    299 #ifndef OPENSSL_NO_IDEA
    300 	BIO_printf (bio_err, "-idea         encrypt private keys with idea\n");
    301 #endif
    302 #ifndef OPENSSL_NO_SEED
    303 	BIO_printf (bio_err, "-seed         encrypt private keys with seed\n");
    304 #endif
    305 #ifndef OPENSSL_NO_AES
    306 	BIO_printf (bio_err, "-aes128, -aes192, -aes256\n");
    307 	BIO_printf (bio_err, "              encrypt PEM output with cbc aes\n");
    308 #endif
    309 #ifndef OPENSSL_NO_CAMELLIA
    310 	BIO_printf (bio_err, "-camellia128, -camellia192, -camellia256\n");
    311 	BIO_printf (bio_err, "              encrypt PEM output with cbc camellia\n");
    312 #endif
    313 	BIO_printf (bio_err, "-nodes        don't encrypt private keys\n");
    314 	BIO_printf (bio_err, "-noiter       don't use encryption iteration\n");
    315 	BIO_printf (bio_err, "-nomaciter    don't use MAC iteration\n");
    316 	BIO_printf (bio_err, "-maciter      use MAC iteration\n");
    317 	BIO_printf (bio_err, "-nomac        don't generate MAC\n");
    318 	BIO_printf (bio_err, "-twopass      separate MAC, encryption passwords\n");
    319 	BIO_printf (bio_err, "-descert      encrypt PKCS#12 certificates with triple DES (default RC2-40)\n");
    320 	BIO_printf (bio_err, "-certpbe alg  specify certificate PBE algorithm (default RC2-40)\n");
    321 	BIO_printf (bio_err, "-keypbe alg   specify private key PBE algorithm (default 3DES)\n");
    322 	BIO_printf (bio_err, "-macalg alg   digest algorithm used in MAC (default SHA1)\n");
    323 	BIO_printf (bio_err, "-keyex        set MS key exchange type\n");
    324 	BIO_printf (bio_err, "-keysig       set MS key signature type\n");
    325 	BIO_printf (bio_err, "-password p   set import/export password source\n");
    326 	BIO_printf (bio_err, "-passin p     input file pass phrase source\n");
    327 	BIO_printf (bio_err, "-passout p    output file pass phrase source\n");
    328 #ifndef OPENSSL_NO_ENGINE
    329 	BIO_printf (bio_err, "-engine e     use engine e, possibly a hardware device.\n");
    330 #endif
    331 	BIO_printf(bio_err,  "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
    332 	BIO_printf(bio_err,  "              load the file (or the files in the directory) into\n");
    333 	BIO_printf(bio_err,  "              the random number generator\n");
    334 	BIO_printf(bio_err,  "-CSP name     Microsoft CSP name\n");
    335 	BIO_printf(bio_err,  "-LMK          Add local machine keyset attribute to private key\n");
    336     	goto end;
    337     }
    338 
    339 #ifndef OPENSSL_NO_ENGINE
    340     e = setup_engine(bio_err, engine, 0);
    341 #endif
    342 
    343     if(passarg) {
    344 	if(export_cert) passargout = passarg;
    345 	else passargin = passarg;
    346     }
    347 
    348     if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
    349 	BIO_printf(bio_err, "Error getting passwords\n");
    350 	goto end;
    351     }
    352 
    353     if(!cpass) {
    354     	if(export_cert) cpass = passout;
    355     	else cpass = passin;
    356     }
    357 
    358     if(cpass) {
    359 	mpass = cpass;
    360 	noprompt = 1;
    361     } else {
    362 	cpass = pass;
    363 	mpass = macpass;
    364     }
    365 
    366     if(export_cert || inrand) {
    367     	app_RAND_load_file(NULL, bio_err, (inrand != NULL));
    368         if (inrand != NULL)
    369 		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
    370 			app_RAND_load_files(inrand));
    371     }
    372     ERR_load_crypto_strings();
    373 
    374 #ifdef CRYPTO_MDEBUG
    375     CRYPTO_push_info("read files");
    376 #endif
    377 
    378     if (!infile) in = BIO_new_fp(stdin, BIO_NOCLOSE);
    379     else in = BIO_new_file(infile, "rb");
    380     if (!in) {
    381 	    BIO_printf(bio_err, "Error opening input file %s\n",
    382 						infile ? infile : "<stdin>");
    383 	    perror (infile);
    384 	    goto end;
    385    }
    386 
    387 #ifdef CRYPTO_MDEBUG
    388     CRYPTO_pop_info();
    389     CRYPTO_push_info("write files");
    390 #endif
    391 
    392     if (!outfile) {
    393 	out = BIO_new_fp(stdout, BIO_NOCLOSE);
    394 #ifdef OPENSSL_SYS_VMS
    395 	{
    396 	    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
    397 	    out = BIO_push(tmpbio, out);
    398 	}
    399 #endif
    400     } else out = BIO_new_file(outfile, "wb");
    401     if (!out) {
    402 	BIO_printf(bio_err, "Error opening output file %s\n",
    403 						outfile ? outfile : "<stdout>");
    404 	perror (outfile);
    405 	goto end;
    406     }
    407     if (twopass) {
    408 #ifdef CRYPTO_MDEBUG
    409     CRYPTO_push_info("read MAC password");
    410 #endif
    411 	if(EVP_read_pw_string (macpass, sizeof macpass, "Enter MAC Password:", export_cert))
    412 	{
    413     	    BIO_printf (bio_err, "Can't read Password\n");
    414     	    goto end;
    415        	}
    416 #ifdef CRYPTO_MDEBUG
    417     CRYPTO_pop_info();
    418 #endif
    419     }
    420 
    421     if (export_cert) {
    422 	EVP_PKEY *key = NULL;
    423 	X509 *ucert = NULL, *x = NULL;
    424 	STACK_OF(X509) *certs=NULL;
    425 	const EVP_MD *macmd = NULL;
    426 	unsigned char *catmp = NULL;
    427 	int i;
    428 
    429 	if ((options & (NOCERTS|NOKEYS)) == (NOCERTS|NOKEYS))
    430 		{
    431 		BIO_printf(bio_err, "Nothing to do!\n");
    432 		goto export_end;
    433 		}
    434 
    435 	if (options & NOCERTS)
    436 		chain = 0;
    437 
    438 #ifdef CRYPTO_MDEBUG
    439 	CRYPTO_push_info("process -export_cert");
    440 	CRYPTO_push_info("reading private key");
    441 #endif
    442 	if (!(options & NOKEYS))
    443 		{
    444 		key = load_key(bio_err, keyname ? keyname : infile,
    445 				FORMAT_PEM, 1, passin, e, "private key");
    446 		if (!key)
    447 			goto export_end;
    448 		}
    449 
    450 #ifdef CRYPTO_MDEBUG
    451 	CRYPTO_pop_info();
    452 	CRYPTO_push_info("reading certs from input");
    453 #endif
    454 
    455 	/* Load in all certs in input file */
    456 	if(!(options & NOCERTS))
    457 		{
    458 		certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e,
    459 							"certificates");
    460 		if (!certs)
    461 			goto export_end;
    462 
    463 		if (key)
    464 			{
    465 			/* Look for matching private key */
    466 			for(i = 0; i < sk_X509_num(certs); i++)
    467 				{
    468 				x = sk_X509_value(certs, i);
    469 				if(X509_check_private_key(x, key))
    470 					{
    471 					ucert = x;
    472 					/* Zero keyid and alias */
    473 					X509_keyid_set1(ucert, NULL, 0);
    474 					X509_alias_set1(ucert, NULL, 0);
    475 					/* Remove from list */
    476 					(void)sk_X509_delete(certs, i);
    477 					break;
    478 					}
    479 				}
    480 			if (!ucert)
    481 				{
    482 				BIO_printf(bio_err, "No certificate matches private key\n");
    483 				goto export_end;
    484 				}
    485 			}
    486 
    487 		}
    488 
    489 #ifdef CRYPTO_MDEBUG
    490 	CRYPTO_pop_info();
    491 	CRYPTO_push_info("reading certs from input 2");
    492 #endif
    493 
    494 	/* Add any more certificates asked for */
    495 	if(certfile)
    496 		{
    497 		STACK_OF(X509) *morecerts=NULL;
    498 		if(!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM,
    499 					    NULL, e,
    500 					    "certificates from certfile")))
    501 			goto export_end;
    502 		while(sk_X509_num(morecerts) > 0)
    503 			sk_X509_push(certs, sk_X509_shift(morecerts));
    504 		sk_X509_free(morecerts);
    505  		}
    506 
    507 #ifdef CRYPTO_MDEBUG
    508 	CRYPTO_pop_info();
    509 	CRYPTO_push_info("reading certs from certfile");
    510 #endif
    511 
    512 #ifdef CRYPTO_MDEBUG
    513 	CRYPTO_pop_info();
    514 	CRYPTO_push_info("building chain");
    515 #endif
    516 
    517 	/* If chaining get chain from user cert */
    518 	if (chain) {
    519         	int vret;
    520 		STACK_OF(X509) *chain2;
    521 		X509_STORE *store = X509_STORE_new();
    522 		if (!store)
    523 			{
    524 			BIO_printf (bio_err, "Memory allocation error\n");
    525 			goto export_end;
    526 			}
    527 		if (!X509_STORE_load_locations(store, CAfile, CApath))
    528 			X509_STORE_set_default_paths (store);
    529 
    530 		vret = get_cert_chain (ucert, store, &chain2);
    531 		X509_STORE_free(store);
    532 
    533 		if (!vret) {
    534 		    /* Exclude verified certificate */
    535 		    for (i = 1; i < sk_X509_num (chain2) ; i++)
    536 			sk_X509_push(certs, sk_X509_value (chain2, i));
    537 		    /* Free first certificate */
    538 		    X509_free(sk_X509_value(chain2, 0));
    539 		    sk_X509_free(chain2);
    540 		} else {
    541 			if (vret >= 0)
    542 				BIO_printf (bio_err, "Error %s getting chain.\n",
    543 					X509_verify_cert_error_string(vret));
    544 			else
    545 				ERR_print_errors(bio_err);
    546 			goto export_end;
    547 		}
    548     	}
    549 
    550 	/* Add any CA names */
    551 
    552 	for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++)
    553 		{
    554 		catmp = (unsigned char *)sk_OPENSSL_STRING_value(canames, i);
    555 		X509_alias_set1(sk_X509_value(certs, i), catmp, -1);
    556 		}
    557 
    558 	if (csp_name && key)
    559 		EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name,
    560 				MBSTRING_ASC, (unsigned char *)csp_name, -1);
    561 
    562 	if (add_lmk && key)
    563 		EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1);
    564 
    565 #ifdef CRYPTO_MDEBUG
    566 	CRYPTO_pop_info();
    567 	CRYPTO_push_info("reading password");
    568 #endif
    569 
    570 	if(!noprompt &&
    571 		EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:", 1))
    572 		{
    573 	    	BIO_printf (bio_err, "Can't read Password\n");
    574 	    	goto export_end;
    575         	}
    576 	if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass);
    577 
    578 #ifdef CRYPTO_MDEBUG
    579 	CRYPTO_pop_info();
    580 	CRYPTO_push_info("creating PKCS#12 structure");
    581 #endif
    582 
    583 	p12 = PKCS12_create(cpass, name, key, ucert, certs,
    584 				key_pbe, cert_pbe, iter, -1, keytype);
    585 
    586 	if (!p12)
    587 		{
    588 	    	ERR_print_errors (bio_err);
    589 		goto export_end;
    590 		}
    591 
    592 	if (macalg)
    593 		{
    594 		macmd = EVP_get_digestbyname(macalg);
    595 		if (!macmd)
    596 			{
    597 			BIO_printf(bio_err, "Unknown digest algorithm %s\n",
    598 						macalg);
    599 			}
    600 		}
    601 
    602 	if (maciter != -1)
    603 		PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd);
    604 
    605 #ifdef CRYPTO_MDEBUG
    606 	CRYPTO_pop_info();
    607 	CRYPTO_push_info("writing pkcs12");
    608 #endif
    609 
    610 	i2d_PKCS12_bio(out, p12);
    611 
    612 	ret = 0;
    613 
    614     export_end:
    615 #ifdef CRYPTO_MDEBUG
    616 	CRYPTO_pop_info();
    617 	CRYPTO_pop_info();
    618 	CRYPTO_push_info("process -export_cert: freeing");
    619 #endif
    620 
    621 	if (key) EVP_PKEY_free(key);
    622 	if (certs) sk_X509_pop_free(certs, X509_free);
    623 	if (ucert) X509_free(ucert);
    624 
    625 #ifdef CRYPTO_MDEBUG
    626 	CRYPTO_pop_info();
    627 #endif
    628 	goto end;
    629 
    630     }
    631 
    632     if (!(p12 = d2i_PKCS12_bio (in, NULL))) {
    633 	ERR_print_errors(bio_err);
    634 	goto end;
    635     }
    636 
    637 #ifdef CRYPTO_MDEBUG
    638     CRYPTO_push_info("read import password");
    639 #endif
    640     if(!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:", 0)) {
    641 	BIO_printf (bio_err, "Can't read Password\n");
    642 	goto end;
    643     }
    644 #ifdef CRYPTO_MDEBUG
    645     CRYPTO_pop_info();
    646 #endif
    647 
    648     if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass);
    649 
    650     if ((options & INFO) && p12->mac) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1);
    651     if(macver) {
    652 #ifdef CRYPTO_MDEBUG
    653     CRYPTO_push_info("verify MAC");
    654 #endif
    655 	/* If we enter empty password try no password first */
    656 	if(!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) {
    657 		/* If mac and crypto pass the same set it to NULL too */
    658 		if(!twopass) cpass = NULL;
    659 	} else if (!PKCS12_verify_mac(p12, mpass, -1)) {
    660 	    BIO_printf (bio_err, "Mac verify error: invalid password?\n");
    661 	    ERR_print_errors (bio_err);
    662 	    goto end;
    663 	}
    664 	BIO_printf (bio_err, "MAC verified OK\n");
    665 #ifdef CRYPTO_MDEBUG
    666     CRYPTO_pop_info();
    667 #endif
    668     }
    669 
    670 #ifdef CRYPTO_MDEBUG
    671     CRYPTO_push_info("output keys and certificates");
    672 #endif
    673     if (!dump_certs_keys_p12 (out, p12, cpass, -1, options, passout)) {
    674 	BIO_printf(bio_err, "Error outputting keys and certificates\n");
    675 	ERR_print_errors (bio_err);
    676 	goto end;
    677     }
    678 #ifdef CRYPTO_MDEBUG
    679     CRYPTO_pop_info();
    680 #endif
    681     ret = 0;
    682  end:
    683     if (p12) PKCS12_free(p12);
    684     if(export_cert || inrand) app_RAND_write_file(NULL, bio_err);
    685 #ifdef CRYPTO_MDEBUG
    686     CRYPTO_remove_all_info();
    687 #endif
    688     BIO_free(in);
    689     BIO_free_all(out);
    690     if (canames) sk_OPENSSL_STRING_free(canames);
    691     if(passin) OPENSSL_free(passin);
    692     if(passout) OPENSSL_free(passout);
    693     apps_shutdown();
    694     OPENSSL_EXIT(ret);
    695 }
    696 
    697 int dump_certs_keys_p12 (BIO *out, PKCS12 *p12, char *pass,
    698 	     int passlen, int options, char *pempass)
    699 {
    700 	STACK_OF(PKCS7) *asafes = NULL;
    701 	STACK_OF(PKCS12_SAFEBAG) *bags;
    702 	int i, bagnid;
    703 	int ret = 0;
    704 	PKCS7 *p7;
    705 
    706 	if (!( asafes = PKCS12_unpack_authsafes(p12))) return 0;
    707 	for (i = 0; i < sk_PKCS7_num (asafes); i++) {
    708 		p7 = sk_PKCS7_value (asafes, i);
    709 		bagnid = OBJ_obj2nid (p7->type);
    710 		if (bagnid == NID_pkcs7_data) {
    711 			bags = PKCS12_unpack_p7data(p7);
    712 			if (options & INFO) BIO_printf (bio_err, "PKCS7 Data\n");
    713 		} else if (bagnid == NID_pkcs7_encrypted) {
    714 			if (options & INFO) {
    715 				BIO_printf(bio_err, "PKCS7 Encrypted data: ");
    716 				alg_print(bio_err,
    717 					p7->d.encrypted->enc_data->algorithm);
    718 			}
    719 			bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
    720 		} else continue;
    721 		if (!bags) goto err;
    722 	    	if (!dump_certs_pkeys_bags (out, bags, pass, passlen,
    723 						 options, pempass)) {
    724 			sk_PKCS12_SAFEBAG_pop_free (bags, PKCS12_SAFEBAG_free);
    725 			goto err;
    726 		}
    727 		sk_PKCS12_SAFEBAG_pop_free (bags, PKCS12_SAFEBAG_free);
    728 		bags = NULL;
    729 	}
    730 	ret = 1;
    731 
    732 	err:
    733 
    734 	if (asafes)
    735 		sk_PKCS7_pop_free (asafes, PKCS7_free);
    736 	return ret;
    737 }
    738 
    739 int dump_certs_pkeys_bags (BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags,
    740 			   char *pass, int passlen, int options, char *pempass)
    741 {
    742 	int i;
    743 	for (i = 0; i < sk_PKCS12_SAFEBAG_num (bags); i++) {
    744 		if (!dump_certs_pkeys_bag (out,
    745 					   sk_PKCS12_SAFEBAG_value (bags, i),
    746 					   pass, passlen,
    747 					   options, pempass))
    748 		    return 0;
    749 	}
    750 	return 1;
    751 }
    752 
    753 int dump_certs_pkeys_bag (BIO *out, PKCS12_SAFEBAG *bag, char *pass,
    754 	     int passlen, int options, char *pempass)
    755 {
    756 	EVP_PKEY *pkey;
    757 	PKCS8_PRIV_KEY_INFO *p8;
    758 	X509 *x509;
    759 
    760 	switch (M_PKCS12_bag_type(bag))
    761 	{
    762 	case NID_keyBag:
    763 		if (options & INFO) BIO_printf (bio_err, "Key bag\n");
    764 		if (options & NOKEYS) return 1;
    765 		print_attribs (out, bag->attrib, "Bag Attributes");
    766 		p8 = bag->value.keybag;
    767 		if (!(pkey = EVP_PKCS82PKEY (p8))) return 0;
    768 		print_attribs (out, p8->attributes, "Key Attributes");
    769 		PEM_write_bio_PrivateKey (out, pkey, enc, NULL, 0, NULL, pempass);
    770 		EVP_PKEY_free(pkey);
    771 	break;
    772 
    773 	case NID_pkcs8ShroudedKeyBag:
    774 		if (options & INFO) {
    775 			BIO_printf (bio_err, "Shrouded Keybag: ");
    776 			alg_print (bio_err, bag->value.shkeybag->algor);
    777 		}
    778 		if (options & NOKEYS) return 1;
    779 		print_attribs (out, bag->attrib, "Bag Attributes");
    780 		if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen)))
    781 				return 0;
    782 		if (!(pkey = EVP_PKCS82PKEY (p8))) {
    783 			PKCS8_PRIV_KEY_INFO_free(p8);
    784 			return 0;
    785 		}
    786 		print_attribs (out, p8->attributes, "Key Attributes");
    787 		PKCS8_PRIV_KEY_INFO_free(p8);
    788 		PEM_write_bio_PrivateKey (out, pkey, enc, NULL, 0, NULL, pempass);
    789 		EVP_PKEY_free(pkey);
    790 	break;
    791 
    792 	case NID_certBag:
    793 		if (options & INFO) BIO_printf (bio_err, "Certificate bag\n");
    794 		if (options & NOCERTS) return 1;
    795                 if (PKCS12_get_attr(bag, NID_localKeyID)) {
    796 			if (options & CACERTS) return 1;
    797 		} else if (options & CLCERTS) return 1;
    798 		print_attribs (out, bag->attrib, "Bag Attributes");
    799 		if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate )
    800 								 return 1;
    801 		if (!(x509 = PKCS12_certbag2x509(bag))) return 0;
    802 		dump_cert_text (out, x509);
    803 		PEM_write_bio_X509 (out, x509);
    804 		X509_free(x509);
    805 	break;
    806 
    807 	case NID_safeContentsBag:
    808 		if (options & INFO) BIO_printf (bio_err, "Safe Contents bag\n");
    809 		print_attribs (out, bag->attrib, "Bag Attributes");
    810 		return dump_certs_pkeys_bags (out, bag->value.safes, pass,
    811 							    passlen, options, pempass);
    812 
    813 	default:
    814 		BIO_printf (bio_err, "Warning unsupported bag type: ");
    815 		i2a_ASN1_OBJECT (bio_err, bag->type);
    816 		BIO_printf (bio_err, "\n");
    817 		return 1;
    818 	break;
    819 	}
    820 	return 1;
    821 }
    822 
    823 /* Given a single certificate return a verified chain or NULL if error */
    824 
    825 /* Hope this is OK .... */
    826 
    827 int get_cert_chain (X509 *cert, X509_STORE *store, STACK_OF(X509) **chain)
    828 {
    829 	X509_STORE_CTX store_ctx;
    830 	STACK_OF(X509) *chn;
    831 	int i = 0;
    832 
    833 	/* FIXME: Should really check the return status of X509_STORE_CTX_init
    834 	 * for an error, but how that fits into the return value of this
    835 	 * function is less obvious. */
    836 	X509_STORE_CTX_init(&store_ctx, store, cert, NULL);
    837 	if (X509_verify_cert(&store_ctx) <= 0) {
    838 		i = X509_STORE_CTX_get_error (&store_ctx);
    839 		if (i == 0)
    840 			/* avoid returning 0 if X509_verify_cert() did not
    841 			 * set an appropriate error value in the context */
    842 			i = -1;
    843 		chn = NULL;
    844 		goto err;
    845 	} else
    846 		chn = X509_STORE_CTX_get1_chain(&store_ctx);
    847 err:
    848 	X509_STORE_CTX_cleanup(&store_ctx);
    849 	*chain = chn;
    850 
    851 	return i;
    852 }
    853 
    854 int alg_print (BIO *x, X509_ALGOR *alg)
    855 {
    856 	PBEPARAM *pbe;
    857 	const unsigned char *p;
    858 	p = alg->parameter->value.sequence->data;
    859 	pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length);
    860 	if (!pbe)
    861 		return 1;
    862 	BIO_printf (bio_err, "%s, Iteration %ld\n",
    863 		OBJ_nid2ln(OBJ_obj2nid(alg->algorithm)),
    864 		ASN1_INTEGER_get(pbe->iter));
    865 	PBEPARAM_free (pbe);
    866 	return 1;
    867 }
    868 
    869 /* Load all certificates from a given file */
    870 
    871 int cert_load(BIO *in, STACK_OF(X509) *sk)
    872 {
    873 	int ret;
    874 	X509 *cert;
    875 	ret = 0;
    876 #ifdef CRYPTO_MDEBUG
    877 	CRYPTO_push_info("cert_load(): reading one cert");
    878 #endif
    879 	while((cert = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
    880 #ifdef CRYPTO_MDEBUG
    881 		CRYPTO_pop_info();
    882 #endif
    883 		ret = 1;
    884 		sk_X509_push(sk, cert);
    885 #ifdef CRYPTO_MDEBUG
    886 		CRYPTO_push_info("cert_load(): reading one cert");
    887 #endif
    888 	}
    889 #ifdef CRYPTO_MDEBUG
    890 	CRYPTO_pop_info();
    891 #endif
    892 	if(ret) ERR_clear_error();
    893 	return ret;
    894 }
    895 
    896 /* Generalised attribute print: handle PKCS#8 and bag attributes */
    897 
    898 int print_attribs (BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,const char *name)
    899 {
    900 	X509_ATTRIBUTE *attr;
    901 	ASN1_TYPE *av;
    902 	char *value;
    903 	int i, attr_nid;
    904 	if(!attrlst) {
    905 		BIO_printf(out, "%s: <No Attributes>\n", name);
    906 		return 1;
    907 	}
    908 	if(!sk_X509_ATTRIBUTE_num(attrlst)) {
    909 		BIO_printf(out, "%s: <Empty Attributes>\n", name);
    910 		return 1;
    911 	}
    912 	BIO_printf(out, "%s\n", name);
    913 	for(i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) {
    914 		attr = sk_X509_ATTRIBUTE_value(attrlst, i);
    915 		attr_nid = OBJ_obj2nid(attr->object);
    916 		BIO_printf(out, "    ");
    917 		if(attr_nid == NID_undef) {
    918 			i2a_ASN1_OBJECT (out, attr->object);
    919 			BIO_printf(out, ": ");
    920 		} else BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid));
    921 
    922 		if(sk_ASN1_TYPE_num(attr->value.set)) {
    923 			av = sk_ASN1_TYPE_value(attr->value.set, 0);
    924 			switch(av->type) {
    925 				case V_ASN1_BMPSTRING:
    926         			value = OPENSSL_uni2asc(av->value.bmpstring->data,
    927                                 	       av->value.bmpstring->length);
    928 				BIO_printf(out, "%s\n", value);
    929 				OPENSSL_free(value);
    930 				break;
    931 
    932 				case V_ASN1_OCTET_STRING:
    933 				hex_prin(out, av->value.octet_string->data,
    934 					av->value.octet_string->length);
    935 				BIO_printf(out, "\n");
    936 				break;
    937 
    938 				case V_ASN1_BIT_STRING:
    939 				hex_prin(out, av->value.bit_string->data,
    940 					av->value.bit_string->length);
    941 				BIO_printf(out, "\n");
    942 				break;
    943 
    944 				default:
    945 					BIO_printf(out, "<Unsupported tag %d>\n", av->type);
    946 				break;
    947 			}
    948 		} else BIO_printf(out, "<No Values>\n");
    949 	}
    950 	return 1;
    951 }
    952 
    953 void hex_prin(BIO *out, unsigned char *buf, int len)
    954 {
    955 	int i;
    956 	for (i = 0; i < len; i++) BIO_printf (out, "%02X ", buf[i]);
    957 }
    958 
    959 static int set_pbe(BIO *err, int *ppbe, const char *str)
    960 	{
    961 	if (!str)
    962 		return 0;
    963 	if (!strcmp(str, "NONE"))
    964 		{
    965 		*ppbe = -1;
    966 		return 1;
    967 		}
    968 	*ppbe=OBJ_txt2nid(str);
    969 	if (*ppbe == NID_undef)
    970 		{
    971 		BIO_printf(bio_err, "Unknown PBE algorithm %s\n", str);
    972 		return 0;
    973 		}
    974 	return 1;
    975 	}
    976 
    977 #endif
    978