]> git.ipfire.org Git - thirdparty/openssl.git/blame - apps/pkcs12.c
Run the withlibctx.pl script
[thirdparty/openssl.git] / apps / pkcs12.c
CommitLineData
0f113f3e 1/*
33388b44 2 * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved.
ee0508d4 3 *
dffa7520 4 * Licensed under the Apache License 2.0 (the "License"). You may not use
846e33c7
RS
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
ee0508d4
DSH
8 */
9
6e04afb8 10#include <openssl/opensslconf.h>
6e04afb8 11
1ae56f2f
RS
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include "apps.h"
16#include "progs.h"
17#include <openssl/crypto.h>
18#include <openssl/err.h>
19#include <openssl/pem.h>
20#include <openssl/pkcs12.h>
15c9aa3a 21#include <openssl/provider.h>
1ae56f2f
RS
22
23#define NOKEYS 0x1
24#define NOCERTS 0x2
25#define INFO 0x4
26#define CLCERTS 0x8
27#define CACERTS 0x10
0f113f3e 28
eee95522
P
29#define PASSWD_BUF_SIZE 2048
30
e29c73c9 31static int get_cert_chain(X509 *cert, X509_STORE *store,
1d6c8670 32 STACK_OF(X509) *untrusted_certs,
e29c73c9 33 STACK_OF(X509) **chain);
28da1455
MC
34int dump_certs_keys_p12(BIO *out, const PKCS12 *p12,
35 const char *pass, int passlen, int options,
36 char *pempass, const EVP_CIPHER *enc);
37int dump_certs_pkeys_bags(BIO *out, const STACK_OF(PKCS12_SAFEBAG) *bags,
38 const char *pass, int passlen, int options,
39 char *pempass, const EVP_CIPHER *enc);
40int dump_certs_pkeys_bag(BIO *out, const PKCS12_SAFEBAG *bags,
41 const char *pass, int passlen,
42 int options, char *pempass, const EVP_CIPHER *enc);
dbcc7b45 43void print_attribute(BIO *out, const ASN1_TYPE *av);
b2e57e09 44int print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst,
0f113f3e 45 const char *name);
ee0508d4 46void hex_prin(BIO *out, unsigned char *buf, int len);
59b4da05 47static int alg_print(const X509_ALGOR *alg);
84c15db5 48int cert_load(BIO *in, STACK_OF(X509) *sk);
7e1b7485
RS
49static int set_pbe(int *ppbe, const char *str);
50
51typedef enum OPTION_choice {
52 OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
53 OPT_CIPHER, OPT_NOKEYS, OPT_KEYEX, OPT_KEYSIG, OPT_NOCERTS, OPT_CLCERTS,
54 OPT_CACERTS, OPT_NOOUT, OPT_INFO, OPT_CHAIN, OPT_TWOPASS, OPT_NOMACVER,
1fdde917 55 OPT_DESCERT, OPT_EXPORT, OPT_ITER, OPT_NOITER, OPT_MACITER, OPT_NOMACITER,
ef898017 56 OPT_NOMAC, OPT_LMK, OPT_NODES, OPT_NOENC, OPT_MACALG, OPT_CERTPBE, OPT_KEYPBE,
1d6c8670
DDO
57 OPT_INKEY, OPT_CERTFILE, OPT_UNTRUSTED, OPT_PASSCERTS,
58 OPT_NAME, OPT_CSP, OPT_CANAME,
7e1b7485 59 OPT_IN, OPT_OUT, OPT_PASSIN, OPT_PASSOUT, OPT_PASSWORD, OPT_CAPATH,
fd3397fc 60 OPT_CAFILE, OPT_CASTORE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE, OPT_ENGINE,
15c9aa3a 61 OPT_R_ENUM, OPT_PROV_ENUM, OPT_LEGACY_ALG
7e1b7485
RS
62} OPTION_CHOICE;
63
44c83ebd 64const OPTIONS pkcs12_options[] = {
5388f986 65 OPT_SECTION("General"),
7e1b7485 66 {"help", OPT_HELP, '-', "Display this summary"},
15c9aa3a 67 {"legacy", OPT_LEGACY_ALG, '-', "use legacy algorithms"},
1ae56f2f 68#ifndef OPENSSL_NO_ENGINE
5388f986 69 {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
1ae56f2f 70#endif
5388f986 71
1d6c8670 72 OPT_SECTION("CA input for export with the -chain option"),
5388f986
RS
73 {"CApath", OPT_CAPATH, '/', "PEM-format directory of CA's"},
74 {"CAfile", OPT_CAFILE, '<', "PEM-format file of CA's"},
75 {"CAstore", OPT_CASTORE, ':', "URI to store of CA's"},
76 {"no-CAfile", OPT_NOCAFILE, '-',
77 "Do not load the default certificates file"},
78 {"no-CApath", OPT_NOCAPATH, '-',
79 "Do not load certificates from the default certificates directory"},
80 {"no-CAstore", OPT_NOCASTORE, '-',
81 "Do not load certificates from the default certificates store"},
82
83 OPT_SECTION("Input"),
1d6c8670
DDO
84 {"in", OPT_IN, '<', "Input file for PKCS12 parsing or certs and possibly key"},
85 {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
86 {"inkey", OPT_INKEY, 's', "Private key, else read from -in input file"},
87 {"certfile", OPT_CERTFILE, '<', "Extra certificates for PKCS12 output"},
88 {"untrusted", OPT_UNTRUSTED, '<', "Untrusted certificates for chain building"},
b3c5aadf 89 {"passcerts", OPT_PASSCERTS, 's', "Certificate file pass phrase source"},
5388f986
RS
90 {"name", OPT_NAME, 's', "Use name as friendly name"},
91 {"CSP", OPT_CSP, 's', "Microsoft CSP name"},
92 {"caname", OPT_CANAME, 's',
93 "Use name as CA friendly name (can be repeated)"},
5388f986
RS
94
95 OPT_SECTION("Output"),
96 {"export", OPT_EXPORT, '-', "Output PKCS12 file"},
97 {"LMK", OPT_LMK, '-',
98 "Add local machine keyset attribute to private key"},
99 {"macalg", OPT_MACALG, 's',
1d6c8670 100 "Digest algorithm to use in MAC (default SHA1)"},
5388f986
RS
101 {"keypbe", OPT_KEYPBE, 's', "Private key PBE algorithm (default 3DES)"},
102 {"out", OPT_OUT, '>', "Output filename"},
1d6c8670 103 {"passout", OPT_PASSOUT, 's', "Output pass phrase source"},
5388f986 104 {"password", OPT_PASSWORD, 's', "Set import/export password source"},
7e1b7485
RS
105 {"nocerts", OPT_NOCERTS, '-', "Don't output certificates"},
106 {"clcerts", OPT_CLCERTS, '-', "Only output client certificates"},
107 {"cacerts", OPT_CACERTS, '-', "Only output CA certificates"},
1d6c8670
DDO
108 {"noout", OPT_NOOUT, '-', "Don't output anything, just verify PKCS#12 input"},
109 {"chain", OPT_CHAIN, '-', "Build and add certificate chain for EE cert,"},
110 {OPT_MORE_STR, 0, 0,
111 "which is the 1st cert from -in matching the private key (if given)"},
7e1b7485
RS
112 {"twopass", OPT_TWOPASS, '-', "Separate MAC, encryption passwords"},
113 {"nomacver", OPT_NOMACVER, '-', "Don't verify MAC"},
5388f986
RS
114 {"info", OPT_INFO, '-', "Print info about PKCS#12 structure"},
115 {"nokeys", OPT_NOKEYS, '-', "Don't output private keys"},
1d6c8670
DDO
116 {"keyex", OPT_KEYEX, '-', "Set key type to MS key exchange"},
117 {"keysig", OPT_KEYSIG, '-', "Set key type to MS key signature"},
5388f986 118
1d6c8670 119 OPT_SECTION("PKCS12 output encryption and MAC"),
1ae56f2f 120#ifndef OPENSSL_NO_RC2
7e1b7485 121 {"descert", OPT_DESCERT, '-',
15c9aa3a 122 "Encrypt output with 3DES (default PBES2 with PBKDF2 and AES-256 CBC)"},
7e1b7485 123 {"certpbe", OPT_CERTPBE, 's',
15c9aa3a 124 "Certificate PBE algorithm (default PBES2 with PBKDF2 and AES-256 CBC)"},
1ae56f2f 125#else
7e1b7485
RS
126 {"descert", OPT_DESCERT, '-', "Encrypt output with 3DES (the default)"},
127 {"certpbe", OPT_CERTPBE, 's', "Certificate PBE algorithm (default 3DES)"},
1ae56f2f 128#endif
1fdde917
IG
129 {"iter", OPT_ITER, 'p', "Specify the iteration count for encryption key and MAC"},
130 {"noiter", OPT_NOITER, '-', "Don't use encryption key iteration"},
131 {"maciter", OPT_MACITER, '-', "Unused, kept for backwards compatibility"},
7e1b7485
RS
132 {"nomaciter", OPT_NOMACITER, '-', "Don't use MAC iteration"},
133 {"nomac", OPT_NOMAC, '-', "Don't generate MAC"},
ef898017
DDO
134 {"noenc", OPT_NOENC, '-', "Don't encrypt private keys"},
135 {"nodes", OPT_NODES, '-', "Don't encrypt private keys; deprecated"},
9c3bcfa0 136 {"", OPT_CIPHER, '-', "Any supported cipher"},
5388f986
RS
137
138 OPT_R_OPTIONS,
6bd4e3f2 139 OPT_PROV_OPTIONS,
7e1b7485
RS
140 {NULL}
141};
667ac4ec 142
7e1b7485 143int pkcs12_main(int argc, char **argv)
ee0508d4 144{
7e1b7485 145 char *infile = NULL, *outfile = NULL, *keyname = NULL, *certfile = NULL;
1d6c8670 146 char *untrusted = NULL;
b3c5aadf 147 char *passcertsarg = NULL, *passcerts = NULL;
7e1b7485 148 char *name = NULL, *csp_name = NULL;
eee95522 149 char pass[PASSWD_BUF_SIZE] = "", macpass[PASSWD_BUF_SIZE] = "";
15c9aa3a 150 int export_cert = 0, options = 0, chain = 0, twopass = 0, keytype = 0, use_legacy = 0;
7e1b7485 151 int iter = PKCS12_DEFAULT_ITER, maciter = PKCS12_DEFAULT_ITER;
15c9aa3a
SP
152 int cert_pbe = NID_aes_256_cbc;
153 int key_pbe = NID_aes_256_cbc;
923b1857
RL
154 int ret = 1, macver = 1, add_lmk = 0, private = 0;
155 int noprompt = 0;
7e1b7485 156 char *passinarg = NULL, *passoutarg = NULL, *passarg = NULL;
3ee1eac2 157 char *passin = NULL, *passout = NULL, *macalg = NULL;
647ac8d3 158 char *cpass = NULL, *mpass = NULL, *badpass = NULL;
fd3397fc
RL
159 const char *CApath = NULL, *CAfile = NULL, *CAstore = NULL, *prog;
160 int noCApath = 0, noCAfile = 0, noCAstore = 0;
7e1b7485
RS
161 ENGINE *e = NULL;
162 BIO *in = NULL, *out = NULL;
163 PKCS12 *p12 = NULL;
c869da88 164 STACK_OF(OPENSSL_STRING) *canames = NULL;
15c9aa3a 165 const EVP_CIPHER *enc = EVP_aes_256_cbc();
7e1b7485
RS
166 OPTION_CHOICE o;
167
168 prog = opt_init(argc, argv, pkcs12_options);
169 while ((o = opt_next()) != OPT_EOF) {
170 switch (o) {
171 case OPT_EOF:
172 case OPT_ERR:
173 opthelp:
174 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
175 goto end;
176 case OPT_HELP:
177 opt_help(pkcs12_options);
178 ret = 0;
179 goto end;
180 case OPT_NOKEYS:
181 options |= NOKEYS;
182 break;
183 case OPT_KEYEX:
184 keytype = KEY_EX;
185 break;
186 case OPT_KEYSIG:
187 keytype = KEY_SIG;
188 break;
189 case OPT_NOCERTS:
190 options |= NOCERTS;
191 break;
192 case OPT_CLCERTS:
193 options |= CLCERTS;
194 break;
195 case OPT_CACERTS:
196 options |= CACERTS;
197 break;
198 case OPT_NOOUT:
199 options |= (NOKEYS | NOCERTS);
200 break;
201 case OPT_INFO:
202 options |= INFO;
203 break;
204 case OPT_CHAIN:
205 chain = 1;
206 break;
207 case OPT_TWOPASS:
208 twopass = 1;
209 break;
210 case OPT_NOMACVER:
211 macver = 0;
212 break;
213 case OPT_DESCERT:
214 cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
215 break;
216 case OPT_EXPORT:
217 export_cert = 1;
218 break;
219 case OPT_CIPHER:
220 if (!opt_cipher(opt_unknown(), &enc))
221 goto opthelp;
222 break;
1fdde917
IG
223 case OPT_ITER:
224 if (!opt_int(opt_arg(), &iter))
225 goto opthelp;
226 maciter = iter;
227 break;
7e1b7485
RS
228 case OPT_NOITER:
229 iter = 1;
230 break;
231 case OPT_MACITER:
1fdde917 232 /* no-op */
7e1b7485
RS
233 break;
234 case OPT_NOMACITER:
235 maciter = 1;
236 break;
237 case OPT_NOMAC:
238 maciter = -1;
239 break;
240 case OPT_MACALG:
241 macalg = opt_arg();
242 break;
243 case OPT_NODES:
ef898017 244 case OPT_NOENC:
7e1b7485
RS
245 enc = NULL;
246 break;
247 case OPT_CERTPBE:
248 if (!set_pbe(&cert_pbe, opt_arg()))
249 goto opthelp;
250 break;
251 case OPT_KEYPBE:
252 if (!set_pbe(&key_pbe, opt_arg()))
253 goto opthelp;
254 break;
3ee1eac2
RS
255 case OPT_R_CASES:
256 if (!opt_rand(o))
257 goto end;
7e1b7485
RS
258 break;
259 case OPT_INKEY:
260 keyname = opt_arg();
261 break;
262 case OPT_CERTFILE:
263 certfile = opt_arg();
264 break;
1d6c8670
DDO
265 case OPT_UNTRUSTED:
266 untrusted = opt_arg();
267 break;
b3c5aadf
DDO
268 case OPT_PASSCERTS:
269 passcertsarg = opt_arg();
270 break;
7e1b7485
RS
271 case OPT_NAME:
272 name = opt_arg();
273 break;
274 case OPT_LMK:
275 add_lmk = 1;
276 break;
277 case OPT_CSP:
278 csp_name = opt_arg();
279 break;
280 case OPT_CANAME:
281 if (canames == NULL
282 && (canames = sk_OPENSSL_STRING_new_null()) == NULL)
283 goto end;
284 sk_OPENSSL_STRING_push(canames, opt_arg());
285 break;
286 case OPT_IN:
287 infile = opt_arg();
288 break;
289 case OPT_OUT:
290 outfile = opt_arg();
291 break;
292 case OPT_PASSIN:
293 passinarg = opt_arg();
294 break;
295 case OPT_PASSOUT:
296 passoutarg = opt_arg();
297 break;
298 case OPT_PASSWORD:
299 passarg = opt_arg();
300 break;
301 case OPT_CAPATH:
302 CApath = opt_arg();
303 break;
fd3397fc
RL
304 case OPT_CASTORE:
305 CAstore = opt_arg();
306 break;
7e1b7485
RS
307 case OPT_CAFILE:
308 CAfile = opt_arg();
309 break;
2b6bcb70
MC
310 case OPT_NOCAPATH:
311 noCApath = 1;
312 break;
fd3397fc
RL
313 case OPT_NOCASTORE:
314 noCAstore = 1;
315 break;
2b6bcb70
MC
316 case OPT_NOCAFILE:
317 noCAfile = 1;
318 break;
7e1b7485 319 case OPT_ENGINE:
333b070e 320 e = setup_engine(opt_arg(), 0);
7e1b7485 321 break;
15c9aa3a
SP
322 case OPT_LEGACY_ALG:
323 use_legacy = 1;
324 break;
6bd4e3f2
P
325 case OPT_PROV_CASES:
326 if (!opt_provider(o))
327 goto end;
328 break;
7e1b7485 329 }
ee0508d4 330 }
7e1b7485 331 argc = opt_num_rest();
15c9aa3a 332
1d6c8670
DDO
333 if (!export_cert) {
334 if (chain)
335 BIO_printf(bio_err, "Warning: -chain option ignored without -export\n");
336 if (certfile != NULL)
337 BIO_printf(bio_err, "Warning: -certfile option ignored without -export\n");
338 if (untrusted != NULL)
339 BIO_printf(bio_err, "Warning: -untrusted option ignored without -export\n");
340 if (passcertsarg != NULL)
341 BIO_printf(bio_err,
342 "Warning: -passcerts option ignored without -export\n");
343 if (CApath != NULL || noCApath)
344 BIO_printf(bio_err, "Warning: -[no-]CApath option ignored without -export\n");
345 if (CAfile != NULL || noCAfile)
346 BIO_printf(bio_err, "Warning: -[no-]CAfile option ignored without -export\n");
347 if (CAstore != NULL || noCAstore)
348 BIO_printf(bio_err, "Warning: -[no-]CAstore option ignored without -export\n");
349 if (add_lmk)
350 BIO_printf(bio_err, "Warning: -LMK option ignored without -export\n");
351 if (name != NULL)
352 BIO_printf(bio_err, "Warning: -name option ignored without -export\n");
353 if (csp_name != NULL)
354 BIO_printf(bio_err, "Warning: -CSP option ignored without -export\n");
355 if (canames != NULL)
356 BIO_printf(bio_err, "Warning: -caname option ignored without -export\n");
357 if (keyname != NULL)
358 BIO_printf(bio_err, "Warning: -inkey option ignored without -export\n");
359 if (keytype != 0)
360 BIO_printf(bio_err, "Warning: -keyex and -keysig options ignored without -export\n");
361 if (macalg != NULL)
362 BIO_printf(bio_err, "Warning: -macalg option ignored without -export\n");
363 }
15c9aa3a
SP
364 if (use_legacy) {
365 /* load the legacy provider if not loaded already*/
366 if (!OSSL_PROVIDER_available(app_get0_libctx(), "legacy")) {
367 if (!app_provider_load(app_get0_libctx(), "legacy"))
368 goto end;
369 /* load the default provider explicitly */
370 if (!app_provider_load(app_get0_libctx(), "default"))
371 goto end;
372 }
373 if (cert_pbe != NID_pbe_WithSHA1And3_Key_TripleDES_CBC) {
374 /* Restore default algorithms */
375#ifndef OPENSSL_NO_RC2
376 cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
377#else
378 cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
379#endif
380 }
381
382 key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
383 enc = EVP_des_ede3_cbc();
384 }
385
03358517
KR
386 if (argc != 0)
387 goto opthelp;
388
3b061a00 389 private = 1;
ee0508d4 390
b3c5aadf
DDO
391 if (!app_passwd(passcertsarg, NULL, &passcerts, NULL)) {
392 BIO_printf(bio_err, "Error getting certificate file password\n");
393 goto end;
394 }
395
2234212c 396 if (passarg != NULL) {
0f113f3e 397 if (export_cert)
7e1b7485 398 passoutarg = passarg;
0f113f3e 399 else
7e1b7485 400 passinarg = passarg;
a3fe382e
DSH
401 }
402
7e1b7485 403 if (!app_passwd(passinarg, passoutarg, &passin, &passout)) {
0f113f3e
MC
404 BIO_printf(bio_err, "Error getting passwords\n");
405 goto end;
a3fe382e
DSH
406 }
407
2234212c 408 if (cpass == NULL) {
0f113f3e
MC
409 if (export_cert)
410 cpass = passout;
411 else
412 cpass = passin;
f07fb9b2
DSH
413 }
414
2234212c 415 if (cpass != NULL) {
0f113f3e
MC
416 mpass = cpass;
417 noprompt = 1;
40b64553
MC
418 if (twopass) {
419 if (export_cert)
420 BIO_printf(bio_err, "Option -twopass cannot be used with -passout or -password\n");
421 else
422 BIO_printf(bio_err, "Option -twopass cannot be used with -passin or -password\n");
423 goto end;
424 }
f07fb9b2 425 } else {
0f113f3e
MC
426 cpass = pass;
427 mpass = macpass;
e40b7abe
DSH
428 }
429
ee0508d4 430 if (twopass) {
2234212c 431 /* To avoid bit rot */
923b1857 432 if (1) {
48feaceb 433#ifndef OPENSSL_NO_UI_CONSOLE
cbe29648
RS
434 if (EVP_read_pw_string(
435 macpass, sizeof(macpass), "Enter MAC Password:", export_cert)) {
923b1857
RL
436 BIO_printf(bio_err, "Can't read Password\n");
437 goto end;
438 }
439 } else {
440#endif
441 BIO_printf(bio_err, "Unsupported option -twopass\n");
0f113f3e
MC
442 goto end;
443 }
ee0508d4
DSH
444 }
445
2d681b77 446 if (export_cert) {
0f113f3e 447 EVP_PKEY *key = NULL;
1d6c8670 448 X509 *ee_cert = NULL, *x = NULL;
0f113f3e 449 STACK_OF(X509) *certs = NULL;
1d6c8670 450 STACK_OF(X509) *untrusted_certs = NULL;
0f113f3e
MC
451 const EVP_MD *macmd = NULL;
452 unsigned char *catmp = NULL;
453 int i;
454
455 if ((options & (NOCERTS | NOKEYS)) == (NOCERTS | NOKEYS)) {
1d6c8670 456 BIO_printf(bio_err, "Nothing to export due to -nocerts and -nokeys or -noout!\n");
0f113f3e
MC
457 goto export_end;
458 }
459
1d6c8670 460 if ((options & NOCERTS) != 0) {
0f113f3e 461 chain = 0;
1d6c8670
DDO
462 BIO_printf(bio_err, "Warning: -chain option ignored with -nocerts\n");
463 }
0f113f3e 464
0f113f3e 465 if (!(options & NOKEYS)) {
7e1b7485 466 key = load_key(keyname ? keyname : infile,
1d6c8670
DDO
467 FORMAT_PEM, 1, passin, e,
468 keyname ?
469 "private key from -inkey file" :
470 "private key from -in file");
2234212c 471 if (key == NULL)
0f113f3e
MC
472 goto export_end;
473 }
0f113f3e 474
1d6c8670 475 /* Load all certs in input file */
0f113f3e 476 if (!(options & NOCERTS)) {
1d6c8670
DDO
477 if (!load_certs(infile, &certs, passin,
478 "certificates from -in file"))
0f113f3e 479 goto export_end;
1d6c8670
DDO
480 if (sk_X509_num(certs) < 1) {
481 BIO_printf(bio_err, "No certificate in -in file %s\n", infile);
482 goto export_end;
483 }
0f113f3e 484
2234212c 485 if (key != NULL) {
0f113f3e
MC
486 /* Look for matching private key */
487 for (i = 0; i < sk_X509_num(certs); i++) {
488 x = sk_X509_value(certs, i);
489 if (X509_check_private_key(x, key)) {
1d6c8670 490 ee_cert = x;
0f113f3e 491 /* Zero keyid and alias */
1d6c8670
DDO
492 X509_keyid_set1(ee_cert, NULL, 0);
493 X509_alias_set1(ee_cert, NULL, 0);
0f113f3e
MC
494 /* Remove from list */
495 (void)sk_X509_delete(certs, i);
496 break;
497 }
498 }
1d6c8670 499 if (ee_cert == NULL) {
0f113f3e 500 BIO_printf(bio_err,
1d6c8670
DDO
501 "No cert in -in file '%s' matches private key\n",
502 infile);
0f113f3e
MC
503 goto export_end;
504 }
1d6c8670
DDO
505 } else {
506 ee_cert = X509_dup(sk_X509_value(certs, 0)); /* take 1st cert */
0f113f3e 507 }
0f113f3e 508 }
0f113f3e 509
1d6c8670
DDO
510 /* Load any untrusted certificates for chain building */
511 if (untrusted != NULL) {
512 if (!load_certs(untrusted, &untrusted_certs, passcerts,
513 "untrusted certificates"))
0f113f3e 514 goto export_end;
0f113f3e 515 }
0f113f3e 516
1d6c8670 517 /* If chaining get chain from end entity cert */
0f113f3e
MC
518 if (chain) {
519 int vret;
520 STACK_OF(X509) *chain2;
7e1b7485 521 X509_STORE *store;
1d6c8670
DDO
522
523 if (ee_cert == NULL) {
524 BIO_printf(bio_err,
525 "No end entity certificate to check with -chain\n");
526 goto export_end;
527 }
528
fd3397fc
RL
529 if ((store = setup_verify(CAfile, noCAfile, CApath, noCApath,
530 CAstore, noCAstore))
2b6bcb70 531 == NULL)
0f113f3e 532 goto export_end;
0f113f3e 533
1d6c8670 534 vret = get_cert_chain(ee_cert, store, untrusted_certs, &chain2);
0f113f3e
MC
535 X509_STORE_free(store);
536
e29c73c9 537 if (vret == X509_V_OK) {
5e8cd0a4 538 int add_certs;
1d6c8670
DDO
539 /* Remove from chain2 the first (end entity) certificate */
540 X509_free(sk_X509_shift(chain2));
541 /* Add the remaining certs (except for duplicates) */
5e8cd0a4
SL
542 add_certs = X509_add_certs(certs, chain2, X509_ADD_FLAG_UP_REF
543 | X509_ADD_FLAG_NO_DUP);
1d6c8670 544 sk_X509_pop_free(chain2, X509_free);
5e8cd0a4
SL
545 if (!add_certs)
546 goto export_end;
0f113f3e 547 } else {
e29c73c9 548 if (vret != X509_V_ERR_UNSPECIFIED)
1d6c8670 549 BIO_printf(bio_err, "Error getting chain: %s\n",
0f113f3e 550 X509_verify_cert_error_string(vret));
0f113f3e
MC
551 goto export_end;
552 }
553 }
554
1d6c8670
DDO
555 /* Add any extra certificates asked for */
556 if (certfile != NULL) {
557 if (!load_certs(certfile, &certs, passcerts,
558 "extra certificates from -certfile"))
559 goto export_end;
560 }
0f113f3e 561
1d6c8670 562 /* Add any CA names */
0f113f3e
MC
563 for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++) {
564 catmp = (unsigned char *)sk_OPENSSL_STRING_value(canames, i);
565 X509_alias_set1(sk_X509_value(certs, i), catmp, -1);
566 }
567
2234212c 568 if (csp_name != NULL && key != NULL)
0f113f3e
MC
569 EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name,
570 MBSTRING_ASC, (unsigned char *)csp_name,
571 -1);
572
2234212c 573 if (add_lmk && key != NULL)
0f113f3e
MC
574 EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1);
575
923b1857 576 if (!noprompt) {
2234212c 577 /* To avoid bit rot */
923b1857 578 if (1) {
48feaceb 579#ifndef OPENSSL_NO_UI_CONSOLE
cbe29648
RS
580 if (EVP_read_pw_string(pass, sizeof(pass),
581 "Enter Export Password:", 1)) {
923b1857
RL
582 BIO_printf(bio_err, "Can't read Password\n");
583 goto export_end;
584 }
585 } else {
586#endif
587 BIO_printf(bio_err, "Password required\n");
588 goto export_end;
589 }
0f113f3e 590 }
923b1857 591
0f113f3e 592 if (!twopass)
eee95522 593 OPENSSL_strlcpy(macpass, pass, sizeof(macpass));
0f113f3e 594
1d6c8670 595 p12 = PKCS12_create(cpass, name, key, ee_cert, certs,
0f113f3e
MC
596 key_pbe, cert_pbe, iter, -1, keytype);
597
12a765a5 598 if (p12 == NULL) {
0f113f3e
MC
599 ERR_print_errors(bio_err);
600 goto export_end;
601 }
602
1d6c8670 603 if (macalg != NULL) {
7e1b7485
RS
604 if (!opt_md(macalg, &macmd))
605 goto opthelp;
0f113f3e
MC
606 }
607
608 if (maciter != -1)
609 PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd);
610
3b061a00 611 assert(private);
bdd58d98
RL
612
613 out = bio_open_owner(outfile, FORMAT_PKCS12, private);
614 if (out == NULL)
615 goto end;
616
0f113f3e
MC
617 i2d_PKCS12_bio(out, p12);
618
619 ret = 0;
620
621 export_end:
0f113f3e 622
c5ba2d99 623 EVP_PKEY_free(key);
222561fe 624 sk_X509_pop_free(certs, X509_free);
1d6c8670
DDO
625 sk_X509_pop_free(untrusted_certs, X509_free);
626 X509_free(ee_cert);
0f113f3e 627
0f113f3e 628 goto end;
ee0508d4 629
ee86c3f5 630 }
ee0508d4 631
bdd58d98
RL
632 in = bio_open_default(infile, 'r', FORMAT_PKCS12);
633 if (in == NULL)
634 goto end;
635 out = bio_open_owner(outfile, FORMAT_PEM, private);
636 if (out == NULL)
637 goto end;
638
75ebbd9a 639 if ((p12 = d2i_PKCS12_bio(in, NULL)) == NULL) {
0f113f3e
MC
640 ERR_print_errors(bio_err);
641 goto end;
ee0508d4 642 }
7e1b7485 643
923b1857
RL
644 if (!noprompt) {
645 if (1) {
48feaceb 646#ifndef OPENSSL_NO_UI_CONSOLE
cbe29648 647 if (EVP_read_pw_string(pass, sizeof(pass), "Enter Import Password:",
923b1857
RL
648 0)) {
649 BIO_printf(bio_err, "Can't read Password\n");
650 goto end;
651 }
652 } else {
653#endif
654 BIO_printf(bio_err, "Password required\n");
655 goto end;
656 }
ee0508d4 657 }
0f113f3e
MC
658
659 if (!twopass)
cbe29648 660 OPENSSL_strlcpy(macpass, pass, sizeof(macpass));
0f113f3e 661
776cfa9b 662 if ((options & INFO) && PKCS12_mac_present(p12)) {
59b4da05
DSH
663 const ASN1_INTEGER *tmaciter;
664 const X509_ALGOR *macalgid;
ac4e2577 665 const ASN1_OBJECT *macobj;
11a25d34
HK
666 const ASN1_OCTET_STRING *tmac;
667 const ASN1_OCTET_STRING *tsalt;
668
669 PKCS12_get0_mac(&tmac, &macalgid, &tsalt, &tmaciter, p12);
670 /* current hash algorithms do not use parameters so extract just name,
671 in future alg_print() may be needed */
44c248b5 672 X509_ALGOR_get0(&macobj, NULL, NULL, macalgid);
7eb370ee 673 BIO_puts(bio_err, "MAC: ");
44c248b5 674 i2a_ASN1_OBJECT(bio_err, macobj);
7eb370ee 675 BIO_printf(bio_err, ", Iteration %ld\n",
11a25d34
HK
676 tmaciter != NULL ? ASN1_INTEGER_get(tmaciter) : 1L);
677 BIO_printf(bio_err, "MAC length: %ld, salt length: %ld\n",
678 tmac != NULL ? ASN1_STRING_length(tmac) : 0L,
679 tsalt != NULL ? ASN1_STRING_length(tsalt) : 0L);
776cfa9b 680 }
0f113f3e 681 if (macver) {
0f113f3e
MC
682 /* If we enter empty password try no password first */
683 if (!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) {
684 /* If mac and crypto pass the same set it to NULL too */
685 if (!twopass)
686 cpass = NULL;
687 } else if (!PKCS12_verify_mac(p12, mpass, -1)) {
647ac8d3
DSH
688 /*
689 * May be UTF8 from previous version of OpenSSL:
690 * convert to a UTF8 form which will translate
691 * to the same Unicode password.
692 */
693 unsigned char *utmp;
694 int utmplen;
695 utmp = OPENSSL_asc2uni(mpass, -1, NULL, &utmplen);
696 if (utmp == NULL)
697 goto end;
698 badpass = OPENSSL_uni2utf8(utmp, utmplen);
699 OPENSSL_free(utmp);
700 if (!PKCS12_verify_mac(p12, badpass, -1)) {
701 BIO_printf(bio_err, "Mac verify error: invalid password?\n");
702 ERR_print_errors(bio_err);
703 goto end;
704 } else {
705 BIO_printf(bio_err, "Warning: using broken algorithm\n");
706 if (!twopass)
707 cpass = badpass;
708 }
0f113f3e 709 }
ee0508d4 710 }
7e1b7485 711
3b061a00 712 assert(private);
7e1b7485 713 if (!dump_certs_keys_p12(out, p12, cpass, -1, options, passout, enc)) {
0f113f3e
MC
714 BIO_printf(bio_err, "Error outputting keys and certificates\n");
715 ERR_print_errors(bio_err);
716 goto end;
ee0508d4 717 }
ee0508d4 718 ret = 0;
88364bc2 719 end:
e0e920b1 720 PKCS12_free(p12);
dd1abd44 721 release_engine(e);
a873356c 722 BIO_free(in);
645749ef 723 BIO_free_all(out);
25aaa98a 724 sk_OPENSSL_STRING_free(canames);
647ac8d3 725 OPENSSL_free(badpass);
b3c5aadf 726 OPENSSL_free(passcerts);
b548a1f1
RS
727 OPENSSL_free(passin);
728 OPENSSL_free(passout);
eee95522 729 return ret;
ee0508d4
DSH
730}
731
28da1455 732int dump_certs_keys_p12(BIO *out, const PKCS12 *p12, const char *pass,
7e1b7485
RS
733 int passlen, int options, char *pempass,
734 const EVP_CIPHER *enc)
ee0508d4 735{
0f113f3e
MC
736 STACK_OF(PKCS7) *asafes = NULL;
737 STACK_OF(PKCS12_SAFEBAG) *bags;
738 int i, bagnid;
739 int ret = 0;
740 PKCS7 *p7;
741
75ebbd9a 742 if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL)
0f113f3e
MC
743 return 0;
744 for (i = 0; i < sk_PKCS7_num(asafes); i++) {
745 p7 = sk_PKCS7_value(asafes, i);
746 bagnid = OBJ_obj2nid(p7->type);
747 if (bagnid == NID_pkcs7_data) {
748 bags = PKCS12_unpack_p7data(p7);
749 if (options & INFO)
750 BIO_printf(bio_err, "PKCS7 Data\n");
751 } else if (bagnid == NID_pkcs7_encrypted) {
752 if (options & INFO) {
753 BIO_printf(bio_err, "PKCS7 Encrypted data: ");
ecf3a1fb 754 alg_print(p7->d.encrypted->enc_data->algorithm);
0f113f3e
MC
755 }
756 bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
2234212c 757 } else {
0f113f3e 758 continue;
2234212c 759 }
0f113f3e
MC
760 if (!bags)
761 goto err;
762 if (!dump_certs_pkeys_bags(out, bags, pass, passlen,
7e1b7485 763 options, pempass, enc)) {
0f113f3e
MC
764 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
765 goto err;
766 }
767 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
768 bags = NULL;
769 }
770 ret = 1;
771
772 err:
e0e920b1 773 sk_PKCS7_pop_free(asafes, PKCS7_free);
0f113f3e 774 return ret;
ee0508d4
DSH
775}
776
28da1455
MC
777int dump_certs_pkeys_bags(BIO *out, const STACK_OF(PKCS12_SAFEBAG) *bags,
778 const char *pass, int passlen, int options,
779 char *pempass, const EVP_CIPHER *enc)
ee0508d4 780{
0f113f3e
MC
781 int i;
782 for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
783 if (!dump_certs_pkeys_bag(out,
784 sk_PKCS12_SAFEBAG_value(bags, i),
7e1b7485 785 pass, passlen, options, pempass, enc))
0f113f3e
MC
786 return 0;
787 }
788 return 1;
ee0508d4
DSH
789}
790
28da1455
MC
791int dump_certs_pkeys_bag(BIO *out, const PKCS12_SAFEBAG *bag,
792 const char *pass, int passlen, int options,
793 char *pempass, const EVP_CIPHER *enc)
ee0508d4 794{
0f113f3e
MC
795 EVP_PKEY *pkey;
796 PKCS8_PRIV_KEY_INFO *p8;
28da1455 797 const PKCS8_PRIV_KEY_INFO *p8c;
0f113f3e 798 X509 *x509;
28da1455 799 const STACK_OF(X509_ATTRIBUTE) *attrs;
c73aa309 800 int ret = 0;
776cfa9b
DSH
801
802 attrs = PKCS12_SAFEBAG_get0_attrs(bag);
0f113f3e 803
762ee38d 804 switch (PKCS12_SAFEBAG_get_nid(bag)) {
0f113f3e
MC
805 case NID_keyBag:
806 if (options & INFO)
807 BIO_printf(bio_err, "Key bag\n");
808 if (options & NOKEYS)
809 return 1;
776cfa9b 810 print_attribs(out, attrs, "Bag Attributes");
28da1455
MC
811 p8c = PKCS12_SAFEBAG_get0_p8inf(bag);
812 if ((pkey = EVP_PKCS82PKEY(p8c)) == NULL)
0f113f3e 813 return 0;
28da1455 814 print_attribs(out, PKCS8_pkey_get0_attrs(p8c), "Key Attributes");
c73aa309 815 ret = PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass);
0f113f3e
MC
816 EVP_PKEY_free(pkey);
817 break;
818
819 case NID_pkcs8ShroudedKeyBag:
820 if (options & INFO) {
59b4da05
DSH
821 const X509_SIG *tp8;
822 const X509_ALGOR *tp8alg;
c9018bdf 823
0f113f3e 824 BIO_printf(bio_err, "Shrouded Keybag: ");
776cfa9b 825 tp8 = PKCS12_SAFEBAG_get0_pkcs8(bag);
59b4da05 826 X509_SIG_get0(tp8, &tp8alg, NULL);
a6eb1ce6 827 alg_print(tp8alg);
0f113f3e
MC
828 }
829 if (options & NOKEYS)
830 return 1;
776cfa9b 831 print_attribs(out, attrs, "Bag Attributes");
75ebbd9a 832 if ((p8 = PKCS12_decrypt_skey(bag, pass, passlen)) == NULL)
0f113f3e 833 return 0;
75ebbd9a 834 if ((pkey = EVP_PKCS82PKEY(p8)) == NULL) {
0f113f3e
MC
835 PKCS8_PRIV_KEY_INFO_free(p8);
836 return 0;
837 }
54dbf423 838 print_attribs(out, PKCS8_pkey_get0_attrs(p8), "Key Attributes");
0f113f3e 839 PKCS8_PRIV_KEY_INFO_free(p8);
c73aa309 840 ret = PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass);
0f113f3e
MC
841 EVP_PKEY_free(pkey);
842 break;
843
844 case NID_certBag:
845 if (options & INFO)
846 BIO_printf(bio_err, "Certificate bag\n");
847 if (options & NOCERTS)
848 return 1;
762ee38d 849 if (PKCS12_SAFEBAG_get0_attr(bag, NID_localKeyID)) {
0f113f3e
MC
850 if (options & CACERTS)
851 return 1;
852 } else if (options & CLCERTS)
853 return 1;
776cfa9b 854 print_attribs(out, attrs, "Bag Attributes");
762ee38d 855 if (PKCS12_SAFEBAG_get_bag_nid(bag) != NID_x509Certificate)
0f113f3e 856 return 1;
762ee38d 857 if ((x509 = PKCS12_SAFEBAG_get1_cert(bag)) == NULL)
0f113f3e
MC
858 return 0;
859 dump_cert_text(out, x509);
c73aa309 860 ret = PEM_write_bio_X509(out, x509);
0f113f3e
MC
861 X509_free(x509);
862 break;
863
c5ec6dcf
JS
864 case NID_secretBag:
865 if (options & INFO)
866 BIO_printf(bio_err, "Secret bag\n");
867 print_attribs(out, attrs, "Bag Attributes");
868 BIO_printf(bio_err, "Bag Type: ");
869 i2a_ASN1_OBJECT(bio_err, PKCS12_SAFEBAG_get0_bag_type(bag));
870 BIO_printf(bio_err, "\nBag Value: ");
871 print_attribute(out, PKCS12_SAFEBAG_get0_bag_obj(bag));
872 return 1;
873
0f113f3e
MC
874 case NID_safeContentsBag:
875 if (options & INFO)
876 BIO_printf(bio_err, "Safe Contents bag\n");
776cfa9b
DSH
877 print_attribs(out, attrs, "Bag Attributes");
878 return dump_certs_pkeys_bags(out, PKCS12_SAFEBAG_get0_safes(bag),
879 pass, passlen, options, pempass, enc);
0f113f3e
MC
880
881 default:
882 BIO_printf(bio_err, "Warning unsupported bag type: ");
776cfa9b 883 i2a_ASN1_OBJECT(bio_err, PKCS12_SAFEBAG_get0_type(bag));
0f113f3e
MC
884 BIO_printf(bio_err, "\n");
885 return 1;
0f113f3e 886 }
c73aa309 887 return ret;
ee0508d4
DSH
888}
889
890/* Given a single certificate return a verified chain or NULL if error */
891
e29c73c9 892static int get_cert_chain(X509 *cert, X509_STORE *store,
1d6c8670 893 STACK_OF(X509) *untrusted_certs,
e29c73c9 894 STACK_OF(X509) **chain)
ee0508d4 895{
f0e0fd51 896 X509_STORE_CTX *store_ctx = NULL;
e29c73c9 897 STACK_OF(X509) *chn = NULL;
0f113f3e
MC
898 int i = 0;
899
d8652be0 900 store_ctx = X509_STORE_CTX_new_ex(app_get0_libctx(), app_get0_propq());
f0e0fd51
RS
901 if (store_ctx == NULL) {
902 i = X509_V_ERR_UNSPECIFIED;
903 goto end;
904 }
1d6c8670 905 if (!X509_STORE_CTX_init(store_ctx, store, cert, untrusted_certs)) {
f0e0fd51
RS
906 i = X509_V_ERR_UNSPECIFIED;
907 goto end;
e29c73c9
VD
908 }
909
f0e0fd51
RS
910
911 if (X509_verify_cert(store_ctx) > 0)
912 chn = X509_STORE_CTX_get1_chain(store_ctx);
913 else if ((i = X509_STORE_CTX_get_error(store_ctx)) == 0)
e29c73c9
VD
914 i = X509_V_ERR_UNSPECIFIED;
915
f0e0fd51
RS
916end:
917 X509_STORE_CTX_free(store_ctx);
0f113f3e 918 *chain = chn;
0f113f3e
MC
919 return i;
920}
921
59b4da05 922static int alg_print(const X509_ALGOR *alg)
ee0508d4 923{
ab6a591c 924 int pbenid, aparamtype;
ac4e2577
DSH
925 const ASN1_OBJECT *aoid;
926 const void *aparam;
ab6a591c
DSH
927 PBEPARAM *pbe = NULL;
928
929 X509_ALGOR_get0(&aoid, &aparamtype, &aparam, alg);
930
931 pbenid = OBJ_obj2nid(aoid);
932
933 BIO_printf(bio_err, "%s", OBJ_nid2ln(pbenid));
934
935 /*
936 * If PBE algorithm is PBES2 decode algorithm parameters
937 * for additional details.
938 */
939 if (pbenid == NID_pbes2) {
940 PBE2PARAM *pbe2 = NULL;
941 int encnid;
942 if (aparamtype == V_ASN1_SEQUENCE)
943 pbe2 = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(PBE2PARAM));
944 if (pbe2 == NULL) {
dc46fc25 945 BIO_puts(bio_err, ", <unsupported parameters>");
ab6a591c
DSH
946 goto done;
947 }
948 X509_ALGOR_get0(&aoid, &aparamtype, &aparam, pbe2->keyfunc);
949 pbenid = OBJ_obj2nid(aoid);
950 X509_ALGOR_get0(&aoid, NULL, NULL, pbe2->encryption);
951 encnid = OBJ_obj2nid(aoid);
952 BIO_printf(bio_err, ", %s, %s", OBJ_nid2ln(pbenid),
953 OBJ_nid2sn(encnid));
954 /* If KDF is PBKDF2 decode parameters */
955 if (pbenid == NID_id_pbkdf2) {
956 PBKDF2PARAM *kdf = NULL;
957 int prfnid;
958 if (aparamtype == V_ASN1_SEQUENCE)
959 kdf = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(PBKDF2PARAM));
960 if (kdf == NULL) {
dc46fc25 961 BIO_puts(bio_err, ", <unsupported parameters>");
ab6a591c
DSH
962 goto done;
963 }
ecf3a1fb 964
ab6a591c
DSH
965 if (kdf->prf == NULL) {
966 prfnid = NID_hmacWithSHA1;
967 } else {
968 X509_ALGOR_get0(&aoid, NULL, NULL, kdf->prf);
969 prfnid = OBJ_obj2nid(aoid);
970 }
971 BIO_printf(bio_err, ", Iteration %ld, PRF %s",
972 ASN1_INTEGER_get(kdf->iter), OBJ_nid2sn(prfnid));
973 PBKDF2PARAM_free(kdf);
402f26e6 974#ifndef OPENSSL_NO_SCRYPT
75f163d3
HK
975 } else if (pbenid == NID_id_scrypt) {
976 SCRYPT_PARAMS *kdf = NULL;
977
978 if (aparamtype == V_ASN1_SEQUENCE)
979 kdf = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(SCRYPT_PARAMS));
980 if (kdf == NULL) {
981 BIO_puts(bio_err, ", <unsupported parameters>");
982 goto done;
983 }
984 BIO_printf(bio_err, ", Salt length: %d, Cost(N): %ld, "
c2969ff6 985 "Block size(r): %ld, Parallelism(p): %ld",
75f163d3
HK
986 ASN1_STRING_length(kdf->salt),
987 ASN1_INTEGER_get(kdf->costParameter),
988 ASN1_INTEGER_get(kdf->blockSize),
989 ASN1_INTEGER_get(kdf->parallelizationParameter));
990 SCRYPT_PARAMS_free(kdf);
402f26e6 991#endif
ab6a591c
DSH
992 }
993 PBE2PARAM_free(pbe2);
994 } else {
995 if (aparamtype == V_ASN1_SEQUENCE)
996 pbe = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(PBEPARAM));
997 if (pbe == NULL) {
dc46fc25 998 BIO_puts(bio_err, ", <unsupported parameters>");
ab6a591c
DSH
999 goto done;
1000 }
1001 BIO_printf(bio_err, ", Iteration %ld", ASN1_INTEGER_get(pbe->iter));
1002 PBEPARAM_free(pbe);
1003 }
1004 done:
1005 BIO_puts(bio_err, "\n");
0f113f3e 1006 return 1;
ee0508d4
DSH
1007}
1008
1009/* Load all certificates from a given file */
1010
84c15db5 1011int cert_load(BIO *in, STACK_OF(X509) *sk)
ee0508d4 1012{
d5e66eab 1013 int ret = 0;
0f113f3e 1014 X509 *cert;
d5e66eab 1015
0f113f3e 1016 while ((cert = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
0f113f3e 1017 ret = 1;
d5e66eab
SL
1018 if (!sk_X509_push(sk, cert))
1019 return 0;
0f113f3e 1020 }
0f113f3e
MC
1021 if (ret)
1022 ERR_clear_error();
1023 return ret;
ee0508d4
DSH
1024}
1025
dbcc7b45
JS
1026/* Generalised x509 attribute value print */
1027
1028void print_attribute(BIO *out, const ASN1_TYPE *av)
1029{
1030 char *value;
1031
1032 switch (av->type) {
1033 case V_ASN1_BMPSTRING:
1034 value = OPENSSL_uni2asc(av->value.bmpstring->data,
1035 av->value.bmpstring->length);
1036 BIO_printf(out, "%s\n", value);
1037 OPENSSL_free(value);
1038 break;
1039
c5ec6dcf
JS
1040 case V_ASN1_UTF8STRING:
1041 BIO_printf(out, "%s\n", av->value.utf8string->data);
1042 break;
1043
dbcc7b45
JS
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", av->type);
1058 break;
1059 }
1060}
1061
ee0508d4
DSH
1062/* Generalised attribute print: handle PKCS#8 and bag attributes */
1063
b2e57e09 1064int print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst,
0f113f3e 1065 const char *name)
ee0508d4 1066{
0f113f3e
MC
1067 X509_ATTRIBUTE *attr;
1068 ASN1_TYPE *av;
dbcc7b45 1069 int i, j, attr_nid;
0f113f3e
MC
1070 if (!attrlst) {
1071 BIO_printf(out, "%s: <No Attributes>\n", name);
1072 return 1;
1073 }
1074 if (!sk_X509_ATTRIBUTE_num(attrlst)) {
1075 BIO_printf(out, "%s: <Empty Attributes>\n", name);
1076 return 1;
1077 }
1078 BIO_printf(out, "%s\n", name);
1079 for (i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) {
9b0a4531 1080 ASN1_OBJECT *attr_obj;
0f113f3e 1081 attr = sk_X509_ATTRIBUTE_value(attrlst, i);
9b0a4531
DSH
1082 attr_obj = X509_ATTRIBUTE_get0_object(attr);
1083 attr_nid = OBJ_obj2nid(attr_obj);
0f113f3e
MC
1084 BIO_printf(out, " ");
1085 if (attr_nid == NID_undef) {
9b0a4531 1086 i2a_ASN1_OBJECT(out, attr_obj);
0f113f3e 1087 BIO_printf(out, ": ");
2234212c 1088 } else {
0f113f3e 1089 BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid));
2234212c 1090 }
0f113f3e 1091
9b0a4531 1092 if (X509_ATTRIBUTE_count(attr)) {
dbcc7b45
JS
1093 for (j = 0; j < X509_ATTRIBUTE_count(attr); j++)
1094 {
1095 av = X509_ATTRIBUTE_get0_type(attr, j);
1096 print_attribute(out, av);
0f113f3e 1097 }
2234212c 1098 } else {
0f113f3e 1099 BIO_printf(out, "<No Values>\n");
2234212c 1100 }
0f113f3e
MC
1101 }
1102 return 1;
ee0508d4
DSH
1103}
1104
6b691a5c 1105void hex_prin(BIO *out, unsigned char *buf, int len)
ee0508d4 1106{
0f113f3e
MC
1107 int i;
1108 for (i = 0; i < len; i++)
1109 BIO_printf(out, "%02X ", buf[i]);
ee0508d4 1110}
a8515441 1111
7e1b7485 1112static int set_pbe(int *ppbe, const char *str)
0f113f3e
MC
1113{
1114 if (!str)
1115 return 0;
86885c28 1116 if (strcmp(str, "NONE") == 0) {
0f113f3e
MC
1117 *ppbe = -1;
1118 return 1;
1119 }
1120 *ppbe = OBJ_txt2nid(str);
1121 if (*ppbe == NID_undef) {
1122 BIO_printf(bio_err, "Unknown PBE algorithm %s\n", str);
1123 return 0;
1124 }
1125 return 1;
1126}