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