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