1 /* $OpenBSD: pkcs12.c,v 1.23 2022/09/14 16:31:36 tb 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 static int get_cert_chain(X509 *cert, X509_STORE *store,
81     STACK_OF(X509) **chain);
82 static int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int passlen,
83     int options, char *pempass);
84 static int dump_certs_pkeys_bags(BIO *out, const STACK_OF(PKCS12_SAFEBAG) *bags,
85     char *pass, int passlen, int options, char *pempass);
86 static int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass,
87     int passlen, int options, char *pempass);
88 static int print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst,
89     const char *name);
90 static void hex_prin(BIO *out, unsigned char *buf, int len);
91 static int alg_print(BIO *x, const X509_ALGOR *alg);
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
pkcs12_opt_canames(char * arg)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
pkcs12_opt_cert_pbe(char * arg)137 pkcs12_opt_cert_pbe(char *arg)
138 {
139 	return (!set_pbe(bio_err, &pkcs12_config.cert_pbe, arg));
140 }
141 
142 static int
pkcs12_opt_key_pbe(char * arg)143 pkcs12_opt_key_pbe(char *arg)
144 {
145 	return (!set_pbe(bio_err, &pkcs12_config.key_pbe, arg));
146 }
147 
148 static int
pkcs12_opt_passarg(char * arg)149 pkcs12_opt_passarg(char *arg)
150 {
151 	pkcs12_config.passarg = arg;
152 	pkcs12_config.noprompt = 1;
153 	return (0);
154 }
155 
get_cipher_by_name(char * name)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
pkcs12_opt_enc(int argc,char ** argv,int * argsused)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
pkcs12_usage(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
pkcs12_main(int argc,char ** argv)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 != NULL) {
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 == NULL) {
571 		if (pkcs12_config.export_cert)
572 			cpass = passout;
573 		else
574 			cpass = passin;
575 	}
576 	if (cpass != NULL) {
577 		mpass = cpass;
578 		pkcs12_config.noprompt = 1;
579 	} else {
580 		cpass = pass;
581 		mpass = macpass;
582 	}
583 
584 	if (pkcs12_config.infile == NULL)
585 		in = BIO_new_fp(stdin, BIO_NOCLOSE);
586 	else
587 		in = BIO_new_file(pkcs12_config.infile, "rb");
588 	if (in == NULL) {
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 == NULL) {
596 		out = BIO_new_fp(stdout, BIO_NOCLOSE);
597 	} else
598 		out = BIO_new_file(pkcs12_config.outfile, "wb");
599 	if (out == NULL) {
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 == NULL)
641 				goto export_end;
642 
643 			if (key != NULL) {
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 == NULL) {
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 != NULL) {
667 			STACK_OF(X509) *morecerts = NULL;
668 			if ((morecerts = load_certs(bio_err,
669 			    pkcs12_config.certfile, FORMAT_PEM, NULL,
670 			    "certificates from certfile")) == NULL)
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 == NULL) {
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 == X509_V_OK) {
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 != X509_V_ERR_UNSPECIFIED)
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 != NULL && key != NULL)
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 != NULL)
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 == NULL) {
747 			ERR_print_errors(bio_err);
748 			goto export_end;
749 		}
750 		if (pkcs12_config.macalg != NULL) {
751 			macmd = EVP_get_digestbyname(pkcs12_config.macalg);
752 			if (macmd == NULL) {
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)) == 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) != 0 && PKCS12_mac_present(p12)) {
788 		const ASN1_INTEGER *iter;
789 
790 		PKCS12_get0_mac(NULL, NULL, NULL, &iter, p12);
791 		BIO_printf(bio_err, "MAC Iteration %ld\n",
792 		    iter != NULL ? ASN1_INTEGER_get(iter) : 1);
793 	}
794 	if (pkcs12_config.macver) {
795 		/* If we enter empty password try no password first */
796 		if (!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) {
797 			/* If mac and crypto pass the same set it to NULL too */
798 			if (!pkcs12_config.twopass)
799 				cpass = NULL;
800 		} else if (!PKCS12_verify_mac(p12, mpass, -1)) {
801 			BIO_printf(bio_err,
802 			    "Mac verify error: invalid password?\n");
803 			ERR_print_errors(bio_err);
804 			goto end;
805 		}
806 		BIO_printf(bio_err, "MAC verified OK\n");
807 	}
808 	if (!dump_certs_keys_p12(out, p12, cpass, -1, pkcs12_config.options,
809 	    passout)) {
810 		BIO_printf(bio_err, "Error outputting keys and certificates\n");
811 		ERR_print_errors(bio_err);
812 		goto end;
813 	}
814 	ret = 0;
815  end:
816 	PKCS12_free(p12);
817 	BIO_free(in);
818 	BIO_free_all(out);
819 	sk_OPENSSL_STRING_free(pkcs12_config.canames);
820 	free(passin);
821 	free(passout);
822 
823 	return (ret);
824 }
825 
826 static int
dump_certs_keys_p12(BIO * out,PKCS12 * p12,char * pass,int passlen,int options,char * pempass)827 dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int passlen, int options,
828     char *pempass)
829 {
830 	STACK_OF(PKCS7) *asafes = NULL;
831 	STACK_OF(PKCS12_SAFEBAG) *bags;
832 	int i, bagnid;
833 	int ret = 0;
834 	PKCS7 *p7;
835 
836 	if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL)
837 		return 0;
838 	for (i = 0; i < sk_PKCS7_num(asafes); i++) {
839 		p7 = sk_PKCS7_value(asafes, i);
840 		bagnid = OBJ_obj2nid(p7->type);
841 		if (bagnid == NID_pkcs7_data) {
842 			bags = PKCS12_unpack_p7data(p7);
843 			if (options & INFO)
844 				BIO_printf(bio_err, "PKCS7 Data\n");
845 		} else if (bagnid == NID_pkcs7_encrypted) {
846 			if (options & INFO) {
847 				BIO_printf(bio_err, "PKCS7 Encrypted data: ");
848 				alg_print(bio_err,
849 				    p7->d.encrypted->enc_data->algorithm);
850 			}
851 			bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
852 		} else
853 			continue;
854 		if (bags == NULL)
855 			goto err;
856 		if (!dump_certs_pkeys_bags(out, bags, pass, passlen,
857 			options, pempass)) {
858 			sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
859 			goto err;
860 		}
861 		sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
862 		bags = NULL;
863 	}
864 	ret = 1;
865 
866  err:
867 	sk_PKCS7_pop_free(asafes, PKCS7_free);
868 	return ret;
869 }
870 
871 static int
dump_certs_pkeys_bags(BIO * out,const STACK_OF (PKCS12_SAFEBAG)* bags,char * pass,int passlen,int options,char * pempass)872 dump_certs_pkeys_bags(BIO *out, const STACK_OF(PKCS12_SAFEBAG) *bags,
873     char *pass, int passlen, int options, char *pempass)
874 {
875 	int i;
876 
877 	for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
878 		if (!dump_certs_pkeys_bag(out,
879 			sk_PKCS12_SAFEBAG_value(bags, i),
880 			pass, passlen,
881 			options, pempass))
882 			return 0;
883 	}
884 	return 1;
885 }
886 
887 static int
dump_certs_pkeys_bag(BIO * out,PKCS12_SAFEBAG * bag,char * pass,int passlen,int options,char * pempass)888 dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bag, char *pass, int passlen,
889     int options, char *pempass)
890 {
891 	EVP_PKEY *pkey;
892 	const STACK_OF(X509_ATTRIBUTE) *attrs;
893 	X509 *x509;
894 
895 	attrs = PKCS12_SAFEBAG_get0_attrs(bag);
896 
897 	switch (PKCS12_SAFEBAG_get_nid(bag)) {
898 	case NID_keyBag:
899 	    {
900 		const PKCS8_PRIV_KEY_INFO *p8;
901 
902 		if (options & INFO)
903 			BIO_printf(bio_err, "Key bag\n");
904 		if (options & NOKEYS)
905 			return 1;
906 		print_attribs(out, attrs, "Bag Attributes");
907 		if ((p8 = PKCS12_SAFEBAG_get0_p8inf(bag)) == NULL)
908 			return 0;
909 		if ((pkey = EVP_PKCS82PKEY(p8)) == NULL)
910 			return 0;
911 		print_attribs(out, PKCS8_pkey_get0_attrs(p8), "Key Attributes");
912 		PEM_write_bio_PrivateKey(out, pkey, pkcs12_config.enc, NULL, 0,
913 		    NULL, pempass);
914 		EVP_PKEY_free(pkey);
915 		break;
916 	    }
917 
918 	case NID_pkcs8ShroudedKeyBag:
919 	    {
920 		PKCS8_PRIV_KEY_INFO *p8;
921 
922 		if (options & INFO) {
923 			const X509_SIG *tp8;
924 			const X509_ALGOR *tp8alg;
925 
926 			BIO_printf(bio_err, "Shrouded Keybag: ");
927 			if ((tp8 = PKCS12_SAFEBAG_get0_pkcs8(bag)) == NULL)
928 				return 0;
929 			X509_SIG_get0(tp8, &tp8alg, NULL);
930 			alg_print(bio_err, tp8alg);
931 		}
932 		if (options & NOKEYS)
933 			return 1;
934 		print_attribs(out, attrs, "Bag Attributes");
935 		if ((p8 = PKCS12_decrypt_skey(bag, pass, passlen)) == NULL)
936 			return 0;
937 		if ((pkey = EVP_PKCS82PKEY(p8)) == NULL) {
938 			PKCS8_PRIV_KEY_INFO_free(p8);
939 			return 0;
940 		}
941 		print_attribs(out, PKCS8_pkey_get0_attrs(p8), "Key Attributes");
942 		PKCS8_PRIV_KEY_INFO_free(p8);
943 		PEM_write_bio_PrivateKey(out, pkey, pkcs12_config.enc, NULL, 0,
944 		    NULL, pempass);
945 		EVP_PKEY_free(pkey);
946 		break;
947 	    }
948 
949 	case NID_certBag:
950 		if (options & INFO)
951 			BIO_printf(bio_err, "Certificate bag\n");
952 		if (options & NOCERTS)
953 			return 1;
954 		if (PKCS12_SAFEBAG_get0_attr(bag, NID_localKeyID) != NULL) {
955 			if (options & CACERTS)
956 				return 1;
957 		} else if (options & CLCERTS)
958 			return 1;
959 		print_attribs(out, attrs, "Bag Attributes");
960 		if (PKCS12_SAFEBAG_get_bag_nid(bag) != NID_x509Certificate)
961 			return 1;
962 		if ((x509 = PKCS12_certbag2x509(bag)) == NULL)
963 			return 0;
964 		dump_cert_text(out, x509);
965 		PEM_write_bio_X509(out, x509);
966 		X509_free(x509);
967 		break;
968 
969 	case NID_safeContentsBag:
970 		if (options & INFO)
971 			BIO_printf(bio_err, "Safe Contents bag\n");
972 		print_attribs(out, attrs, "Bag Attributes");
973 		return dump_certs_pkeys_bags(out, PKCS12_SAFEBAG_get0_safes(bag),
974 		    pass, passlen, options, pempass);
975 
976 	default:
977 		BIO_printf(bio_err, "Warning unsupported bag type: ");
978 		i2a_ASN1_OBJECT(bio_err, PKCS12_SAFEBAG_get0_type(bag));
979 		BIO_printf(bio_err, "\n");
980 		return 1;
981 		break;
982 	}
983 	return 1;
984 }
985 
986 /* Given a single certificate return a verified chain or NULL if error */
987 static int
get_cert_chain(X509 * cert,X509_STORE * store,STACK_OF (X509)** out_chain)988 get_cert_chain(X509 *cert, X509_STORE *store, STACK_OF(X509) **out_chain)
989 {
990 	X509_STORE_CTX *store_ctx = NULL;
991 	STACK_OF(X509) *chain = NULL;
992 	int ret = X509_V_ERR_UNSPECIFIED;
993 
994 	if ((store_ctx = X509_STORE_CTX_new()) == NULL)
995 		goto err;
996 	if (!X509_STORE_CTX_init(store_ctx, store, cert, NULL))
997 		goto err;
998 
999 	if (X509_verify_cert(store_ctx) > 0) {
1000 		if ((chain = X509_STORE_CTX_get1_chain(store_ctx)) == NULL)
1001 			goto err;
1002 	}
1003 	ret = X509_STORE_CTX_get_error(store_ctx);
1004 
1005  err:
1006 	X509_STORE_CTX_free(store_ctx);
1007 	*out_chain = chain;
1008 
1009 	return ret;
1010 }
1011 
1012 static int
alg_print(BIO * x,const X509_ALGOR * alg)1013 alg_print(BIO *x, const X509_ALGOR *alg)
1014 {
1015 	PBEPARAM *pbe;
1016 	const unsigned char *p;
1017 
1018 	p = alg->parameter->value.sequence->data;
1019 	pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length);
1020 	if (pbe == NULL)
1021 		return 1;
1022 	BIO_printf(bio_err, "%s, Iteration %ld\n",
1023 	    OBJ_nid2ln(OBJ_obj2nid(alg->algorithm)),
1024 	    ASN1_INTEGER_get(pbe->iter));
1025 	PBEPARAM_free(pbe);
1026 	return 1;
1027 }
1028 
1029 /* Generalised attribute print: handle PKCS#8 and bag attributes */
1030 static void
print_attribute(BIO * out,const ASN1_TYPE * av)1031 print_attribute(BIO *out, const ASN1_TYPE *av)
1032 {
1033 	char *value;
1034 
1035 	switch (av->type) {
1036 	case V_ASN1_BMPSTRING:
1037 		value = OPENSSL_uni2asc(
1038 		    av->value.bmpstring->data,
1039 		    av->value.bmpstring->length);
1040 		BIO_printf(out, "%s\n", value);
1041 		free(value);
1042 		break;
1043 
1044 	case V_ASN1_OCTET_STRING:
1045 		hex_prin(out, av->value.octet_string->data,
1046 		    av->value.octet_string->length);
1047 		BIO_printf(out, "\n");
1048 		break;
1049 
1050 	case V_ASN1_BIT_STRING:
1051 		hex_prin(out, av->value.bit_string->data,
1052 		    av->value.bit_string->length);
1053 		BIO_printf(out, "\n");
1054 		break;
1055 
1056 	default:
1057 		BIO_printf(out, "<Unsupported tag %d>\n",
1058 		    av->type);
1059 		break;
1060 	}
1061 }
1062 
1063 static int
print_attribs(BIO * out,const STACK_OF (X509_ATTRIBUTE)* attrlst,const char * name)1064 print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst,
1065     const char *name)
1066 {
1067 	X509_ATTRIBUTE *attr;
1068 	ASN1_TYPE *av;
1069 	int i, j, attr_nid;
1070 
1071 	if (attrlst == NULL) {
1072 		BIO_printf(out, "%s: <No Attributes>\n", name);
1073 		return 1;
1074 	}
1075 	if (!sk_X509_ATTRIBUTE_num(attrlst)) {
1076 		BIO_printf(out, "%s: <Empty Attributes>\n", name);
1077 		return 1;
1078 	}
1079 	BIO_printf(out, "%s\n", name);
1080 	for (i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) {
1081 		ASN1_OBJECT *obj;
1082 
1083 		attr = sk_X509_ATTRIBUTE_value(attrlst, i);
1084 		obj = X509_ATTRIBUTE_get0_object(attr);
1085 		attr_nid = OBJ_obj2nid(X509_ATTRIBUTE_get0_object(attr));
1086 		BIO_printf(out, "    ");
1087 		if (attr_nid == NID_undef) {
1088 			i2a_ASN1_OBJECT(out, obj);
1089 			BIO_printf(out, ": ");
1090 		} else
1091 			BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid));
1092 
1093 		if (X509_ATTRIBUTE_count(attr)) {
1094 			for (j = 0; j < X509_ATTRIBUTE_count(attr); j++) {
1095 				av = X509_ATTRIBUTE_get0_type(attr, j);
1096 				print_attribute(out, av);
1097 			}
1098 		} else
1099 			BIO_printf(out, "<No Values>\n");
1100 	}
1101 	return 1;
1102 }
1103 
1104 static void
hex_prin(BIO * out,unsigned char * buf,int len)1105 hex_prin(BIO *out, unsigned char *buf, int len)
1106 {
1107 	int i;
1108 
1109 	for (i = 0; i < len; i++)
1110 		BIO_printf(out, "%02X ", buf[i]);
1111 }
1112 
1113 static int
set_pbe(BIO * err,int * ppbe,const char * str)1114 set_pbe(BIO *err, int *ppbe, const char *str)
1115 {
1116 	if (str == NULL)
1117 		return 0;
1118 	if (strcmp(str, "NONE") == 0) {
1119 		*ppbe = -1;
1120 		return 1;
1121 	}
1122 	*ppbe = OBJ_txt2nid(str);
1123 	if (*ppbe == NID_undef) {
1124 		BIO_printf(bio_err, "Unknown PBE algorithm %s\n", str);
1125 		return 0;
1126 	}
1127 	return 1;
1128 }
1129 
1130 #endif
1131