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