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