155714Skris/* pkcs12.c */ 2194206Ssimon/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3160814Ssimon * project. 455714Skris */ 555714Skris/* ==================================================================== 6162911Ssimon * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. 755714Skris * 855714Skris * Redistribution and use in source and binary forms, with or without 955714Skris * modification, are permitted provided that the following conditions 1055714Skris * are met: 1155714Skris * 1255714Skris * 1. Redistributions of source code must retain the above copyright 1355714Skris * notice, this list of conditions and the following disclaimer. 1455714Skris * 1555714Skris * 2. Redistributions in binary form must reproduce the above copyright 1655714Skris * notice, this list of conditions and the following disclaimer in 1755714Skris * the documentation and/or other materials provided with the 1855714Skris * distribution. 1955714Skris * 2055714Skris * 3. All advertising materials mentioning features or use of this 2155714Skris * software must display the following acknowledgment: 2255714Skris * "This product includes software developed by the OpenSSL Project 2355714Skris * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 2455714Skris * 2555714Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 2655714Skris * endorse or promote products derived from this software without 2755714Skris * prior written permission. For written permission, please contact 2855714Skris * licensing@OpenSSL.org. 2955714Skris * 3055714Skris * 5. Products derived from this software may not be called "OpenSSL" 3155714Skris * nor may "OpenSSL" appear in their names without prior written 3255714Skris * permission of the OpenSSL Project. 3355714Skris * 3455714Skris * 6. Redistributions of any form whatsoever must retain the following 3555714Skris * acknowledgment: 3655714Skris * "This product includes software developed by the OpenSSL Project 3755714Skris * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 3855714Skris * 3955714Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 4055714Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4155714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 4255714Skris * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 4355714Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4455714Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4555714Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 4655714Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4755714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4855714Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 4955714Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 5055714Skris * OF THE POSSIBILITY OF SUCH DAMAGE. 5155714Skris * ==================================================================== 5255714Skris * 5355714Skris * This product includes cryptographic software written by Eric Young 5455714Skris * (eay@cryptsoft.com). This product includes software written by Tim 5555714Skris * Hudson (tjh@cryptsoft.com). 5655714Skris * 5755714Skris */ 5855714Skris 59160814Ssimon#include <openssl/opensslconf.h> 60160814Ssimon#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1) 61160814Ssimon 6255714Skris#include <stdio.h> 6355714Skris#include <stdlib.h> 6455714Skris#include <string.h> 6559191Skris#include "apps.h" 6659191Skris#include <openssl/crypto.h> 6759191Skris#include <openssl/err.h> 6855714Skris#include <openssl/pem.h> 6955714Skris#include <openssl/pkcs12.h> 7055714Skris 7155714Skris#define PROG pkcs12_main 7255714Skris 73109998Smarkmconst EVP_CIPHER *enc; 7455714Skris 7555714Skris 7655714Skris#define NOKEYS 0x1 7755714Skris#define NOCERTS 0x2 7855714Skris#define INFO 0x4 7955714Skris#define CLCERTS 0x8 8055714Skris#define CACERTS 0x10 8155714Skris 8268651Skrisint get_cert_chain (X509 *cert, X509_STORE *store, STACK_OF(X509) **chain); 8359191Skrisint dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int passlen, int options, char *pempass); 8468651Skrisint dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, char *pass, 8568651Skris int passlen, int options, char *pempass); 8659191Skrisint dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass, int passlen, int options, char *pempass); 87160814Ssimonint print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,const char *name); 8855714Skrisvoid hex_prin(BIO *out, unsigned char *buf, int len); 8955714Skrisint alg_print(BIO *x, X509_ALGOR *alg); 9055714Skrisint cert_load(BIO *in, STACK_OF(X509) *sk); 91238405Sjkimstatic int set_pbe(BIO *err, int *ppbe, const char *str); 9259191Skris 9359191Skrisint MAIN(int, char **); 9459191Skris 9555714Skrisint MAIN(int argc, char **argv) 9655714Skris{ 97109998Smarkm ENGINE *e = NULL; 9855714Skris char *infile=NULL, *outfile=NULL, *keyname = NULL; 9955714Skris char *certfile=NULL; 100109998Smarkm BIO *in=NULL, *out = NULL; 10155714Skris char **args; 10255714Skris char *name = NULL; 103109998Smarkm char *csp_name = NULL; 104194206Ssimon int add_lmk = 0; 10555714Skris PKCS12 *p12 = NULL; 10655714Skris char pass[50], macpass[50]; 10755714Skris int export_cert = 0; 10855714Skris int options = 0; 10955714Skris int chain = 0; 11055714Skris int badarg = 0; 11155714Skris int iter = PKCS12_DEFAULT_ITER; 11259191Skris int maciter = PKCS12_DEFAULT_ITER; 11355714Skris int twopass = 0; 11455714Skris int keytype = 0; 115279264Sdelphij int cert_pbe; 11659191Skris int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; 11755714Skris int ret = 1; 11855714Skris int macver = 1; 11955714Skris int noprompt = 0; 120238405Sjkim STACK_OF(OPENSSL_STRING) *canames = NULL; 12155714Skris char *cpass = NULL, *mpass = NULL; 12259191Skris char *passargin = NULL, *passargout = NULL, *passarg = NULL; 12359191Skris char *passin = NULL, *passout = NULL; 12459191Skris char *inrand = NULL; 125238405Sjkim char *macalg = NULL; 12668651Skris char *CApath = NULL, *CAfile = NULL; 127111147Snectar#ifndef OPENSSL_NO_ENGINE 128109998Smarkm char *engine=NULL; 129111147Snectar#endif 13055714Skris 13155714Skris apps_startup(); 13255714Skris 133279264Sdelphij#ifdef OPENSSL_FIPS 134279264Sdelphij if (FIPS_mode()) 135279264Sdelphij cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; 136279264Sdelphij else 137279264Sdelphij#endif 138279264Sdelphij cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; 139279264Sdelphij 14055714Skris enc = EVP_des_ede3_cbc(); 14155714Skris if (bio_err == NULL ) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE); 14255714Skris 143109998Smarkm if (!load_config(bio_err, NULL)) 144109998Smarkm goto end; 145109998Smarkm 14655714Skris args = argv + 1; 14755714Skris 14855714Skris 14955714Skris while (*args) { 15055714Skris if (*args[0] == '-') { 15155714Skris if (!strcmp (*args, "-nokeys")) options |= NOKEYS; 15255714Skris else if (!strcmp (*args, "-keyex")) keytype = KEY_EX; 15355714Skris else if (!strcmp (*args, "-keysig")) keytype = KEY_SIG; 15455714Skris else if (!strcmp (*args, "-nocerts")) options |= NOCERTS; 15555714Skris else if (!strcmp (*args, "-clcerts")) options |= CLCERTS; 15655714Skris else if (!strcmp (*args, "-cacerts")) options |= CACERTS; 15755714Skris else if (!strcmp (*args, "-noout")) options |= (NOKEYS|NOCERTS); 15855714Skris else if (!strcmp (*args, "-info")) options |= INFO; 15955714Skris else if (!strcmp (*args, "-chain")) chain = 1; 16055714Skris else if (!strcmp (*args, "-twopass")) twopass = 1; 16155714Skris else if (!strcmp (*args, "-nomacver")) macver = 0; 16255714Skris else if (!strcmp (*args, "-descert")) 16355714Skris cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; 16455714Skris else if (!strcmp (*args, "-export")) export_cert = 1; 16555714Skris else if (!strcmp (*args, "-des")) enc=EVP_des_cbc(); 166194206Ssimon else if (!strcmp (*args, "-des3")) enc = EVP_des_ede3_cbc(); 167109998Smarkm#ifndef OPENSSL_NO_IDEA 16855714Skris else if (!strcmp (*args, "-idea")) enc=EVP_idea_cbc(); 16955714Skris#endif 170194206Ssimon#ifndef OPENSSL_NO_SEED 171194206Ssimon else if (!strcmp(*args, "-seed")) enc=EVP_seed_cbc(); 172194206Ssimon#endif 173109998Smarkm#ifndef OPENSSL_NO_AES 174109998Smarkm else if (!strcmp(*args,"-aes128")) enc=EVP_aes_128_cbc(); 175109998Smarkm else if (!strcmp(*args,"-aes192")) enc=EVP_aes_192_cbc(); 176109998Smarkm else if (!strcmp(*args,"-aes256")) enc=EVP_aes_256_cbc(); 177109998Smarkm#endif 178162911Ssimon#ifndef OPENSSL_NO_CAMELLIA 179162911Ssimon else if (!strcmp(*args,"-camellia128")) enc=EVP_camellia_128_cbc(); 180162911Ssimon else if (!strcmp(*args,"-camellia192")) enc=EVP_camellia_192_cbc(); 181162911Ssimon else if (!strcmp(*args,"-camellia256")) enc=EVP_camellia_256_cbc(); 182162911Ssimon#endif 18355714Skris else if (!strcmp (*args, "-noiter")) iter = 1; 18455714Skris else if (!strcmp (*args, "-maciter")) 18555714Skris maciter = PKCS12_DEFAULT_ITER; 18659191Skris else if (!strcmp (*args, "-nomaciter")) 18759191Skris maciter = 1; 188160814Ssimon else if (!strcmp (*args, "-nomac")) 189160814Ssimon maciter = -1; 190238405Sjkim else if (!strcmp (*args, "-macalg")) 191238405Sjkim if (args[1]) { 192238405Sjkim args++; 193238405Sjkim macalg = *args; 194238405Sjkim } else badarg = 1; 19555714Skris else if (!strcmp (*args, "-nodes")) enc=NULL; 19659191Skris else if (!strcmp (*args, "-certpbe")) { 197238405Sjkim if (!set_pbe(bio_err, &cert_pbe, *++args)) 198238405Sjkim badarg = 1; 19959191Skris } else if (!strcmp (*args, "-keypbe")) { 200238405Sjkim if (!set_pbe(bio_err, &key_pbe, *++args)) 201238405Sjkim badarg = 1; 20259191Skris } else if (!strcmp (*args, "-rand")) { 20355714Skris if (args[1]) { 20455714Skris args++; 20559191Skris inrand = *args; 20659191Skris } else badarg = 1; 20759191Skris } else if (!strcmp (*args, "-inkey")) { 20859191Skris if (args[1]) { 20959191Skris args++; 21055714Skris keyname = *args; 21155714Skris } else badarg = 1; 21255714Skris } else if (!strcmp (*args, "-certfile")) { 21355714Skris if (args[1]) { 21455714Skris args++; 21555714Skris certfile = *args; 21655714Skris } else badarg = 1; 21755714Skris } else if (!strcmp (*args, "-name")) { 21855714Skris if (args[1]) { 21955714Skris args++; 22055714Skris name = *args; 22155714Skris } else badarg = 1; 222194206Ssimon } else if (!strcmp (*args, "-LMK")) 223194206Ssimon add_lmk = 1; 224194206Ssimon else if (!strcmp (*args, "-CSP")) { 225109998Smarkm if (args[1]) { 226109998Smarkm args++; 227109998Smarkm csp_name = *args; 228109998Smarkm } else badarg = 1; 22955714Skris } else if (!strcmp (*args, "-caname")) { 23055714Skris if (args[1]) { 23155714Skris args++; 232238405Sjkim if (!canames) canames = sk_OPENSSL_STRING_new_null(); 233238405Sjkim sk_OPENSSL_STRING_push(canames, *args); 23455714Skris } else badarg = 1; 23555714Skris } else if (!strcmp (*args, "-in")) { 23655714Skris if (args[1]) { 23755714Skris args++; 23855714Skris infile = *args; 23955714Skris } else badarg = 1; 24055714Skris } else if (!strcmp (*args, "-out")) { 24155714Skris if (args[1]) { 24255714Skris args++; 24355714Skris outfile = *args; 24455714Skris } else badarg = 1; 24559191Skris } else if (!strcmp(*args,"-passin")) { 24655714Skris if (args[1]) { 24755714Skris args++; 24859191Skris passargin = *args; 24955714Skris } else badarg = 1; 25059191Skris } else if (!strcmp(*args,"-passout")) { 25159191Skris if (args[1]) { 25259191Skris args++; 25359191Skris passargout = *args; 25459191Skris } else badarg = 1; 25555714Skris } else if (!strcmp (*args, "-password")) { 25655714Skris if (args[1]) { 25755714Skris args++; 25859191Skris passarg = *args; 25955714Skris noprompt = 1; 26055714Skris } else badarg = 1; 26168651Skris } else if (!strcmp(*args,"-CApath")) { 26268651Skris if (args[1]) { 26368651Skris args++; 26468651Skris CApath = *args; 26568651Skris } else badarg = 1; 26668651Skris } else if (!strcmp(*args,"-CAfile")) { 26768651Skris if (args[1]) { 26868651Skris args++; 26968651Skris CAfile = *args; 27068651Skris } else badarg = 1; 271111147Snectar#ifndef OPENSSL_NO_ENGINE 272109998Smarkm } else if (!strcmp(*args,"-engine")) { 273109998Smarkm if (args[1]) { 274109998Smarkm args++; 275109998Smarkm engine = *args; 276109998Smarkm } else badarg = 1; 277111147Snectar#endif 27855714Skris } else badarg = 1; 27955714Skris 28055714Skris } else badarg = 1; 28155714Skris args++; 28255714Skris } 28355714Skris 28455714Skris if (badarg) { 28555714Skris BIO_printf (bio_err, "Usage: pkcs12 [options]\n"); 28655714Skris BIO_printf (bio_err, "where options are\n"); 28755714Skris BIO_printf (bio_err, "-export output PKCS12 file\n"); 28855714Skris BIO_printf (bio_err, "-chain add certificate chain\n"); 28955714Skris BIO_printf (bio_err, "-inkey file private key if not infile\n"); 29055714Skris BIO_printf (bio_err, "-certfile f add all certs in f\n"); 29168651Skris BIO_printf (bio_err, "-CApath arg - PEM format directory of CA's\n"); 29268651Skris BIO_printf (bio_err, "-CAfile arg - PEM format file of CA's\n"); 29355714Skris BIO_printf (bio_err, "-name \"name\" use name as friendly name\n"); 29455714Skris BIO_printf (bio_err, "-caname \"nm\" use nm as CA friendly name (can be used more than once).\n"); 29555714Skris BIO_printf (bio_err, "-in infile input filename\n"); 29655714Skris BIO_printf (bio_err, "-out outfile output filename\n"); 29755714Skris BIO_printf (bio_err, "-noout don't output anything, just verify.\n"); 29855714Skris BIO_printf (bio_err, "-nomacver don't verify MAC.\n"); 29955714Skris BIO_printf (bio_err, "-nocerts don't output certificates.\n"); 30055714Skris BIO_printf (bio_err, "-clcerts only output client certificates.\n"); 30155714Skris BIO_printf (bio_err, "-cacerts only output CA certificates.\n"); 30255714Skris BIO_printf (bio_err, "-nokeys don't output private keys.\n"); 30355714Skris BIO_printf (bio_err, "-info give info about PKCS#12 structure.\n"); 30455714Skris BIO_printf (bio_err, "-des encrypt private keys with DES\n"); 30555714Skris BIO_printf (bio_err, "-des3 encrypt private keys with triple DES (default)\n"); 306109998Smarkm#ifndef OPENSSL_NO_IDEA 30755714Skris BIO_printf (bio_err, "-idea encrypt private keys with idea\n"); 30855714Skris#endif 309194206Ssimon#ifndef OPENSSL_NO_SEED 310194206Ssimon BIO_printf (bio_err, "-seed encrypt private keys with seed\n"); 311194206Ssimon#endif 312109998Smarkm#ifndef OPENSSL_NO_AES 313109998Smarkm BIO_printf (bio_err, "-aes128, -aes192, -aes256\n"); 314109998Smarkm BIO_printf (bio_err, " encrypt PEM output with cbc aes\n"); 315109998Smarkm#endif 316162911Ssimon#ifndef OPENSSL_NO_CAMELLIA 317162911Ssimon BIO_printf (bio_err, "-camellia128, -camellia192, -camellia256\n"); 318162911Ssimon BIO_printf (bio_err, " encrypt PEM output with cbc camellia\n"); 319162911Ssimon#endif 32055714Skris BIO_printf (bio_err, "-nodes don't encrypt private keys\n"); 32155714Skris BIO_printf (bio_err, "-noiter don't use encryption iteration\n"); 322238405Sjkim BIO_printf (bio_err, "-nomaciter don't use MAC iteration\n"); 32355714Skris BIO_printf (bio_err, "-maciter use MAC iteration\n"); 324238405Sjkim BIO_printf (bio_err, "-nomac don't generate MAC\n"); 32555714Skris BIO_printf (bio_err, "-twopass separate MAC, encryption passwords\n"); 32655714Skris BIO_printf (bio_err, "-descert encrypt PKCS#12 certificates with triple DES (default RC2-40)\n"); 32759191Skris BIO_printf (bio_err, "-certpbe alg specify certificate PBE algorithm (default RC2-40)\n"); 32859191Skris BIO_printf (bio_err, "-keypbe alg specify private key PBE algorithm (default 3DES)\n"); 329238405Sjkim BIO_printf (bio_err, "-macalg alg digest algorithm used in MAC (default SHA1)\n"); 33055714Skris BIO_printf (bio_err, "-keyex set MS key exchange type\n"); 33155714Skris BIO_printf (bio_err, "-keysig set MS key signature type\n"); 33259191Skris BIO_printf (bio_err, "-password p set import/export password source\n"); 33359191Skris BIO_printf (bio_err, "-passin p input file pass phrase source\n"); 33459191Skris BIO_printf (bio_err, "-passout p output file pass phrase source\n"); 335111147Snectar#ifndef OPENSSL_NO_ENGINE 336109998Smarkm BIO_printf (bio_err, "-engine e use engine e, possibly a hardware device.\n"); 337111147Snectar#endif 33859191Skris BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); 33959191Skris BIO_printf(bio_err, " load the file (or the files in the directory) into\n"); 34059191Skris BIO_printf(bio_err, " the random number generator\n"); 341238405Sjkim BIO_printf(bio_err, "-CSP name Microsoft CSP name\n"); 342238405Sjkim BIO_printf(bio_err, "-LMK Add local machine keyset attribute to private key\n"); 34355714Skris goto end; 34455714Skris } 34555714Skris 346111147Snectar#ifndef OPENSSL_NO_ENGINE 347109998Smarkm e = setup_engine(bio_err, engine, 0); 348111147Snectar#endif 349109998Smarkm 35059191Skris if(passarg) { 35159191Skris if(export_cert) passargout = passarg; 35259191Skris else passargin = passarg; 35359191Skris } 35459191Skris 35559191Skris if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { 35659191Skris BIO_printf(bio_err, "Error getting passwords\n"); 35759191Skris goto end; 35859191Skris } 35959191Skris 36059191Skris if(!cpass) { 36159191Skris if(export_cert) cpass = passout; 36259191Skris else cpass = passin; 36359191Skris } 36459191Skris 36559191Skris if(cpass) { 36659191Skris mpass = cpass; 36759191Skris noprompt = 1; 36859191Skris } else { 36955714Skris cpass = pass; 37055714Skris mpass = macpass; 37155714Skris } 37255714Skris 37359191Skris if(export_cert || inrand) { 37459191Skris app_RAND_load_file(NULL, bio_err, (inrand != NULL)); 37559191Skris if (inrand != NULL) 37659191Skris BIO_printf(bio_err,"%ld semi-random bytes loaded\n", 37759191Skris app_RAND_load_files(inrand)); 37859191Skris } 37955714Skris ERR_load_crypto_strings(); 38055714Skris 38159191Skris#ifdef CRYPTO_MDEBUG 38259191Skris CRYPTO_push_info("read files"); 38359191Skris#endif 38459191Skris 38555714Skris if (!infile) in = BIO_new_fp(stdin, BIO_NOCLOSE); 38655714Skris else in = BIO_new_file(infile, "rb"); 38755714Skris if (!in) { 38855714Skris BIO_printf(bio_err, "Error opening input file %s\n", 38955714Skris infile ? infile : "<stdin>"); 39055714Skris perror (infile); 39155714Skris goto end; 39255714Skris } 39355714Skris 39459191Skris#ifdef CRYPTO_MDEBUG 39559191Skris CRYPTO_pop_info(); 39659191Skris CRYPTO_push_info("write files"); 39759191Skris#endif 39859191Skris 39968651Skris if (!outfile) { 40068651Skris out = BIO_new_fp(stdout, BIO_NOCLOSE); 401109998Smarkm#ifdef OPENSSL_SYS_VMS 40268651Skris { 40368651Skris BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 40468651Skris out = BIO_push(tmpbio, out); 40568651Skris } 40668651Skris#endif 40768651Skris } else out = BIO_new_file(outfile, "wb"); 40855714Skris if (!out) { 40955714Skris BIO_printf(bio_err, "Error opening output file %s\n", 41055714Skris outfile ? outfile : "<stdout>"); 41155714Skris perror (outfile); 41255714Skris goto end; 41355714Skris } 41455714Skris if (twopass) { 41559191Skris#ifdef CRYPTO_MDEBUG 41659191Skris CRYPTO_push_info("read MAC password"); 41759191Skris#endif 418109998Smarkm if(EVP_read_pw_string (macpass, sizeof macpass, "Enter MAC Password:", export_cert)) 41955714Skris { 42055714Skris BIO_printf (bio_err, "Can't read Password\n"); 42155714Skris goto end; 42255714Skris } 42359191Skris#ifdef CRYPTO_MDEBUG 42459191Skris CRYPTO_pop_info(); 42559191Skris#endif 42655714Skris } 42755714Skris 42859191Skris if (export_cert) { 42968651Skris EVP_PKEY *key = NULL; 430160814Ssimon X509 *ucert = NULL, *x = NULL; 43159191Skris STACK_OF(X509) *certs=NULL; 432238405Sjkim const EVP_MD *macmd = NULL; 433160814Ssimon unsigned char *catmp = NULL; 43455714Skris int i; 43559191Skris 436160814Ssimon if ((options & (NOCERTS|NOKEYS)) == (NOCERTS|NOKEYS)) 437160814Ssimon { 438160814Ssimon BIO_printf(bio_err, "Nothing to do!\n"); 439160814Ssimon goto export_end; 440160814Ssimon } 441160814Ssimon 442160814Ssimon if (options & NOCERTS) 443160814Ssimon chain = 0; 444160814Ssimon 44559191Skris#ifdef CRYPTO_MDEBUG 44659191Skris CRYPTO_push_info("process -export_cert"); 44768651Skris CRYPTO_push_info("reading private key"); 44859191Skris#endif 449160814Ssimon if (!(options & NOKEYS)) 450160814Ssimon { 451160814Ssimon key = load_key(bio_err, keyname ? keyname : infile, 452160814Ssimon FORMAT_PEM, 1, passin, e, "private key"); 453160814Ssimon if (!key) 454160814Ssimon goto export_end; 455160814Ssimon } 45655714Skris 45768651Skris#ifdef CRYPTO_MDEBUG 45868651Skris CRYPTO_pop_info(); 45968651Skris CRYPTO_push_info("reading certs from input"); 46068651Skris#endif 46155714Skris 46255714Skris /* Load in all certs in input file */ 463160814Ssimon if(!(options & NOCERTS)) 464160814Ssimon { 465160814Ssimon certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e, 466160814Ssimon "certificates"); 467160814Ssimon if (!certs) 468160814Ssimon goto export_end; 46955714Skris 470160814Ssimon if (key) 471160814Ssimon { 472160814Ssimon /* Look for matching private key */ 473160814Ssimon for(i = 0; i < sk_X509_num(certs); i++) 474160814Ssimon { 475160814Ssimon x = sk_X509_value(certs, i); 476160814Ssimon if(X509_check_private_key(x, key)) 477160814Ssimon { 478160814Ssimon ucert = x; 479160814Ssimon /* Zero keyid and alias */ 480160814Ssimon X509_keyid_set1(ucert, NULL, 0); 481160814Ssimon X509_alias_set1(ucert, NULL, 0); 482160814Ssimon /* Remove from list */ 483194206Ssimon (void)sk_X509_delete(certs, i); 484160814Ssimon break; 485160814Ssimon } 486160814Ssimon } 487160814Ssimon if (!ucert) 488160814Ssimon { 489160814Ssimon BIO_printf(bio_err, "No certificate matches private key\n"); 490160814Ssimon goto export_end; 491160814Ssimon } 492160814Ssimon } 49368651Skris 49455714Skris } 495160814Ssimon 49668651Skris#ifdef CRYPTO_MDEBUG 49768651Skris CRYPTO_pop_info(); 498160814Ssimon CRYPTO_push_info("reading certs from input 2"); 49968651Skris#endif 50055714Skris 50155714Skris /* Add any more certificates asked for */ 502160814Ssimon if(certfile) 503160814Ssimon { 504109998Smarkm STACK_OF(X509) *morecerts=NULL; 505109998Smarkm if(!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM, 506109998Smarkm NULL, e, 507160814Ssimon "certificates from certfile"))) 50868651Skris goto export_end; 509160814Ssimon while(sk_X509_num(morecerts) > 0) 510109998Smarkm sk_X509_push(certs, sk_X509_shift(morecerts)); 511109998Smarkm sk_X509_free(morecerts); 512160814Ssimon } 51355714Skris 51468651Skris#ifdef CRYPTO_MDEBUG 51568651Skris CRYPTO_pop_info(); 516160814Ssimon CRYPTO_push_info("reading certs from certfile"); 517160814Ssimon#endif 518160814Ssimon 519160814Ssimon#ifdef CRYPTO_MDEBUG 520160814Ssimon CRYPTO_pop_info(); 52168651Skris CRYPTO_push_info("building chain"); 52268651Skris#endif 52368651Skris 52455714Skris /* If chaining get chain from user cert */ 52555714Skris if (chain) { 52655714Skris int vret; 52755714Skris STACK_OF(X509) *chain2; 52868651Skris X509_STORE *store = X509_STORE_new(); 52968651Skris if (!store) 53068651Skris { 53168651Skris BIO_printf (bio_err, "Memory allocation error\n"); 53268651Skris goto export_end; 53368651Skris } 53468651Skris if (!X509_STORE_load_locations(store, CAfile, CApath)) 53568651Skris X509_STORE_set_default_paths (store); 53668651Skris 53768651Skris vret = get_cert_chain (ucert, store, &chain2); 53868651Skris X509_STORE_free(store); 53968651Skris 54068651Skris if (!vret) { 54168651Skris /* Exclude verified certificate */ 54268651Skris for (i = 1; i < sk_X509_num (chain2) ; i++) 54368651Skris sk_X509_push(certs, sk_X509_value (chain2, i)); 544109998Smarkm /* Free first certificate */ 545109998Smarkm X509_free(sk_X509_value(chain2, 0)); 546109998Smarkm sk_X509_free(chain2); 547109998Smarkm } else { 548167612Ssimon if (vret >= 0) 549167612Ssimon BIO_printf (bio_err, "Error %s getting chain.\n", 55055714Skris X509_verify_cert_error_string(vret)); 551167612Ssimon else 552167612Ssimon ERR_print_errors(bio_err); 55368651Skris goto export_end; 55468651Skris } 55555714Skris } 55655714Skris 557160814Ssimon /* Add any CA names */ 55868651Skris 559238405Sjkim for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++) 560160814Ssimon { 561238405Sjkim catmp = (unsigned char *)sk_OPENSSL_STRING_value(canames, i); 562160814Ssimon X509_alias_set1(sk_X509_value(certs, i), catmp, -1); 563160814Ssimon } 56455714Skris 565160814Ssimon if (csp_name && key) 566160814Ssimon EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name, 567160814Ssimon MBSTRING_ASC, (unsigned char *)csp_name, -1); 568160814Ssimon 569194206Ssimon if (add_lmk && key) 570194206Ssimon EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1); 571194206Ssimon 57268651Skris#ifdef CRYPTO_MDEBUG 57368651Skris CRYPTO_pop_info(); 574160814Ssimon CRYPTO_push_info("reading password"); 57568651Skris#endif 57668651Skris 57755714Skris if(!noprompt && 578160814Ssimon EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:", 1)) 579160814Ssimon { 580160814Ssimon BIO_printf (bio_err, "Can't read Password\n"); 581160814Ssimon goto export_end; 582160814Ssimon } 583127128Snectar if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass); 58455714Skris 58568651Skris#ifdef CRYPTO_MDEBUG 58668651Skris CRYPTO_pop_info(); 587160814Ssimon CRYPTO_push_info("creating PKCS#12 structure"); 58868651Skris#endif 58968651Skris 590160814Ssimon p12 = PKCS12_create(cpass, name, key, ucert, certs, 591160814Ssimon key_pbe, cert_pbe, iter, -1, keytype); 59268651Skris 593160814Ssimon if (!p12) 594160814Ssimon { 595160814Ssimon ERR_print_errors (bio_err); 596160814Ssimon goto export_end; 597160814Ssimon } 59868651Skris 599238405Sjkim if (macalg) 600238405Sjkim { 601238405Sjkim macmd = EVP_get_digestbyname(macalg); 602238405Sjkim if (!macmd) 603238405Sjkim { 604238405Sjkim BIO_printf(bio_err, "Unknown digest algorithm %s\n", 605238405Sjkim macalg); 606238405Sjkim } 607238405Sjkim } 608238405Sjkim 609160814Ssimon if (maciter != -1) 610238405Sjkim PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd); 61155714Skris 61268651Skris#ifdef CRYPTO_MDEBUG 61368651Skris CRYPTO_pop_info(); 61468651Skris CRYPTO_push_info("writing pkcs12"); 61568651Skris#endif 61668651Skris 617160814Ssimon i2d_PKCS12_bio(out, p12); 61855714Skris 61955714Skris ret = 0; 62059191Skris 62168651Skris export_end: 62259191Skris#ifdef CRYPTO_MDEBUG 62359191Skris CRYPTO_pop_info(); 62468651Skris CRYPTO_pop_info(); 62568651Skris CRYPTO_push_info("process -export_cert: freeing"); 62659191Skris#endif 62768651Skris 62868651Skris if (key) EVP_PKEY_free(key); 62968651Skris if (certs) sk_X509_pop_free(certs, X509_free); 630160814Ssimon if (ucert) X509_free(ucert); 63168651Skris 63268651Skris#ifdef CRYPTO_MDEBUG 63368651Skris CRYPTO_pop_info(); 63468651Skris#endif 63555714Skris goto end; 63655714Skris 63755714Skris } 63855714Skris 63955714Skris if (!(p12 = d2i_PKCS12_bio (in, NULL))) { 64055714Skris ERR_print_errors(bio_err); 64155714Skris goto end; 64255714Skris } 64355714Skris 64459191Skris#ifdef CRYPTO_MDEBUG 64559191Skris CRYPTO_push_info("read import password"); 64659191Skris#endif 647109998Smarkm if(!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:", 0)) { 64855714Skris BIO_printf (bio_err, "Can't read Password\n"); 64955714Skris goto end; 65055714Skris } 65159191Skris#ifdef CRYPTO_MDEBUG 65259191Skris CRYPTO_pop_info(); 65359191Skris#endif 65455714Skris 655127128Snectar if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass); 65655714Skris 657237657Sjkim if ((options & INFO) && p12->mac) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1); 65855714Skris if(macver) { 65959191Skris#ifdef CRYPTO_MDEBUG 66059191Skris CRYPTO_push_info("verify MAC"); 66159191Skris#endif 66268651Skris /* If we enter empty password try no password first */ 663160814Ssimon if(!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) { 66468651Skris /* If mac and crypto pass the same set it to NULL too */ 66568651Skris if(!twopass) cpass = NULL; 66668651Skris } else if (!PKCS12_verify_mac(p12, mpass, -1)) { 66759191Skris BIO_printf (bio_err, "Mac verify error: invalid password?\n"); 66855714Skris ERR_print_errors (bio_err); 66955714Skris goto end; 67068651Skris } 67168651Skris BIO_printf (bio_err, "MAC verified OK\n"); 67259191Skris#ifdef CRYPTO_MDEBUG 67359191Skris CRYPTO_pop_info(); 67459191Skris#endif 67555714Skris } 67655714Skris 67759191Skris#ifdef CRYPTO_MDEBUG 67859191Skris CRYPTO_push_info("output keys and certificates"); 67959191Skris#endif 68059191Skris if (!dump_certs_keys_p12 (out, p12, cpass, -1, options, passout)) { 68155714Skris BIO_printf(bio_err, "Error outputting keys and certificates\n"); 68255714Skris ERR_print_errors (bio_err); 68355714Skris goto end; 68455714Skris } 68559191Skris#ifdef CRYPTO_MDEBUG 68659191Skris CRYPTO_pop_info(); 68759191Skris#endif 68855714Skris ret = 0; 68968651Skris end: 69068651Skris if (p12) PKCS12_free(p12); 69159191Skris if(export_cert || inrand) app_RAND_write_file(NULL, bio_err); 69259191Skris#ifdef CRYPTO_MDEBUG 69359191Skris CRYPTO_remove_all_info(); 69459191Skris#endif 69559191Skris BIO_free(in); 69668651Skris BIO_free_all(out); 697238405Sjkim if (canames) sk_OPENSSL_STRING_free(canames); 69868651Skris if(passin) OPENSSL_free(passin); 69968651Skris if(passout) OPENSSL_free(passout); 700109998Smarkm apps_shutdown(); 701109998Smarkm OPENSSL_EXIT(ret); 70255714Skris} 70355714Skris 70455714Skrisint dump_certs_keys_p12 (BIO *out, PKCS12 *p12, char *pass, 70559191Skris int passlen, int options, char *pempass) 70655714Skris{ 707160814Ssimon STACK_OF(PKCS7) *asafes = NULL; 70868651Skris STACK_OF(PKCS12_SAFEBAG) *bags; 70955714Skris int i, bagnid; 710160814Ssimon int ret = 0; 71155714Skris PKCS7 *p7; 71268651Skris 713109998Smarkm if (!( asafes = PKCS12_unpack_authsafes(p12))) return 0; 71468651Skris for (i = 0; i < sk_PKCS7_num (asafes); i++) { 71568651Skris p7 = sk_PKCS7_value (asafes, i); 71655714Skris bagnid = OBJ_obj2nid (p7->type); 71755714Skris if (bagnid == NID_pkcs7_data) { 718109998Smarkm bags = PKCS12_unpack_p7data(p7); 71955714Skris if (options & INFO) BIO_printf (bio_err, "PKCS7 Data\n"); 72055714Skris } else if (bagnid == NID_pkcs7_encrypted) { 72155714Skris if (options & INFO) { 722109998Smarkm BIO_printf(bio_err, "PKCS7 Encrypted data: "); 723109998Smarkm alg_print(bio_err, 72455714Skris p7->d.encrypted->enc_data->algorithm); 72555714Skris } 726109998Smarkm bags = PKCS12_unpack_p7encdata(p7, pass, passlen); 72755714Skris } else continue; 728160814Ssimon if (!bags) goto err; 72955714Skris if (!dump_certs_pkeys_bags (out, bags, pass, passlen, 73059191Skris options, pempass)) { 73168651Skris sk_PKCS12_SAFEBAG_pop_free (bags, PKCS12_SAFEBAG_free); 732160814Ssimon goto err; 73355714Skris } 73468651Skris sk_PKCS12_SAFEBAG_pop_free (bags, PKCS12_SAFEBAG_free); 735160814Ssimon bags = NULL; 73655714Skris } 737160814Ssimon ret = 1; 738160814Ssimon 739160814Ssimon err: 740160814Ssimon 741160814Ssimon if (asafes) 742160814Ssimon sk_PKCS7_pop_free (asafes, PKCS7_free); 743160814Ssimon return ret; 74455714Skris} 74555714Skris 74668651Skrisint dump_certs_pkeys_bags (BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, 74768651Skris char *pass, int passlen, int options, char *pempass) 74855714Skris{ 74955714Skris int i; 75068651Skris for (i = 0; i < sk_PKCS12_SAFEBAG_num (bags); i++) { 75155714Skris if (!dump_certs_pkeys_bag (out, 75268651Skris sk_PKCS12_SAFEBAG_value (bags, i), 75368651Skris pass, passlen, 75468651Skris options, pempass)) 75568651Skris return 0; 75655714Skris } 75755714Skris return 1; 75855714Skris} 75955714Skris 76055714Skrisint dump_certs_pkeys_bag (BIO *out, PKCS12_SAFEBAG *bag, char *pass, 76159191Skris int passlen, int options, char *pempass) 76255714Skris{ 76355714Skris EVP_PKEY *pkey; 76455714Skris PKCS8_PRIV_KEY_INFO *p8; 76555714Skris X509 *x509; 76655714Skris 76755714Skris switch (M_PKCS12_bag_type(bag)) 76855714Skris { 76955714Skris case NID_keyBag: 77055714Skris if (options & INFO) BIO_printf (bio_err, "Key bag\n"); 77155714Skris if (options & NOKEYS) return 1; 77255714Skris print_attribs (out, bag->attrib, "Bag Attributes"); 77355714Skris p8 = bag->value.keybag; 77455714Skris if (!(pkey = EVP_PKCS82PKEY (p8))) return 0; 77555714Skris print_attribs (out, p8->attributes, "Key Attributes"); 77659191Skris PEM_write_bio_PrivateKey (out, pkey, enc, NULL, 0, NULL, pempass); 77755714Skris EVP_PKEY_free(pkey); 77855714Skris break; 77955714Skris 78055714Skris case NID_pkcs8ShroudedKeyBag: 78155714Skris if (options & INFO) { 78255714Skris BIO_printf (bio_err, "Shrouded Keybag: "); 78355714Skris alg_print (bio_err, bag->value.shkeybag->algor); 78455714Skris } 78555714Skris if (options & NOKEYS) return 1; 78655714Skris print_attribs (out, bag->attrib, "Bag Attributes"); 787109998Smarkm if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen))) 78855714Skris return 0; 789100928Snectar if (!(pkey = EVP_PKCS82PKEY (p8))) { 790100928Snectar PKCS8_PRIV_KEY_INFO_free(p8); 791100928Snectar return 0; 792100928Snectar } 79355714Skris print_attribs (out, p8->attributes, "Key Attributes"); 79455714Skris PKCS8_PRIV_KEY_INFO_free(p8); 79559191Skris PEM_write_bio_PrivateKey (out, pkey, enc, NULL, 0, NULL, pempass); 79655714Skris EVP_PKEY_free(pkey); 79755714Skris break; 79855714Skris 79955714Skris case NID_certBag: 80055714Skris if (options & INFO) BIO_printf (bio_err, "Certificate bag\n"); 80155714Skris if (options & NOCERTS) return 1; 80255714Skris if (PKCS12_get_attr(bag, NID_localKeyID)) { 80355714Skris if (options & CACERTS) return 1; 80455714Skris } else if (options & CLCERTS) return 1; 80555714Skris print_attribs (out, bag->attrib, "Bag Attributes"); 80655714Skris if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate ) 80755714Skris return 1; 808109998Smarkm if (!(x509 = PKCS12_certbag2x509(bag))) return 0; 80955714Skris dump_cert_text (out, x509); 81055714Skris PEM_write_bio_X509 (out, x509); 81155714Skris X509_free(x509); 81255714Skris break; 81355714Skris 81455714Skris case NID_safeContentsBag: 81555714Skris if (options & INFO) BIO_printf (bio_err, "Safe Contents bag\n"); 81655714Skris print_attribs (out, bag->attrib, "Bag Attributes"); 81755714Skris return dump_certs_pkeys_bags (out, bag->value.safes, pass, 81859191Skris passlen, options, pempass); 81955714Skris 82055714Skris default: 82155714Skris BIO_printf (bio_err, "Warning unsupported bag type: "); 82255714Skris i2a_ASN1_OBJECT (bio_err, bag->type); 82355714Skris BIO_printf (bio_err, "\n"); 82455714Skris return 1; 82555714Skris break; 82655714Skris } 82755714Skris return 1; 82855714Skris} 82955714Skris 83055714Skris/* Given a single certificate return a verified chain or NULL if error */ 83155714Skris 83255714Skris/* Hope this is OK .... */ 83355714Skris 83468651Skrisint get_cert_chain (X509 *cert, X509_STORE *store, STACK_OF(X509) **chain) 83555714Skris{ 83655714Skris X509_STORE_CTX store_ctx; 83755714Skris STACK_OF(X509) *chn; 838167612Ssimon int i = 0; 83959191Skris 840109998Smarkm /* FIXME: Should really check the return status of X509_STORE_CTX_init 841109998Smarkm * for an error, but how that fits into the return value of this 842109998Smarkm * function is less obvious. */ 84355714Skris X509_STORE_CTX_init(&store_ctx, store, cert, NULL); 84455714Skris if (X509_verify_cert(&store_ctx) <= 0) { 84555714Skris i = X509_STORE_CTX_get_error (&store_ctx); 846167612Ssimon if (i == 0) 847167612Ssimon /* avoid returning 0 if X509_verify_cert() did not 848167612Ssimon * set an appropriate error value in the context */ 849167612Ssimon i = -1; 850167612Ssimon chn = NULL; 85155714Skris goto err; 852167612Ssimon } else 853167612Ssimon chn = X509_STORE_CTX_get1_chain(&store_ctx); 85455714Skriserr: 85555714Skris X509_STORE_CTX_cleanup(&store_ctx); 856167612Ssimon *chain = chn; 85755714Skris 85855714Skris return i; 85955714Skris} 86055714Skris 86155714Skrisint alg_print (BIO *x, X509_ALGOR *alg) 86255714Skris{ 86355714Skris PBEPARAM *pbe; 864160814Ssimon const unsigned char *p; 86555714Skris p = alg->parameter->value.sequence->data; 866162911Ssimon pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length); 867162911Ssimon if (!pbe) 868162911Ssimon return 1; 869160814Ssimon BIO_printf (bio_err, "%s, Iteration %ld\n", 870160814Ssimon OBJ_nid2ln(OBJ_obj2nid(alg->algorithm)), 871160814Ssimon ASN1_INTEGER_get(pbe->iter)); 87255714Skris PBEPARAM_free (pbe); 873162911Ssimon return 1; 87455714Skris} 87555714Skris 87655714Skris/* Load all certificates from a given file */ 87755714Skris 87855714Skrisint cert_load(BIO *in, STACK_OF(X509) *sk) 87955714Skris{ 88055714Skris int ret; 88155714Skris X509 *cert; 88255714Skris ret = 0; 88368651Skris#ifdef CRYPTO_MDEBUG 88468651Skris CRYPTO_push_info("cert_load(): reading one cert"); 88568651Skris#endif 88655714Skris while((cert = PEM_read_bio_X509(in, NULL, NULL, NULL))) { 88768651Skris#ifdef CRYPTO_MDEBUG 88868651Skris CRYPTO_pop_info(); 88968651Skris#endif 89055714Skris ret = 1; 89155714Skris sk_X509_push(sk, cert); 89268651Skris#ifdef CRYPTO_MDEBUG 89368651Skris CRYPTO_push_info("cert_load(): reading one cert"); 89468651Skris#endif 89555714Skris } 89668651Skris#ifdef CRYPTO_MDEBUG 89768651Skris CRYPTO_pop_info(); 89868651Skris#endif 89955714Skris if(ret) ERR_clear_error(); 90055714Skris return ret; 90155714Skris} 90255714Skris 90355714Skris/* Generalised attribute print: handle PKCS#8 and bag attributes */ 90455714Skris 905160814Ssimonint print_attribs (BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,const char *name) 90655714Skris{ 90755714Skris X509_ATTRIBUTE *attr; 90855714Skris ASN1_TYPE *av; 90955714Skris char *value; 91055714Skris int i, attr_nid; 91155714Skris if(!attrlst) { 91255714Skris BIO_printf(out, "%s: <No Attributes>\n", name); 91355714Skris return 1; 91455714Skris } 91555714Skris if(!sk_X509_ATTRIBUTE_num(attrlst)) { 91655714Skris BIO_printf(out, "%s: <Empty Attributes>\n", name); 91755714Skris return 1; 91855714Skris } 91955714Skris BIO_printf(out, "%s\n", name); 92055714Skris for(i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) { 92155714Skris attr = sk_X509_ATTRIBUTE_value(attrlst, i); 92255714Skris attr_nid = OBJ_obj2nid(attr->object); 92355714Skris BIO_printf(out, " "); 92455714Skris if(attr_nid == NID_undef) { 92555714Skris i2a_ASN1_OBJECT (out, attr->object); 92655714Skris BIO_printf(out, ": "); 92755714Skris } else BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid)); 92855714Skris 92955714Skris if(sk_ASN1_TYPE_num(attr->value.set)) { 93055714Skris av = sk_ASN1_TYPE_value(attr->value.set, 0); 93155714Skris switch(av->type) { 93255714Skris case V_ASN1_BMPSTRING: 933238405Sjkim value = OPENSSL_uni2asc(av->value.bmpstring->data, 93455714Skris av->value.bmpstring->length); 93555714Skris BIO_printf(out, "%s\n", value); 93668651Skris OPENSSL_free(value); 93755714Skris break; 93855714Skris 93955714Skris case V_ASN1_OCTET_STRING: 94068651Skris hex_prin(out, av->value.octet_string->data, 94168651Skris av->value.octet_string->length); 94255714Skris BIO_printf(out, "\n"); 94355714Skris break; 94455714Skris 94555714Skris case V_ASN1_BIT_STRING: 94668651Skris hex_prin(out, av->value.bit_string->data, 94768651Skris av->value.bit_string->length); 94855714Skris BIO_printf(out, "\n"); 94955714Skris break; 95055714Skris 95155714Skris default: 95255714Skris BIO_printf(out, "<Unsupported tag %d>\n", av->type); 95355714Skris break; 95455714Skris } 95555714Skris } else BIO_printf(out, "<No Values>\n"); 95655714Skris } 95755714Skris return 1; 95855714Skris} 95955714Skris 96055714Skrisvoid hex_prin(BIO *out, unsigned char *buf, int len) 96155714Skris{ 96255714Skris int i; 96355714Skris for (i = 0; i < len; i++) BIO_printf (out, "%02X ", buf[i]); 96455714Skris} 96555714Skris 966238405Sjkimstatic int set_pbe(BIO *err, int *ppbe, const char *str) 967238405Sjkim { 968238405Sjkim if (!str) 969238405Sjkim return 0; 970238405Sjkim if (!strcmp(str, "NONE")) 971238405Sjkim { 972238405Sjkim *ppbe = -1; 973238405Sjkim return 1; 974238405Sjkim } 975238405Sjkim *ppbe=OBJ_txt2nid(str); 976238405Sjkim if (*ppbe == NID_undef) 977238405Sjkim { 978238405Sjkim BIO_printf(bio_err, "Unknown PBE algorithm %s\n", str); 979238405Sjkim return 0; 980238405Sjkim } 981238405Sjkim return 1; 982238405Sjkim } 983238405Sjkim 98455714Skris#endif 985