smime.c 18.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
/* smime.c */
/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
 * project 1999.
 */
/* ====================================================================
 * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

/* S/MIME utility function */

#include <stdio.h>
#include <string.h>
63
#include "apps.h"
64
#include <openssl/crypto.h>
65 66 67 68 69 70
#include <openssl/pem.h>
#include <openssl/err.h>

#undef PROG
#define PROG smime_main
static X509 *load_cert(char *file);
71
static EVP_PKEY *load_key(char *file, char *pass);
72 73
static STACK_OF(X509) *load_certs(char *file);
static X509_STORE *setup_verify(char *CAfile, char *CApath);
74
static int save_certs(char *signerfile, STACK_OF(X509) *signers);
75 76 77 78 79 80 81 82

#define SMIME_OP	0x10
#define SMIME_ENCRYPT	(1 | SMIME_OP)
#define SMIME_DECRYPT	2
#define SMIME_SIGN	(3 | SMIME_OP)
#define SMIME_VERIFY	4
#define SMIME_PK7OUT	5

83 84
int MAIN(int, char **);

85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
int MAIN(int argc, char **argv)
{
	int operation = 0;
	int ret = 0;
	char **args;
	char *inmode = "r", *outmode = "w";
	char *infile = NULL, *outfile = NULL;
	char *signerfile = NULL, *recipfile = NULL;
	char *certfile = NULL, *keyfile = NULL;
	EVP_CIPHER *cipher = NULL;
	PKCS7 *p7 = NULL;
	X509_STORE *store = NULL;
	X509 *cert = NULL, *recip = NULL, *signer = NULL;
	EVP_PKEY *key = NULL;
	STACK_OF(X509) *encerts = NULL, *other = NULL;
	BIO *in = NULL, *out = NULL, *indata = NULL;
	int badarg = 0;
	int flags = PKCS7_DETACHED;
	char *to = NULL, *from = NULL, *subject = NULL;
D
Dr. Stephen Henson 已提交
104 105
	char *CAfile = NULL, *CApath = NULL;
	char *passargin = NULL, *passin = NULL;
106 107
	char *inrand = NULL;
	int need_rand = 0;
108 109 110 111 112 113 114 115 116 117
	args = argv + 1;

	ret = 1;

	while (!badarg && *args && *args[0] == '-') {
		if (!strcmp (*args, "-encrypt")) operation = SMIME_ENCRYPT;
		else if (!strcmp (*args, "-decrypt")) operation = SMIME_DECRYPT;
		else if (!strcmp (*args, "-sign")) operation = SMIME_SIGN;
		else if (!strcmp (*args, "-verify")) operation = SMIME_VERIFY;
		else if (!strcmp (*args, "-pk7out")) operation = SMIME_PK7OUT;
B
Bodo Möller 已提交
118
#ifndef NO_DES
119 120 121 122
		else if (!strcmp (*args, "-des3")) 
				cipher = EVP_des_ede3_cbc();
		else if (!strcmp (*args, "-des")) 
				cipher = EVP_des_cbc();
B
Bodo Möller 已提交
123 124
#endif
#ifndef NO_RC2
125 126 127 128 129 130
		else if (!strcmp (*args, "-rc2-40")) 
				cipher = EVP_rc2_40_cbc();
		else if (!strcmp (*args, "-rc2-128")) 
				cipher = EVP_rc2_cbc();
		else if (!strcmp (*args, "-rc2-64")) 
				cipher = EVP_rc2_64_cbc();
B
Bodo Möller 已提交
131
#endif
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
		else if (!strcmp (*args, "-text")) 
				flags |= PKCS7_TEXT;
		else if (!strcmp (*args, "-nointern")) 
				flags |= PKCS7_NOINTERN;
		else if (!strcmp (*args, "-noverify")) 
				flags |= PKCS7_NOVERIFY;
		else if (!strcmp (*args, "-nochain")) 
				flags |= PKCS7_NOCHAIN;
		else if (!strcmp (*args, "-nocerts")) 
				flags |= PKCS7_NOCERTS;
		else if (!strcmp (*args, "-noattr")) 
				flags |= PKCS7_NOATTR;
		else if (!strcmp (*args, "-nodetach")) 
				flags &= ~PKCS7_DETACHED;
		else if (!strcmp (*args, "-binary"))
				flags |= PKCS7_BINARY;
148 149
		else if (!strcmp (*args, "-nosigs"))
				flags |= PKCS7_NOSIGS;
150 151 152 153 154 155 156 157 158
		else if (!strcmp(*args,"-rand")) {
			if (args[1]) {
				args++;
				inrand = *args;
			} else badarg = 1;
			need_rand = 1;
		} else if (!strcmp(*args,"-passin")) {
			if (args[1]) {
				args++;
D
Dr. Stephen Henson 已提交
159
				passargin = *args;
160
			} else badarg = 1;
161
		} else if (!strcmp (*args, "-to")) {
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
			if (args[1]) {
				args++;
				to = *args;
			} else badarg = 1;
		} else if (!strcmp (*args, "-from")) {
			if (args[1]) {
				args++;
				from = *args;
			} else badarg = 1;
		} else if (!strcmp (*args, "-subject")) {
			if (args[1]) {
				args++;
				subject = *args;
			} else badarg = 1;
		} else if (!strcmp (*args, "-signer")) {
			if (args[1]) {
				args++;
				signerfile = *args;
			} else badarg = 1;
		} else if (!strcmp (*args, "-recip")) {
			if (args[1]) {
				args++;
				recipfile = *args;
			} else badarg = 1;
		} else if (!strcmp (*args, "-inkey")) {
			if (args[1]) {
				args++;
				keyfile = *args;
			} else badarg = 1;
		} else if (!strcmp (*args, "-certfile")) {
			if (args[1]) {
				args++;
				certfile = *args;
			} else badarg = 1;
		} else if (!strcmp (*args, "-CAfile")) {
			if (args[1]) {
				args++;
				CAfile = *args;
			} else badarg = 1;
		} else if (!strcmp (*args, "-CApath")) {
			if (args[1]) {
				args++;
				CApath = *args;
			} else badarg = 1;
		} else if (!strcmp (*args, "-in")) {
			if (args[1]) {
				args++;
				infile = *args;
			} else badarg = 1;
		} else if (!strcmp (*args, "-out")) {
			if (args[1]) {
				args++;
				outfile = *args;
			} else badarg = 1;
		} else badarg = 1;
		args++;
	}

	if(operation == SMIME_SIGN) {
		if(!signerfile) {
			BIO_printf(bio_err, "No signer certificate specified\n");
			badarg = 1;
		}
225
		need_rand = 1;
226 227 228 229 230 231 232 233 234 235
	} else if(operation == SMIME_DECRYPT) {
		if(!recipfile) {
			BIO_printf(bio_err, "No recipient certificate and key specified\n");
			badarg = 1;
		}
	} else if(operation == SMIME_ENCRYPT) {
		if(!*args) {
			BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");
			badarg = 1;
		}
236
		need_rand = 1;
237 238 239 240 241 242 243 244 245 246
	} else if(!operation) badarg = 1;

	if (badarg) {
		BIO_printf (bio_err, "Usage smime [options] cert.pem ...\n");
		BIO_printf (bio_err, "where options are\n");
		BIO_printf (bio_err, "-encrypt       encrypt message\n");
		BIO_printf (bio_err, "-decrypt       decrypt encrypted message\n");
		BIO_printf (bio_err, "-sign          sign message\n");
		BIO_printf (bio_err, "-verify        verify signed message\n");
		BIO_printf (bio_err, "-pk7out        output PKCS#7 structure\n");
B
Bodo Möller 已提交
247
#ifndef NO_DES
248
		BIO_printf (bio_err, "-des3          encrypt with triple DES\n");
B
Bodo Möller 已提交
249 250 251 252
		BIO_printf (bio_err, "-des           encrypt with DES\n");
#endif
#ifndef NO_RC2
		BIO_printf (bio_err, "-rc2-40        encrypt with RC2-40 (default)\n");
253 254
		BIO_printf (bio_err, "-rc2-64        encrypt with RC2-64\n");
		BIO_printf (bio_err, "-rc2-128       encrypt with RC2-128\n");
B
Bodo Möller 已提交
255
#endif
256 257 258 259 260 261 262
		BIO_printf (bio_err, "-nointern      don't search certificates in message for signer\n");
		BIO_printf (bio_err, "-nosigs        don't verify message signature\n");
		BIO_printf (bio_err, "-noverify      don't verify signers certificate\n");
		BIO_printf (bio_err, "-nocerts       don't include signers certificate when signing\n");
		BIO_printf (bio_err, "-nodetach      use opaque signing\n");
		BIO_printf (bio_err, "-noattr        don't include any signed attributes\n");
		BIO_printf (bio_err, "-binary        don't translate message to text\n");
263 264
		BIO_printf (bio_err, "-certfile file other certificates file\n");
		BIO_printf (bio_err, "-signer file   signer certificate file\n");
B
Bodo Möller 已提交
265
		BIO_printf (bio_err, "-recip  file   recipient certificate file for decryption\n");
266 267 268 269 270 271 272
		BIO_printf (bio_err, "-in file       input file\n");
		BIO_printf (bio_err, "-inkey file    input private key (if not signer or recipient)\n");
		BIO_printf (bio_err, "-out file      output file\n");
		BIO_printf (bio_err, "-to addr       to address\n");
		BIO_printf (bio_err, "-from ad       from address\n");
		BIO_printf (bio_err, "-subject s     subject\n");
		BIO_printf (bio_err, "-text          include or delete text MIME headers\n");
273 274
		BIO_printf (bio_err, "-CApath dir    trusted certificates directory\n");
		BIO_printf (bio_err, "-CAfile file   trusted certificates file\n");
275 276 277
		BIO_printf(bio_err,  "-rand file:file:...\n");
		BIO_printf(bio_err,  "               load the file (or the files in the directory) into\n");
		BIO_printf(bio_err,  "               the random number generator\n");
B
Bodo Möller 已提交
278
		BIO_printf (bio_err, "cert.pem       recipient certificate(s) for encryption\n");
279 280 281
		goto end;
	}

D
Dr. Stephen Henson 已提交
282 283 284 285 286
	if(!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
		BIO_printf(bio_err, "Error getting password\n");
		goto end;
	}

287 288 289 290 291 292 293
	if (need_rand) {
		app_RAND_load_file(NULL, bio_err, (inrand != NULL));
		if (inrand != NULL)
			BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
				app_RAND_load_files(inrand));
	}

294 295 296 297 298 299 300 301 302 303
	ret = 2;

	if(operation != SMIME_SIGN) flags &= ~PKCS7_DETACHED;

	if(flags & PKCS7_BINARY) {
		if(operation & SMIME_OP) inmode = "rb";
		else outmode = "rb";
	}

	if(operation == SMIME_ENCRYPT) {
B
Bodo Möller 已提交
304 305 306 307 308 309 310 311
		if (!cipher) {
#ifndef NO_RC2			
			cipher = EVP_rc2_40_cbc();
#else
			BIO_printf(bio_err, "No cipher selected\n");
			goto end;
#endif
		}
312 313 314
#ifdef CRYPTO_MDEBUG
		CRYPTO_push_info("load encryption certificates");
#endif		
315
		encerts = sk_X509_new_null();
316 317
		while (*args) {
			if(!(cert = load_cert(*args))) {
U
Ulf Möller 已提交
318
				BIO_printf(bio_err, "Can't read recipient certificate file %s\n", *args);
319 320
				goto end;
			}
321
			sk_X509_push(encerts, cert);
322 323 324
			cert = NULL;
			args++;
		}
325 326 327
#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
#endif		
328 329
	}

330
	if(signerfile && (operation == SMIME_SIGN)) {
331 332 333
#ifdef CRYPTO_MDEBUG
		CRYPTO_push_info("load signer certificate");
#endif		
334 335 336 337
		if(!(signer = load_cert(signerfile))) {
			BIO_printf(bio_err, "Can't read signer certificate file %s\n", signerfile);
			goto end;
		}
338 339 340
#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
#endif		
341 342 343
	}

	if(certfile) {
344 345 346
#ifdef CRYPTO_MDEBUG
		CRYPTO_push_info("load other certfiles");
#endif		
347 348 349 350 351
		if(!(other = load_certs(certfile))) {
			BIO_printf(bio_err, "Can't read certificate file %s\n", certfile);
			ERR_print_errors(bio_err);
			goto end;
		}
352 353 354
#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
#endif		
355 356
	}

357
	if(recipfile && (operation == SMIME_DECRYPT)) {
358 359 360
#ifdef CRYPTO_MDEBUG
		CRYPTO_push_info("load recipient certificate");
#endif		
361 362 363 364 365
		if(!(recip = load_cert(recipfile))) {
			BIO_printf(bio_err, "Can't read recipient certificate file %s\n", recipfile);
			ERR_print_errors(bio_err);
			goto end;
		}
366 367 368
#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
#endif		
369 370 371 372 373 374 375 376 377
	}

	if(operation == SMIME_DECRYPT) {
		if(!keyfile) keyfile = recipfile;
	} else if(operation == SMIME_SIGN) {
		if(!keyfile) keyfile = signerfile;
	} else keyfile = NULL;

	if(keyfile) {
378 379 380
#ifdef CRYPTO_MDEBUG
		CRYPTO_push_info("load keyfile");
#endif		
381
		if(!(key = load_key(keyfile, passin))) {
382 383 384 385
			BIO_printf(bio_err, "Can't read recipient certificate file %s\n", keyfile);
			ERR_print_errors(bio_err);
			goto end;
		}
386 387 388
#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
#endif		
389 390
	}

391 392 393
#ifdef CRYPTO_MDEBUG
	CRYPTO_push_info("open input files");
#endif		
394 395 396 397 398 399 400
	if (infile) {
		if (!(in = BIO_new_file(infile, inmode))) {
			BIO_printf (bio_err,
				 "Can't open input file %s\n", infile);
			goto end;
		}
	} else in = BIO_new_fp(stdin, BIO_NOCLOSE);
401 402 403
#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
#endif		
404

405 406 407
#ifdef CRYPTO_MDEBUG
	CRYPTO_push_info("open output files");
#endif		
408 409 410 411 412 413 414
	if (outfile) {
		if (!(out = BIO_new_file(outfile, outmode))) {
			BIO_printf (bio_err,
				 "Can't open output file %s\n", outfile);
			goto end;
		}
	} else out = BIO_new_fp(stdout, BIO_NOCLOSE);
415 416 417 418 419 420 421 422
#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
#endif		

	if(operation == SMIME_VERIFY) {
#ifdef CRYPTO_MDEBUG
		CRYPTO_push_info("setup_verify");
#endif		
423
		if(!(store = setup_verify(CAfile, CApath))) goto end;
424 425 426 427
#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
#endif		
	}
428 429

	ret = 3;
430

431
	if(operation == SMIME_ENCRYPT) {
432 433 434
#ifdef CRYPTO_MDEBUG
		CRYPTO_push_info("PKCS7_encrypt");
#endif		
435
		p7 = PKCS7_encrypt(encerts, in, cipher, flags);
436 437 438
#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
#endif		
439
	} else if(operation == SMIME_SIGN) {
440 441 442
#ifdef CRYPTO_MDEBUG
		CRYPTO_push_info("PKCS7_sign");
#endif		
443 444
		p7 = PKCS7_sign(signer, key, other, in, flags);
		BIO_reset(in);
445 446 447
#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
#endif		
448
	} else {
449 450 451
#ifdef CRYPTO_MDEBUG
		CRYPTO_push_info("SMIME_read_PKCS7");
#endif		
452 453 454 455
		if(!(p7 = SMIME_read_PKCS7(in, &indata))) {
			BIO_printf(bio_err, "Error reading S/MIME message\n");
			goto end;
		}
456 457 458
#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
#endif		
459
	}
460

461 462 463 464 465
	if(!p7) {
		BIO_printf(bio_err, "Error creating PKCS#7 structure\n");
		goto end;
	}

466
	ret = 4;
467
	if(operation == SMIME_DECRYPT) {
468 469 470
#ifdef CRYPTO_MDEBUG
		CRYPTO_push_info("PKCS7_decrypt");
#endif		
471
		if(!PKCS7_decrypt(p7, key, recip, out, flags)) {
472
			BIO_printf(bio_err, "Error decrypting PKCS#7 structure\n");
473 474
			goto end;
		}
475 476 477
#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
#endif		
478
	} else if(operation == SMIME_VERIFY) {
479
		STACK_OF(X509) *signers;
480 481 482
#ifdef CRYPTO_MDEBUG
		CRYPTO_push_info("PKCS7_verify");
#endif		
483 484 485 486
		if(PKCS7_verify(p7, other, store, indata, out, flags)) {
			BIO_printf(bio_err, "Verification Successful\n");
		} else {
			BIO_printf(bio_err, "Verification Failure\n");
487
			goto end;
488
		}
489 490
#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
491
		CRYPTO_push_info("PKCS7_get0_signers");
492
#endif		
493
		signers = PKCS7_get0_signers(p7, other, flags);
494 495 496 497
#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
		CRYPTO_push_info("save_certs");
#endif		
498 499 500
		if(!save_certs(signerfile, signers)) {
			BIO_printf(bio_err, "Error writing signers to %s\n",
								signerfile);
501 502
			ret = 5;
			goto end;
503
		}
504 505 506
#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
#endif		
507
		sk_X509_free(signers);
508 509 510 511 512 513 514 515
	} else if(operation == SMIME_PK7OUT) {
		PEM_write_bio_PKCS7(out, p7);
	} else {
		if(to) BIO_printf(out, "To: %s\n", to);
		if(from) BIO_printf(out, "From: %s\n", from);
		if(subject) BIO_printf(out, "Subject: %s\n", subject);
		SMIME_write_PKCS7(out, p7, in, flags);
	}
516
	ret = 0;
517
end:
518 519 520
#ifdef CRYPTO_MDEBUG
	CRYPTO_remove_all_info();
#endif
521 522
	if (need_rand)
		app_RAND_write_file(NULL, bio_err);
523 524 525 526 527 528 529 530 531 532 533 534
	if(ret) ERR_print_errors(bio_err);
	sk_X509_pop_free(encerts, X509_free);
	sk_X509_pop_free(other, X509_free);
	X509_STORE_free(store);
	X509_free(cert);
	X509_free(recip);
	X509_free(signer);
	EVP_PKEY_free(key);
	PKCS7_free(p7);
	BIO_free(in);
	BIO_free(indata);
	BIO_free(out);
D
Dr. Stephen Henson 已提交
535
	if(passin) Free(passin);
536 537 538 539 540 541 542 543 544 545 546 547 548
	return (ret);
}

static X509 *load_cert(char *file)
{
	BIO *in;
	X509 *cert;
	if(!(in = BIO_new_file(file, "r"))) return NULL;
	cert = PEM_read_bio_X509(in, NULL, NULL,NULL);
	BIO_free(in);
	return cert;
}

549
static EVP_PKEY *load_key(char *file, char *pass)
550 551 552 553
{
	BIO *in;
	EVP_PKEY *key;
	if(!(in = BIO_new_file(file, "r"))) return NULL;
D
Dr. Stephen Henson 已提交
554
	key = PEM_read_bio_PrivateKey(in, NULL,NULL,pass);
555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585
	BIO_free(in);
	return key;
}

static STACK_OF(X509) *load_certs(char *file)
{
	BIO *in;
	int i;
	STACK_OF(X509) *othercerts;
	STACK_OF(X509_INFO) *allcerts;
	X509_INFO *xi;
	if(!(in = BIO_new_file(file, "r"))) return NULL;
	othercerts = sk_X509_new(NULL);
	if(!othercerts) return NULL;
	allcerts = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
	for(i = 0; i < sk_X509_INFO_num(allcerts); i++) {
		xi = sk_X509_INFO_value (allcerts, i);
		if (xi->x509) {
			sk_X509_push(othercerts, xi->x509);
			xi->x509 = NULL;
		}
	}
	sk_X509_INFO_pop_free(allcerts, X509_INFO_free);
	BIO_free(in);
	return othercerts;
}

static X509_STORE *setup_verify(char *CAfile, char *CApath)
{
	X509_STORE *store;
	X509_LOOKUP *lookup;
586 587 588
#ifdef CRYPTO_MDEBUG
	CRYPTO_push_info("X509_STORE_new");
#endif	
589
	if(!(store = X509_STORE_new())) goto end;
590 591 592 593
#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("X509_STORE_add_lookup(...file)");
#endif	
594 595
	lookup=X509_STORE_add_lookup(store,X509_LOOKUP_file());
	if (lookup == NULL) goto end;
596 597 598 599
#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("X509_LOOKUP_load_file");
#endif	
600 601 602 603 604 605 606
	if (CAfile) {
		if(!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM)) {
			BIO_printf(bio_err, "Error loading file %s\n", CAfile);
			goto end;
		}
	} else X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);
		
607 608 609 610
#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("X509_STORE_add_lookup(...hash_dir)");
#endif	
611 612
	lookup=X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir());
	if (lookup == NULL) goto end;
613 614 615 616
#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("X509_LOOKUP_add_dir");
#endif	
617 618 619 620 621 622
	if (CApath) {
		if(!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM)) {
			BIO_printf(bio_err, "Error loading directory %s\n", CApath);
			goto end;
		}
	} else X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
623 624 625
#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
#endif	
626 627 628 629 630 631 632

	ERR_clear_error();
	return store;
	end:
	X509_STORE_free(store);
	return NULL;
}
633

B
Bodo Möller 已提交
634
static int save_certs(char *signerfile, STACK_OF(X509) *signers)
635 636 637 638 639 640 641 642 643 644 645 646
{
	int i;
	BIO *tmp;
	if(!signerfile) return 1;
	tmp = BIO_new_file(signerfile, "w");
	if(!tmp) return 0;
	for(i = 0; i < sk_X509_num(signers); i++)
		PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
	BIO_free(tmp);
	return 1;
}