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