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