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