pkcs12.c revision 312826
1/* pkcs12.c */
2/*
3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
4 * project.
5 */
6/* ====================================================================
7 * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in
18 *    the documentation and/or other materials provided with the
19 *    distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 *    software must display the following acknowledgment:
23 *    "This product includes software developed by the OpenSSL Project
24 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 *    endorse or promote products derived from this software without
28 *    prior written permission. For written permission, please contact
29 *    licensing@OpenSSL.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 *    nor may "OpenSSL" appear in their names without prior written
33 *    permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 *    acknowledgment:
37 *    "This product includes software developed by the OpenSSL Project
38 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com).  This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
57 *
58 */
59
60#include <openssl/opensslconf.h>
61#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)
62
63# include <stdio.h>
64# include <stdlib.h>
65# include <string.h>
66# include "apps.h"
67# include <openssl/crypto.h>
68# include <openssl/err.h>
69# include <openssl/pem.h>
70# include <openssl/pkcs12.h>
71
72# define PROG pkcs12_main
73
74const 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
82static int get_cert_chain(X509 *cert, X509_STORE *store,
83                          STACK_OF(X509) **chain);
84int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int passlen,
85                        int options, char *pempass);
86int dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags,
87                          char *pass, int passlen, int options,
88                          char *pempass);
89int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass,
90                         int passlen, int options, char *pempass);
91int print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,
92                  const char *name);
93void hex_prin(BIO *out, unsigned char *buf, int len);
94int alg_print(BIO *x, X509_ALGOR *alg);
95int cert_load(BIO *in, STACK_OF(X509) *sk);
96static int set_pbe(BIO *err, int *ppbe, const char *str);
97
98int MAIN(int, char **);
99
100int MAIN(int argc, char **argv)
101{
102    ENGINE *e = NULL;
103    char *infile = NULL, *outfile = NULL, *keyname = NULL;
104    char *certfile = NULL;
105    BIO *in = NULL, *out = NULL;
106    char **args;
107    char *name = NULL;
108    char *csp_name = NULL;
109    int add_lmk = 0;
110    PKCS12 *p12 = NULL;
111    char pass[50], macpass[50];
112    int export_cert = 0;
113    int options = 0;
114    int chain = 0;
115    int badarg = 0;
116    int iter = PKCS12_DEFAULT_ITER;
117    int maciter = PKCS12_DEFAULT_ITER;
118    int twopass = 0;
119    int keytype = 0;
120    int cert_pbe;
121    int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
122    int ret = 1;
123    int macver = 1;
124    int noprompt = 0;
125    STACK_OF(OPENSSL_STRING) *canames = NULL;
126    char *cpass = NULL, *mpass = NULL;
127    char *passargin = NULL, *passargout = NULL, *passarg = NULL;
128    char *passin = NULL, *passout = NULL;
129    char *inrand = NULL;
130    char *macalg = NULL;
131    char *CApath = NULL, *CAfile = NULL;
132    char *engine = NULL;
133
134    apps_startup();
135
136    enc = EVP_des_ede3_cbc();
137    if (bio_err == NULL)
138        bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
139
140    if (!load_config(bio_err, NULL))
141        goto end;
142
143# ifdef OPENSSL_FIPS
144    if (FIPS_mode())
145        cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
146    else
147# endif
148        cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
149
150    args = argv + 1;
151
152    while (*args) {
153        if (*args[0] == '-') {
154            if (!strcmp(*args, "-nokeys"))
155                options |= NOKEYS;
156            else if (!strcmp(*args, "-keyex"))
157                keytype = KEY_EX;
158            else if (!strcmp(*args, "-keysig"))
159                keytype = KEY_SIG;
160            else if (!strcmp(*args, "-nocerts"))
161                options |= NOCERTS;
162            else if (!strcmp(*args, "-clcerts"))
163                options |= CLCERTS;
164            else if (!strcmp(*args, "-cacerts"))
165                options |= CACERTS;
166            else if (!strcmp(*args, "-noout"))
167                options |= (NOKEYS | NOCERTS);
168            else if (!strcmp(*args, "-info"))
169                options |= INFO;
170            else if (!strcmp(*args, "-chain"))
171                chain = 1;
172            else if (!strcmp(*args, "-twopass"))
173                twopass = 1;
174            else if (!strcmp(*args, "-nomacver"))
175                macver = 0;
176            else if (!strcmp(*args, "-descert"))
177                cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
178            else if (!strcmp(*args, "-export"))
179                export_cert = 1;
180            else if (!strcmp(*args, "-des"))
181                enc = EVP_des_cbc();
182            else if (!strcmp(*args, "-des3"))
183                enc = EVP_des_ede3_cbc();
184# ifndef OPENSSL_NO_IDEA
185            else if (!strcmp(*args, "-idea"))
186                enc = EVP_idea_cbc();
187# endif
188# ifndef OPENSSL_NO_SEED
189            else if (!strcmp(*args, "-seed"))
190                enc = EVP_seed_cbc();
191# endif
192# ifndef OPENSSL_NO_AES
193            else if (!strcmp(*args, "-aes128"))
194                enc = EVP_aes_128_cbc();
195            else if (!strcmp(*args, "-aes192"))
196                enc = EVP_aes_192_cbc();
197            else if (!strcmp(*args, "-aes256"))
198                enc = EVP_aes_256_cbc();
199# endif
200# ifndef OPENSSL_NO_CAMELLIA
201            else if (!strcmp(*args, "-camellia128"))
202                enc = EVP_camellia_128_cbc();
203            else if (!strcmp(*args, "-camellia192"))
204                enc = EVP_camellia_192_cbc();
205            else if (!strcmp(*args, "-camellia256"))
206                enc = EVP_camellia_256_cbc();
207# endif
208            else if (!strcmp(*args, "-noiter"))
209                iter = 1;
210            else if (!strcmp(*args, "-maciter"))
211                maciter = PKCS12_DEFAULT_ITER;
212            else if (!strcmp(*args, "-nomaciter"))
213                maciter = 1;
214            else if (!strcmp(*args, "-nomac"))
215                maciter = -1;
216            else if (!strcmp(*args, "-macalg"))
217                if (args[1]) {
218                    args++;
219                    macalg = *args;
220                } else
221                    badarg = 1;
222            else if (!strcmp(*args, "-nodes"))
223                enc = NULL;
224            else if (!strcmp(*args, "-certpbe")) {
225                if (!set_pbe(bio_err, &cert_pbe, *++args))
226                    badarg = 1;
227            } else if (!strcmp(*args, "-keypbe")) {
228                if (!set_pbe(bio_err, &key_pbe, *++args))
229                    badarg = 1;
230            } else if (!strcmp(*args, "-rand")) {
231                if (args[1]) {
232                    args++;
233                    inrand = *args;
234                } else
235                    badarg = 1;
236            } else if (!strcmp(*args, "-inkey")) {
237                if (args[1]) {
238                    args++;
239                    keyname = *args;
240                } else
241                    badarg = 1;
242            } else if (!strcmp(*args, "-certfile")) {
243                if (args[1]) {
244                    args++;
245                    certfile = *args;
246                } else
247                    badarg = 1;
248            } else if (!strcmp(*args, "-name")) {
249                if (args[1]) {
250                    args++;
251                    name = *args;
252                } else
253                    badarg = 1;
254            } else if (!strcmp(*args, "-LMK"))
255                add_lmk = 1;
256            else if (!strcmp(*args, "-CSP")) {
257                if (args[1]) {
258                    args++;
259                    csp_name = *args;
260                } else
261                    badarg = 1;
262            } else if (!strcmp(*args, "-caname")) {
263                if (args[1]) {
264                    args++;
265                    if (!canames)
266                        canames = sk_OPENSSL_STRING_new_null();
267                    sk_OPENSSL_STRING_push(canames, *args);
268                } else
269                    badarg = 1;
270            } else if (!strcmp(*args, "-in")) {
271                if (args[1]) {
272                    args++;
273                    infile = *args;
274                } else
275                    badarg = 1;
276            } else if (!strcmp(*args, "-out")) {
277                if (args[1]) {
278                    args++;
279                    outfile = *args;
280                } else
281                    badarg = 1;
282            } else if (!strcmp(*args, "-passin")) {
283                if (args[1]) {
284                    args++;
285                    passargin = *args;
286                } else
287                    badarg = 1;
288            } else if (!strcmp(*args, "-passout")) {
289                if (args[1]) {
290                    args++;
291                    passargout = *args;
292                } else
293                    badarg = 1;
294            } else if (!strcmp(*args, "-password")) {
295                if (args[1]) {
296                    args++;
297                    passarg = *args;
298                    noprompt = 1;
299                } else
300                    badarg = 1;
301            } else if (!strcmp(*args, "-CApath")) {
302                if (args[1]) {
303                    args++;
304                    CApath = *args;
305                } else
306                    badarg = 1;
307            } else if (!strcmp(*args, "-CAfile")) {
308                if (args[1]) {
309                    args++;
310                    CAfile = *args;
311                } else
312                    badarg = 1;
313# ifndef OPENSSL_NO_ENGINE
314            } else if (!strcmp(*args, "-engine")) {
315                if (args[1]) {
316                    args++;
317                    engine = *args;
318                } else
319                    badarg = 1;
320# endif
321            } else
322                badarg = 1;
323
324        } else
325            badarg = 1;
326        args++;
327    }
328
329    if (badarg) {
330        BIO_printf(bio_err, "Usage: pkcs12 [options]\n");
331        BIO_printf(bio_err, "where options are\n");
332        BIO_printf(bio_err, "-export       output PKCS12 file\n");
333        BIO_printf(bio_err, "-chain        add certificate chain\n");
334        BIO_printf(bio_err, "-inkey file   private key if not infile\n");
335        BIO_printf(bio_err, "-certfile f   add all certs in f\n");
336        BIO_printf(bio_err, "-CApath arg   - PEM format directory of CA's\n");
337        BIO_printf(bio_err, "-CAfile arg   - PEM format file of CA's\n");
338        BIO_printf(bio_err, "-name \"name\"  use name as friendly name\n");
339        BIO_printf(bio_err,
340                   "-caname \"nm\"  use nm as CA friendly name (can be used more than once).\n");
341        BIO_printf(bio_err, "-in  infile   input filename\n");
342        BIO_printf(bio_err, "-out outfile  output filename\n");
343        BIO_printf(bio_err,
344                   "-noout        don't output anything, just verify.\n");
345        BIO_printf(bio_err, "-nomacver     don't verify MAC.\n");
346        BIO_printf(bio_err, "-nocerts      don't output certificates.\n");
347        BIO_printf(bio_err,
348                   "-clcerts      only output client certificates.\n");
349        BIO_printf(bio_err, "-cacerts      only output CA certificates.\n");
350        BIO_printf(bio_err, "-nokeys       don't output private keys.\n");
351        BIO_printf(bio_err,
352                   "-info         give info about PKCS#12 structure.\n");
353        BIO_printf(bio_err, "-des          encrypt private keys with DES\n");
354        BIO_printf(bio_err,
355                   "-des3         encrypt private keys with triple DES (default)\n");
356# ifndef OPENSSL_NO_IDEA
357        BIO_printf(bio_err, "-idea         encrypt private keys with idea\n");
358# endif
359# ifndef OPENSSL_NO_SEED
360        BIO_printf(bio_err, "-seed         encrypt private keys with seed\n");
361# endif
362# ifndef OPENSSL_NO_AES
363        BIO_printf(bio_err, "-aes128, -aes192, -aes256\n");
364        BIO_printf(bio_err,
365                   "              encrypt PEM output with cbc aes\n");
366# endif
367# ifndef OPENSSL_NO_CAMELLIA
368        BIO_printf(bio_err, "-camellia128, -camellia192, -camellia256\n");
369        BIO_printf(bio_err,
370                   "              encrypt PEM output with cbc camellia\n");
371# endif
372        BIO_printf(bio_err, "-nodes        don't encrypt private keys\n");
373        BIO_printf(bio_err, "-noiter       don't use encryption iteration\n");
374        BIO_printf(bio_err, "-nomaciter    don't use MAC iteration\n");
375        BIO_printf(bio_err, "-maciter      use MAC iteration\n");
376        BIO_printf(bio_err, "-nomac        don't generate MAC\n");
377        BIO_printf(bio_err,
378                   "-twopass      separate MAC, encryption passwords\n");
379        BIO_printf(bio_err,
380                   "-descert      encrypt PKCS#12 certificates with triple DES (default RC2-40)\n");
381        BIO_printf(bio_err,
382                   "-certpbe alg  specify certificate PBE algorithm (default RC2-40)\n");
383        BIO_printf(bio_err,
384                   "-keypbe alg   specify private key PBE algorithm (default 3DES)\n");
385        BIO_printf(bio_err,
386                   "-macalg alg   digest algorithm used in MAC (default SHA1)\n");
387        BIO_printf(bio_err, "-keyex        set MS key exchange type\n");
388        BIO_printf(bio_err, "-keysig       set MS key signature type\n");
389        BIO_printf(bio_err,
390                   "-password p   set import/export password source\n");
391        BIO_printf(bio_err, "-passin p     input file pass phrase source\n");
392        BIO_printf(bio_err, "-passout p    output file pass phrase source\n");
393# ifndef OPENSSL_NO_ENGINE
394        BIO_printf(bio_err,
395                   "-engine e     use engine e, possibly a hardware device.\n");
396# endif
397        BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR,
398                   LIST_SEPARATOR_CHAR);
399        BIO_printf(bio_err,
400                   "              load the file (or the files in the directory) into\n");
401        BIO_printf(bio_err, "              the random number generator\n");
402        BIO_printf(bio_err, "-CSP name     Microsoft CSP name\n");
403        BIO_printf(bio_err,
404                   "-LMK          Add local machine keyset attribute to private key\n");
405        goto end;
406    }
407    e = setup_engine(bio_err, engine, 0);
408
409    if (passarg) {
410        if (export_cert)
411            passargout = passarg;
412        else
413            passargin = passarg;
414    }
415
416    if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
417        BIO_printf(bio_err, "Error getting passwords\n");
418        goto end;
419    }
420
421    if (!cpass) {
422        if (export_cert)
423            cpass = passout;
424        else
425            cpass = passin;
426    }
427
428    if (cpass) {
429        mpass = cpass;
430        noprompt = 1;
431    } else {
432        cpass = pass;
433        mpass = macpass;
434    }
435
436    if (export_cert || inrand) {
437        app_RAND_load_file(NULL, bio_err, (inrand != NULL));
438        if (inrand != NULL)
439            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
440                       app_RAND_load_files(inrand));
441    }
442    ERR_load_crypto_strings();
443
444# ifdef CRYPTO_MDEBUG
445    CRYPTO_push_info("read files");
446# endif
447
448    if (!infile)
449        in = BIO_new_fp(stdin, BIO_NOCLOSE);
450    else
451        in = BIO_new_file(infile, "rb");
452    if (!in) {
453        BIO_printf(bio_err, "Error opening input file %s\n",
454                   infile ? infile : "<stdin>");
455        perror(infile);
456        goto end;
457    }
458# ifdef CRYPTO_MDEBUG
459    CRYPTO_pop_info();
460    CRYPTO_push_info("write files");
461# endif
462
463    if (!outfile) {
464        out = BIO_new_fp(stdout, BIO_NOCLOSE);
465# ifdef OPENSSL_SYS_VMS
466        {
467            BIO *tmpbio = BIO_new(BIO_f_linebuffer());
468            out = BIO_push(tmpbio, out);
469        }
470# endif
471    } else
472        out = BIO_new_file(outfile, "wb");
473    if (!out) {
474        BIO_printf(bio_err, "Error opening output file %s\n",
475                   outfile ? outfile : "<stdout>");
476        perror(outfile);
477        goto end;
478    }
479    if (twopass) {
480# ifdef CRYPTO_MDEBUG
481        CRYPTO_push_info("read MAC password");
482# endif
483        if (EVP_read_pw_string
484            (macpass, sizeof macpass, "Enter MAC Password:", export_cert)) {
485            BIO_printf(bio_err, "Can't read Password\n");
486            goto end;
487        }
488# ifdef CRYPTO_MDEBUG
489        CRYPTO_pop_info();
490# endif
491    }
492
493    if (export_cert) {
494        EVP_PKEY *key = NULL;
495        X509 *ucert = NULL, *x = NULL;
496        STACK_OF(X509) *certs = NULL;
497        const EVP_MD *macmd = NULL;
498        unsigned char *catmp = NULL;
499        int i;
500
501        if ((options & (NOCERTS | NOKEYS)) == (NOCERTS | NOKEYS)) {
502            BIO_printf(bio_err, "Nothing to do!\n");
503            goto export_end;
504        }
505
506        if (options & NOCERTS)
507            chain = 0;
508
509# ifdef CRYPTO_MDEBUG
510        CRYPTO_push_info("process -export_cert");
511        CRYPTO_push_info("reading private key");
512# endif
513        if (!(options & NOKEYS)) {
514            key = load_key(bio_err, keyname ? keyname : infile,
515                           FORMAT_PEM, 1, passin, e, "private key");
516            if (!key)
517                goto export_end;
518        }
519# ifdef CRYPTO_MDEBUG
520        CRYPTO_pop_info();
521        CRYPTO_push_info("reading certs from input");
522# endif
523
524        /* Load in all certs in input file */
525        if (!(options & NOCERTS)) {
526            certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e,
527                               "certificates");
528            if (!certs)
529                goto export_end;
530
531            if (key) {
532                /* Look for matching private key */
533                for (i = 0; i < sk_X509_num(certs); i++) {
534                    x = sk_X509_value(certs, i);
535                    if (X509_check_private_key(x, key)) {
536                        ucert = x;
537                        /* Zero keyid and alias */
538                        X509_keyid_set1(ucert, NULL, 0);
539                        X509_alias_set1(ucert, NULL, 0);
540                        /* Remove from list */
541                        (void)sk_X509_delete(certs, i);
542                        break;
543                    }
544                }
545                if (!ucert) {
546                    BIO_printf(bio_err,
547                               "No certificate matches private key\n");
548                    goto export_end;
549                }
550            }
551
552        }
553# ifdef CRYPTO_MDEBUG
554        CRYPTO_pop_info();
555        CRYPTO_push_info("reading certs from input 2");
556# endif
557
558        /* Add any more certificates asked for */
559        if (certfile) {
560            STACK_OF(X509) *morecerts = NULL;
561            if (!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM,
562                                         NULL, e,
563                                         "certificates from certfile")))
564                goto export_end;
565            while (sk_X509_num(morecerts) > 0)
566                sk_X509_push(certs, sk_X509_shift(morecerts));
567            sk_X509_free(morecerts);
568        }
569# ifdef CRYPTO_MDEBUG
570        CRYPTO_pop_info();
571        CRYPTO_push_info("reading certs from certfile");
572# endif
573
574# ifdef CRYPTO_MDEBUG
575        CRYPTO_pop_info();
576        CRYPTO_push_info("building chain");
577# endif
578
579        /* If chaining get chain from user cert */
580        if (chain) {
581            int vret;
582            STACK_OF(X509) *chain2;
583            X509_STORE *store = X509_STORE_new();
584            if (!store) {
585                BIO_printf(bio_err, "Memory allocation error\n");
586                goto export_end;
587            }
588            if (!X509_STORE_load_locations(store, CAfile, CApath))
589                X509_STORE_set_default_paths(store);
590
591            vret = get_cert_chain(ucert, store, &chain2);
592            X509_STORE_free(store);
593
594            if (vret == X509_V_OK) {
595                /* Exclude verified certificate */
596                for (i = 1; i < sk_X509_num(chain2); i++)
597                    sk_X509_push(certs, sk_X509_value(chain2, i));
598                /* Free first certificate */
599                X509_free(sk_X509_value(chain2, 0));
600                sk_X509_free(chain2);
601            } else {
602                if (vret != X509_V_ERR_UNSPECIFIED)
603                    BIO_printf(bio_err, "Error %s getting chain.\n",
604                               X509_verify_cert_error_string(vret));
605                else
606                    ERR_print_errors(bio_err);
607                goto export_end;
608            }
609        }
610
611        /* Add any CA names */
612
613        for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++) {
614            catmp = (unsigned char *)sk_OPENSSL_STRING_value(canames, i);
615            X509_alias_set1(sk_X509_value(certs, i), catmp, -1);
616        }
617
618        if (csp_name && key)
619            EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name,
620                                      MBSTRING_ASC, (unsigned char *)csp_name,
621                                      -1);
622
623        if (add_lmk && key)
624            EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1);
625
626# ifdef CRYPTO_MDEBUG
627        CRYPTO_pop_info();
628        CRYPTO_push_info("reading password");
629# endif
630
631        if (!noprompt &&
632            EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:",
633                               1)) {
634            BIO_printf(bio_err, "Can't read Password\n");
635            goto export_end;
636        }
637        if (!twopass)
638            BUF_strlcpy(macpass, pass, sizeof macpass);
639
640# ifdef CRYPTO_MDEBUG
641        CRYPTO_pop_info();
642        CRYPTO_push_info("creating PKCS#12 structure");
643# endif
644
645        p12 = PKCS12_create(cpass, name, key, ucert, certs,
646                            key_pbe, cert_pbe, iter, -1, keytype);
647
648        if (!p12) {
649            ERR_print_errors(bio_err);
650            goto export_end;
651        }
652
653        if (macalg) {
654            macmd = EVP_get_digestbyname(macalg);
655            if (!macmd) {
656                BIO_printf(bio_err, "Unknown digest algorithm %s\n", macalg);
657            }
658        }
659
660        if (maciter != -1)
661            PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd);
662
663# ifdef CRYPTO_MDEBUG
664        CRYPTO_pop_info();
665        CRYPTO_push_info("writing pkcs12");
666# endif
667
668        i2d_PKCS12_bio(out, p12);
669
670        ret = 0;
671
672 export_end:
673# ifdef CRYPTO_MDEBUG
674        CRYPTO_pop_info();
675        CRYPTO_pop_info();
676        CRYPTO_push_info("process -export_cert: freeing");
677# endif
678
679        if (key)
680            EVP_PKEY_free(key);
681        if (certs)
682            sk_X509_pop_free(certs, X509_free);
683        if (ucert)
684            X509_free(ucert);
685
686# ifdef CRYPTO_MDEBUG
687        CRYPTO_pop_info();
688# endif
689        goto end;
690
691    }
692
693    if (!(p12 = d2i_PKCS12_bio(in, NULL))) {
694        ERR_print_errors(bio_err);
695        goto end;
696    }
697# ifdef CRYPTO_MDEBUG
698    CRYPTO_push_info("read import password");
699# endif
700    if (!noprompt
701        && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:",
702                              0)) {
703        BIO_printf(bio_err, "Can't read Password\n");
704        goto end;
705    }
706# ifdef CRYPTO_MDEBUG
707    CRYPTO_pop_info();
708# endif
709
710    if (!twopass)
711        BUF_strlcpy(macpass, pass, sizeof macpass);
712
713    if ((options & INFO) && p12->mac)
714        BIO_printf(bio_err, "MAC Iteration %ld\n",
715                   p12->mac->iter ? ASN1_INTEGER_get(p12->mac->iter) : 1);
716    if (macver) {
717# ifdef CRYPTO_MDEBUG
718        CRYPTO_push_info("verify MAC");
719# endif
720        /* If we enter empty password try no password first */
721        if (!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) {
722            /* If mac and crypto pass the same set it to NULL too */
723            if (!twopass)
724                cpass = NULL;
725        } else if (!PKCS12_verify_mac(p12, mpass, -1)) {
726            BIO_printf(bio_err, "Mac verify error: invalid password?\n");
727            ERR_print_errors(bio_err);
728            goto end;
729        }
730        BIO_printf(bio_err, "MAC verified OK\n");
731# ifdef CRYPTO_MDEBUG
732        CRYPTO_pop_info();
733# endif
734    }
735# ifdef CRYPTO_MDEBUG
736    CRYPTO_push_info("output keys and certificates");
737# endif
738    if (!dump_certs_keys_p12(out, p12, cpass, -1, options, passout)) {
739        BIO_printf(bio_err, "Error outputting keys and certificates\n");
740        ERR_print_errors(bio_err);
741        goto end;
742    }
743# ifdef CRYPTO_MDEBUG
744    CRYPTO_pop_info();
745# endif
746    ret = 0;
747 end:
748    if (p12)
749        PKCS12_free(p12);
750    if (export_cert || inrand)
751        app_RAND_write_file(NULL, bio_err);
752# ifdef CRYPTO_MDEBUG
753    CRYPTO_remove_all_info();
754# endif
755    release_engine(e);
756    BIO_free(in);
757    BIO_free_all(out);
758    if (canames)
759        sk_OPENSSL_STRING_free(canames);
760    if (passin)
761        OPENSSL_free(passin);
762    if (passout)
763        OPENSSL_free(passout);
764    apps_shutdown();
765    OPENSSL_EXIT(ret);
766}
767
768int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass,
769                        int passlen, int options, char *pempass)
770{
771    STACK_OF(PKCS7) *asafes = NULL;
772    STACK_OF(PKCS12_SAFEBAG) *bags;
773    int i, bagnid;
774    int ret = 0;
775    PKCS7 *p7;
776
777    if (!(asafes = PKCS12_unpack_authsafes(p12)))
778        return 0;
779    for (i = 0; i < sk_PKCS7_num(asafes); i++) {
780        p7 = sk_PKCS7_value(asafes, i);
781        bagnid = OBJ_obj2nid(p7->type);
782        if (bagnid == NID_pkcs7_data) {
783            bags = PKCS12_unpack_p7data(p7);
784            if (options & INFO)
785                BIO_printf(bio_err, "PKCS7 Data\n");
786        } else if (bagnid == NID_pkcs7_encrypted) {
787            if (options & INFO) {
788                BIO_printf(bio_err, "PKCS7 Encrypted data: ");
789                alg_print(bio_err, p7->d.encrypted->enc_data->algorithm);
790            }
791            bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
792        } else
793            continue;
794        if (!bags)
795            goto err;
796        if (!dump_certs_pkeys_bags(out, bags, pass, passlen,
797                                   options, pempass)) {
798            sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
799            goto err;
800        }
801        sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
802        bags = NULL;
803    }
804    ret = 1;
805
806 err:
807
808    if (asafes)
809        sk_PKCS7_pop_free(asafes, PKCS7_free);
810    return ret;
811}
812
813int dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags,
814                          char *pass, int passlen, int options, char *pempass)
815{
816    int i;
817    for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
818        if (!dump_certs_pkeys_bag(out,
819                                  sk_PKCS12_SAFEBAG_value(bags, i),
820                                  pass, passlen, options, pempass))
821            return 0;
822    }
823    return 1;
824}
825
826int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bag, char *pass,
827                         int passlen, int options, char *pempass)
828{
829    EVP_PKEY *pkey;
830    PKCS8_PRIV_KEY_INFO *p8;
831    X509 *x509;
832    int ret = 0;
833
834    switch (M_PKCS12_bag_type(bag)) {
835    case NID_keyBag:
836        if (options & INFO)
837            BIO_printf(bio_err, "Key bag\n");
838        if (options & NOKEYS)
839            return 1;
840        print_attribs(out, bag->attrib, "Bag Attributes");
841        p8 = bag->value.keybag;
842        if (!(pkey = EVP_PKCS82PKEY(p8)))
843            return 0;
844        print_attribs(out, p8->attributes, "Key Attributes");
845        ret = PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass);
846        EVP_PKEY_free(pkey);
847        break;
848
849    case NID_pkcs8ShroudedKeyBag:
850        if (options & INFO) {
851            BIO_printf(bio_err, "Shrouded Keybag: ");
852            alg_print(bio_err, bag->value.shkeybag->algor);
853        }
854        if (options & NOKEYS)
855            return 1;
856        print_attribs(out, bag->attrib, "Bag Attributes");
857        if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen)))
858            return 0;
859        if (!(pkey = EVP_PKCS82PKEY(p8))) {
860            PKCS8_PRIV_KEY_INFO_free(p8);
861            return 0;
862        }
863        print_attribs(out, p8->attributes, "Key Attributes");
864        PKCS8_PRIV_KEY_INFO_free(p8);
865        ret = PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass);
866        EVP_PKEY_free(pkey);
867        break;
868
869    case NID_certBag:
870        if (options & INFO)
871            BIO_printf(bio_err, "Certificate bag\n");
872        if (options & NOCERTS)
873            return 1;
874        if (PKCS12_get_attr(bag, NID_localKeyID)) {
875            if (options & CACERTS)
876                return 1;
877        } else if (options & CLCERTS)
878            return 1;
879        print_attribs(out, bag->attrib, "Bag Attributes");
880        if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate)
881            return 1;
882        if (!(x509 = PKCS12_certbag2x509(bag)))
883            return 0;
884        dump_cert_text(out, x509);
885        ret = PEM_write_bio_X509(out, x509);
886        X509_free(x509);
887        break;
888
889    case NID_safeContentsBag:
890        if (options & INFO)
891            BIO_printf(bio_err, "Safe Contents bag\n");
892        print_attribs(out, bag->attrib, "Bag Attributes");
893        return dump_certs_pkeys_bags(out, bag->value.safes, pass,
894                                     passlen, options, pempass);
895
896    default:
897        BIO_printf(bio_err, "Warning unsupported bag type: ");
898        i2a_ASN1_OBJECT(bio_err, bag->type);
899        BIO_printf(bio_err, "\n");
900        return 1;
901        break;
902    }
903    return ret;
904}
905
906/* Given a single certificate return a verified chain or NULL if error */
907
908static int get_cert_chain(X509 *cert, X509_STORE *store,
909                          STACK_OF(X509) **chain)
910{
911    X509_STORE_CTX store_ctx;
912    STACK_OF(X509) *chn = NULL;
913    int i = 0;
914
915    if (!X509_STORE_CTX_init(&store_ctx, store, cert, NULL)) {
916        *chain = NULL;
917        return X509_V_ERR_UNSPECIFIED;
918    }
919
920    if (X509_verify_cert(&store_ctx) > 0)
921        chn = X509_STORE_CTX_get1_chain(&store_ctx);
922    else if ((i = X509_STORE_CTX_get_error(&store_ctx)) == 0)
923        i = X509_V_ERR_UNSPECIFIED;
924
925    X509_STORE_CTX_cleanup(&store_ctx);
926    *chain = chn;
927    return i;
928}
929
930int alg_print(BIO *x, X509_ALGOR *alg)
931{
932    int pbenid, aparamtype;
933    ASN1_OBJECT *aoid;
934    void *aparam;
935    PBEPARAM *pbe = NULL;
936
937    X509_ALGOR_get0(&aoid, &aparamtype, &aparam, alg);
938
939    pbenid = OBJ_obj2nid(aoid);
940
941    BIO_printf(x, "%s", OBJ_nid2ln(pbenid));
942
943    /*
944     * If PBE algorithm is PBES2 decode algorithm parameters
945     * for additional details.
946     */
947    if (pbenid == NID_pbes2) {
948        PBE2PARAM *pbe2 = NULL;
949        int encnid;
950        if (aparamtype == V_ASN1_SEQUENCE)
951            pbe2 = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(PBE2PARAM));
952        if (pbe2 == NULL) {
953            BIO_puts(x, "<unsupported parameters>");
954            goto done;
955        }
956        X509_ALGOR_get0(&aoid, &aparamtype, &aparam, pbe2->keyfunc);
957        pbenid = OBJ_obj2nid(aoid);
958        X509_ALGOR_get0(&aoid, NULL, NULL, pbe2->encryption);
959        encnid = OBJ_obj2nid(aoid);
960        BIO_printf(x, ", %s, %s", OBJ_nid2ln(pbenid),
961                   OBJ_nid2sn(encnid));
962        /* If KDF is PBKDF2 decode parameters */
963        if (pbenid == NID_id_pbkdf2) {
964            PBKDF2PARAM *kdf = NULL;
965            int prfnid;
966            if (aparamtype == V_ASN1_SEQUENCE)
967                kdf = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(PBKDF2PARAM));
968            if (kdf == NULL) {
969                BIO_puts(x, "<unsupported parameters>");
970                goto done;
971            }
972
973            if (kdf->prf == NULL) {
974                prfnid = NID_hmacWithSHA1;
975            } else {
976                X509_ALGOR_get0(&aoid, NULL, NULL, kdf->prf);
977                prfnid = OBJ_obj2nid(aoid);
978            }
979            BIO_printf(x, ", Iteration %ld, PRF %s",
980                       ASN1_INTEGER_get(kdf->iter), OBJ_nid2sn(prfnid));
981            PBKDF2PARAM_free(kdf);
982        }
983        PBE2PARAM_free(pbe2);
984    } else {
985        if (aparamtype == V_ASN1_SEQUENCE)
986            pbe = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(PBEPARAM));
987        if (pbe == NULL) {
988            BIO_puts(x, "<unsupported parameters>");
989            goto done;
990        }
991        BIO_printf(x, ", Iteration %ld", ASN1_INTEGER_get(pbe->iter));
992        PBEPARAM_free(pbe);
993    }
994 done:
995    BIO_puts(x, "\n");
996    return 1;
997}
998
999/* Load all certificates from a given file */
1000
1001int cert_load(BIO *in, STACK_OF(X509) *sk)
1002{
1003    int ret;
1004    X509 *cert;
1005    ret = 0;
1006# ifdef CRYPTO_MDEBUG
1007    CRYPTO_push_info("cert_load(): reading one cert");
1008# endif
1009    while ((cert = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
1010# ifdef CRYPTO_MDEBUG
1011        CRYPTO_pop_info();
1012# endif
1013        ret = 1;
1014        sk_X509_push(sk, cert);
1015# ifdef CRYPTO_MDEBUG
1016        CRYPTO_push_info("cert_load(): reading one cert");
1017# endif
1018    }
1019# ifdef CRYPTO_MDEBUG
1020    CRYPTO_pop_info();
1021# endif
1022    if (ret)
1023        ERR_clear_error();
1024    return ret;
1025}
1026
1027/* Generalised attribute print: handle PKCS#8 and bag attributes */
1028
1029int print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,
1030                  const char *name)
1031{
1032    X509_ATTRIBUTE *attr;
1033    ASN1_TYPE *av;
1034    char *value;
1035    int i, attr_nid;
1036    if (!attrlst) {
1037        BIO_printf(out, "%s: <No Attributes>\n", name);
1038        return 1;
1039    }
1040    if (!sk_X509_ATTRIBUTE_num(attrlst)) {
1041        BIO_printf(out, "%s: <Empty Attributes>\n", name);
1042        return 1;
1043    }
1044    BIO_printf(out, "%s\n", name);
1045    for (i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) {
1046        attr = sk_X509_ATTRIBUTE_value(attrlst, i);
1047        attr_nid = OBJ_obj2nid(attr->object);
1048        BIO_printf(out, "    ");
1049        if (attr_nid == NID_undef) {
1050            i2a_ASN1_OBJECT(out, attr->object);
1051            BIO_printf(out, ": ");
1052        } else
1053            BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid));
1054
1055        if (sk_ASN1_TYPE_num(attr->value.set)) {
1056            av = sk_ASN1_TYPE_value(attr->value.set, 0);
1057            switch (av->type) {
1058            case V_ASN1_BMPSTRING:
1059                value = OPENSSL_uni2asc(av->value.bmpstring->data,
1060                                        av->value.bmpstring->length);
1061                BIO_printf(out, "%s\n", value);
1062                OPENSSL_free(value);
1063                break;
1064
1065            case V_ASN1_OCTET_STRING:
1066                hex_prin(out, av->value.octet_string->data,
1067                         av->value.octet_string->length);
1068                BIO_printf(out, "\n");
1069                break;
1070
1071            case V_ASN1_BIT_STRING:
1072                hex_prin(out, av->value.bit_string->data,
1073                         av->value.bit_string->length);
1074                BIO_printf(out, "\n");
1075                break;
1076
1077            default:
1078                BIO_printf(out, "<Unsupported tag %d>\n", av->type);
1079                break;
1080            }
1081        } else
1082            BIO_printf(out, "<No Values>\n");
1083    }
1084    return 1;
1085}
1086
1087void hex_prin(BIO *out, unsigned char *buf, int len)
1088{
1089    int i;
1090    for (i = 0; i < len; i++)
1091        BIO_printf(out, "%02X ", buf[i]);
1092}
1093
1094static int set_pbe(BIO *err, int *ppbe, const char *str)
1095{
1096    if (!str)
1097        return 0;
1098    if (!strcmp(str, "NONE")) {
1099        *ppbe = -1;
1100        return 1;
1101    }
1102    *ppbe = OBJ_txt2nid(str);
1103    if (*ppbe == NID_undef) {
1104        BIO_printf(bio_err, "Unknown PBE algorithm %s\n", str);
1105        return 0;
1106    }
1107    return 1;
1108}
1109
1110#else
1111static void *dummy = &dummy;
1112#endif
1113