[BACK]Return to pkcs12.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / openssl

Annotation of src/usr.bin/openssl/pkcs12.c, Revision 1.1

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