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