Commit 245d2ee3 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Add option to allow in-band CRL loading in verify utility. Add function

load_crls and tidy up load_certs. Remove useless purpose variable from
verify utility: now done with args_verify.
parent 4b4ba6a8
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -4,6 +4,10 @@

 Changes between 0.9.8k and 1.0  [xx XXX xxxx]

  *) Add load_crls() function to apps tidying load_certs() too. Add option
     to verify utility to allow additional CRLs to be included.
     [Steve Henson]

  *) Update OCSP request code to permit adding custom headers to the request:
     some responders need this.
     [Steve Henson]
+86 −42
Original line number Diff line number Diff line
@@ -1095,76 +1095,120 @@ error:
	}
#endif /* ndef OPENSSL_NO_RC4 */

STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
	const char *pass, ENGINE *e, const char *cert_descrip)
static int load_certs_crls(BIO *err, const char *file, int format,
	const char *pass, ENGINE *e, const char *desc,
	STACK_OF(X509) **pcerts, STACK_OF(X509_CRL) **pcrls)
	{
	BIO *certs;
	int i;
	STACK_OF(X509) *othercerts = NULL;
	STACK_OF(X509_INFO) *allcerts = NULL;
	BIO *bio;
	STACK_OF(X509_INFO) *xis = NULL;
	X509_INFO *xi;
	PW_CB_DATA cb_data;
	int rv = 0;

	cb_data.password = pass;
	cb_data.prompt_info = file;

	if((certs = BIO_new(BIO_s_file())) == NULL)
	if (format != FORMAT_PEM)
		{
		ERR_print_errors(err);
		goto end;
		BIO_printf(err,"bad input format specified for %s\n", desc);
		return 0;
		}

	if (file == NULL)
		BIO_set_fp(certs,stdin,BIO_NOCLOSE);
		bio = BIO_new_fp(stdin,BIO_NOCLOSE);
	else
		{
		if (BIO_read_filename(certs,file) <= 0)
		bio = BIO_new_file(file, "r");

	if (bio == NULL)
		{
		BIO_printf(err, "Error opening %s %s\n",
				cert_descrip, file);
				desc, file ? file : "stdin");
		ERR_print_errors(err);
			goto end;
			}
		return 0;
		}

	if      (format == FORMAT_PEM)
	xis = PEM_X509_INFO_read_bio(bio, NULL,
				(pem_password_cb *)password_callback, &cb_data);

	BIO_free(bio);

	if (pcerts)
		{
		othercerts = sk_X509_new_null();
		if(!othercerts)
		*pcerts = sk_X509_new_null();
		if (!*pcerts)
			goto end;
		}

	if (pcrls)
		{
			sk_X509_free(othercerts);
			othercerts = NULL;
		*pcrls = sk_X509_CRL_new_null();
		if (!*pcrls)
			goto end;
		}
		allcerts = PEM_X509_INFO_read_bio(certs, NULL,
				(pem_password_cb *)password_callback, &cb_data);
		for(i = 0; i < sk_X509_INFO_num(allcerts); i++)

	for(i = 0; i < sk_X509_INFO_num(xis); i++)
		{
			xi = sk_X509_INFO_value (allcerts, i);
			if (xi->x509)
		xi = sk_X509_INFO_value (xis, i);
		if (xi->x509 && pcerts)
			{
				sk_X509_push(othercerts, xi->x509);
			if (!sk_X509_push(*pcerts, xi->x509))
				goto end;
			xi->x509 = NULL;
			}
			}
		if (xi->crl && pcrls)
			{
			if (!sk_X509_CRL_push(*pcrls, xi->crl))
				goto end;
			xi->crl = NULL;
			}
	else	{
		BIO_printf(err,"bad input format specified for %s\n",
			cert_descrip);
		goto end;
		}

	if (pcerts && sk_X509_num(*pcerts) > 0)
		rv = 1;

	if (pcrls && sk_X509_CRL_num(*pcrls) > 0)
		rv = 1;

	end:
	if (othercerts == NULL)

	if (xis)
		sk_X509_INFO_pop_free(xis, X509_INFO_free);

	if (rv == 0)
		{
		if (pcerts)
			{
		BIO_printf(err,"unable to load certificates\n");
			sk_X509_pop_free(*pcerts, X509_free);
			*pcerts = NULL;
			}
		if (pcrls)
			{
			sk_X509_CRL_pop_free(*pcrls, X509_CRL_free);
			*pcrls = NULL;
			}
		BIO_printf(err,"unable to load %s\n",
				pcerts ? "certificates" : "CRLs");
		ERR_print_errors(err);
		}
	if (allcerts) sk_X509_INFO_pop_free(allcerts, X509_INFO_free);
	if (certs != NULL) BIO_free(certs);
	return(othercerts);
	return rv;
	}

STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
	const char *pass, ENGINE *e, const char *desc)
	{
	STACK_OF(X509) *certs;
	load_certs_crls(err, file, format, pass, e, desc, &certs, NULL);
	return certs;
	}	

STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format,
	const char *pass, ENGINE *e, const char *desc)
	{
	STACK_OF(X509_CRL) *crls;
	load_certs_crls(err, file, format, pass, e, desc, NULL, &crls);
	return crls;
	}	

#define X509V3_EXT_UNKNOWN_MASK		(0xfL << 16)
/* Return error for unknown extensions */
+2 −0
Original line number Diff line number Diff line
@@ -251,6 +251,8 @@ EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin,
	const char *pass, ENGINE *e, const char *key_descrip);
STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
	const char *pass, ENGINE *e, const char *cert_descrip);
STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format,
	const char *pass, ENGINE *e, const char *cert_descrip);
X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath);
#ifndef OPENSSL_NO_ENGINE
ENGINE *setup_engine(BIO *err, const char *engine, int debug);
+36 −64
Original line number Diff line number Diff line
@@ -70,8 +70,9 @@
#define PROG	verify_main

static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx);
static int check(X509_STORE *ctx, char *file, STACK_OF(X509) *uchain, STACK_OF(X509) *tchain, int purpose, ENGINE *e);
static STACK_OF(X509) *load_untrusted(char *file);
static int check(X509_STORE *ctx, char *file,
		STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
		STACK_OF(X509_CRL) *crls, ENGINE *e);
static int v_verbose=0, vflags = 0;

int MAIN(int, char **);
@@ -80,10 +81,10 @@ int MAIN(int argc, char **argv)
	{
	ENGINE *e = NULL;
	int i,ret=1, badarg = 0;
	int purpose = -1;
	char *CApath=NULL,*CAfile=NULL;
	char *untfile = NULL, *trustfile = NULL;
	char *untfile = NULL, *trustfile = NULL, *crlfile = NULL;
	STACK_OF(X509) *untrusted = NULL, *trusted = NULL;
	STACK_OF(X509_CRL) *crls = NULL;
	X509_STORE *cert_ctx=NULL;
	X509_LOOKUP *lookup=NULL;
	X509_VERIFY_PARAM *vpm = NULL;
@@ -139,6 +140,11 @@ int MAIN(int argc, char **argv)
				if (argc-- < 1) goto end;
				trustfile= *(++argv);
				}
			else if (strcmp(*argv,"-CRLfile") == 0)
				{
				if (argc-- < 1) goto end;
				crlfile= *(++argv);
				}
#ifndef OPENSSL_NO_ENGINE
			else if (strcmp(*argv,"-engine") == 0)
				{
@@ -192,26 +198,34 @@ int MAIN(int argc, char **argv)

	ERR_clear_error();

	if(untfile) {
		if(!(untrusted = load_untrusted(untfile))) {
			BIO_printf(bio_err, "Error loading untrusted file %s\n", untfile);
			ERR_print_errors(bio_err);
	if(untfile)
		{
		untrusted = load_certs(bio_err, untfile, FORMAT_PEM,
					NULL, e, "untrusted certificates");
		if(!untrusted)
			goto end;
		}
	}

	if(trustfile) {
		if(!(trusted = load_untrusted(trustfile))) {
			BIO_printf(bio_err, "Error loading untrusted file %s\n", trustfile);
			ERR_print_errors(bio_err);
	if(trustfile)
		{
		trusted = load_certs(bio_err, trustfile, FORMAT_PEM,
					NULL, e, "trusted certificates");
		if(!trusted)
			goto end;
		}

	if(crlfile)
		{
		crls = load_crls(bio_err, crlfile, FORMAT_PEM,
					NULL, e, "other CRLs");
		if(!crls)
			goto end;
		}

	if (argc < 1) check(cert_ctx, NULL, untrusted, trusted, purpose, e);
	if (argc < 1) check(cert_ctx, NULL, untrusted, trusted, crls, e);
	else
		for (i=0; i<argc; i++)
			check(cert_ctx,argv[i], untrusted, trusted, purpose, e);
			check(cert_ctx,argv[i], untrusted, trusted, crls, e);
	ret=0;
end:
	if (ret == 1) {
@@ -232,11 +246,14 @@ end:
	if (cert_ctx != NULL) X509_STORE_free(cert_ctx);
	sk_X509_pop_free(untrusted, X509_free);
	sk_X509_pop_free(trusted, X509_free);
	sk_X509_CRL_pop_free(crls, X509_CRL_free);
	apps_shutdown();
	OPENSSL_EXIT(ret);
	}

static int check(X509_STORE *ctx, char *file, STACK_OF(X509) *uchain, STACK_OF(X509) *tchain, int purpose, ENGINE *e)
static int check(X509_STORE *ctx, char *file,
		STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
		STACK_OF(X509_CRL) *crls, ENGINE *e)
	{
	X509 *x=NULL;
	int i=0,ret=0;
@@ -260,7 +277,8 @@ static int check(X509_STORE *ctx, char *file, STACK_OF(X509) *uchain, STACK_OF(X
		goto end;
		}
	if(tchain) X509_STORE_CTX_trusted_stack(csc, tchain);
	if(purpose >= 0) X509_STORE_CTX_set_purpose(csc, purpose);
	if (crls)
		X509_STORE_CTX_set0_crls(csc, crls);
	i=X509_verify_cert(csc);
	X509_STORE_CTX_free(csc);

@@ -278,52 +296,6 @@ end:
	return(ret);
	}

static STACK_OF(X509) *load_untrusted(char *certfile)
{
	STACK_OF(X509_INFO) *sk=NULL;
	STACK_OF(X509) *stack=NULL, *ret=NULL;
	BIO *in=NULL;
	X509_INFO *xi;

	if(!(stack = sk_X509_new_null())) {
		BIO_printf(bio_err,"memory allocation failure\n");
		goto end;
	}

	if(!(in=BIO_new_file(certfile, "r"))) {
		BIO_printf(bio_err,"error opening the file, %s\n",certfile);
		goto end;
	}

	/* This loads from a file, a stack of x509/crl/pkey sets */
	if(!(sk=PEM_X509_INFO_read_bio(in,NULL,NULL,NULL))) {
		BIO_printf(bio_err,"error reading the file, %s\n",certfile);
		goto end;
	}

	/* scan over it and pull out the certs */
	while (sk_X509_INFO_num(sk))
		{
		xi=sk_X509_INFO_shift(sk);
		if (xi->x509 != NULL)
			{
			sk_X509_push(stack,xi->x509);
			xi->x509=NULL;
			}
		X509_INFO_free(xi);
		}
	if(!sk_X509_num(stack)) {
		BIO_printf(bio_err,"no certificates in file, %s\n",certfile);
		sk_X509_free(stack);
		goto end;
	}
	ret=stack;
end:
	BIO_free(in);
	sk_X509_INFO_free(sk);
	return(ret);
	}

static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx)
	{
	int cert_error = X509_STORE_CTX_get_error(ctx);