/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * 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 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 acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS 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 AUTHOR OR 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.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.] */

#include <string.h>
#include <time.h>

#include <openssl/asn1.h>
#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/lhash.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/thread.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>

#include "vpm_int.h"
#include "../internal.h"


static CRYPTO_EX_DATA_CLASS g_ex_data_class =
	CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;

/* CRL score values */

/* No unhandled critical extensions */

#define CRL_SCORE_NOCRITICAL	0x100

/* certificate is within CRL scope */

#define CRL_SCORE_SCOPE		0x080

/* CRL times valid */

#define CRL_SCORE_TIME		0x040

/* Issuer name matches certificate */

#define CRL_SCORE_ISSUER_NAME	0x020

/* If this score or above CRL is probably valid */

#define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE)

/* CRL issuer is certificate issuer */

#define CRL_SCORE_ISSUER_CERT	0x018

/* CRL issuer is on certificate path */

#define CRL_SCORE_SAME_PATH	0x008

/* CRL issuer matches CRL AKID */

#define CRL_SCORE_AKID		0x004

/* Have a delta CRL with valid times */

#define CRL_SCORE_TIME_DELTA	0x002

static int null_callback(int ok,X509_STORE_CTX *e);
static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x);
static int check_chain_extensions(X509_STORE_CTX *ctx);
static int check_name_constraints(X509_STORE_CTX *ctx);
static int check_id(X509_STORE_CTX *ctx);
static int check_trust(X509_STORE_CTX *ctx);
static int check_revocation(X509_STORE_CTX *ctx);
static int check_cert(X509_STORE_CTX *ctx);
static int check_policy(X509_STORE_CTX *ctx);

static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
			unsigned int *preasons,
			X509_CRL *crl, X509 *x);
static int get_crl_delta(X509_STORE_CTX *ctx,
				X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x);
static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pcrl_score,
			X509_CRL *base, STACK_OF(X509_CRL) *crls);
static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
				X509 **pissuer, int *pcrl_score);
static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
				unsigned int *preasons);
static int check_crl_path(X509_STORE_CTX *ctx, X509 *x);
static int check_crl_chain(X509_STORE_CTX *ctx,
			STACK_OF(X509) *cert_path,
			STACK_OF(X509) *crl_path);

static int internal_verify(X509_STORE_CTX *ctx);


static int null_callback(int ok, X509_STORE_CTX *e)
	{
	return ok;
	}

#if 0
static int x509_subject_cmp(X509 **a, X509 **b)
	{
	return X509_subject_name_cmp(*a,*b);
	}
#endif
/* Return 1 is a certificate is self signed */
static int cert_self_signed(X509 *x)
	{
	X509_check_purpose(x, -1, 0);
	if (x->ex_flags & EXFLAG_SS)
		return 1;
	else
		return 0;
	}

/* Given a certificate try and find an exact match in the store */

static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x)
	{
	STACK_OF(X509) *certs;
	X509 *xtmp = NULL;
	size_t i;
	/* Lookup all certs with matching subject name */
	certs = ctx->lookup_certs(ctx, X509_get_subject_name(x));
	if (certs == NULL)
		return NULL;
	/* Look for exact match */
	for (i = 0; i < sk_X509_num(certs); i++)
		{
		xtmp = sk_X509_value(certs, i);
		if (!X509_cmp(xtmp, x))
			break;
		}
	if (i < sk_X509_num(certs))
		X509_up_ref(xtmp);
	else
		xtmp = NULL;
	sk_X509_pop_free(certs, X509_free);
	return xtmp;
	}

int X509_verify_cert(X509_STORE_CTX *ctx)
	{
	X509 *x,*xtmp,*chain_ss=NULL;
	int bad_chain = 0;
	X509_VERIFY_PARAM *param = ctx->param;
	int depth,i,ok=0;
	int num;
	int (*cb)(int xok,X509_STORE_CTX *xctx);
	STACK_OF(X509) *sktmp=NULL;
	if (ctx->cert == NULL)
		{
		OPENSSL_PUT_ERROR(X509, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
		return -1;
		}
	if (ctx->chain != NULL)
		{
		/* This X509_STORE_CTX has already been used to verify a
		 * cert. We cannot do another one. */
		OPENSSL_PUT_ERROR(X509, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
		return -1;
		}

	cb=ctx->verify_cb;

	/* first we make sure the chain we are going to build is
	 * present and that the first entry is in place */
	ctx->chain = sk_X509_new_null();
	if (ctx->chain == NULL || !sk_X509_push(ctx->chain, ctx->cert))
		{
		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
		goto end;
		}
	X509_up_ref(ctx->cert);
	ctx->last_untrusted = 1;

	/* We use a temporary STACK so we can chop and hack at it */
	if (ctx->untrusted != NULL
	    && (sktmp=sk_X509_dup(ctx->untrusted)) == NULL)
		{
		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
		goto end;
		}

	num=sk_X509_num(ctx->chain);
	x=sk_X509_value(ctx->chain,num-1);
	depth=param->depth;


	for (;;)
		{
		/* If we have enough, we break */
		if (depth < num) break; /* FIXME: If this happens, we should take
		                         * note of it and, if appropriate, use the
		                         * X509_V_ERR_CERT_CHAIN_TOO_LONG error
		                         * code later.
		                         */

		/* If we are self signed, we break */
		if (cert_self_signed(x))
			break;
		/* If asked see if we can find issuer in trusted store first */
		if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)
			{
			ok = ctx->get_issuer(&xtmp, ctx, x);
			if (ok < 0)
				goto end;
			/* If successful for now free up cert so it
			 * will be picked up again later.
			 */
			if (ok > 0)
				{
				X509_free(xtmp);
				break;
				}
			}

		/* If we were passed a cert chain, use it first */
		if (ctx->untrusted != NULL)
			{
			xtmp=find_issuer(ctx, sktmp,x);
			if (xtmp != NULL)
				{
				if (!sk_X509_push(ctx->chain,xtmp))
					{
					OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
					goto end;
					}
				X509_up_ref(xtmp);
				(void)sk_X509_delete_ptr(sktmp,xtmp);
				ctx->last_untrusted++;
				x=xtmp;
				num++;
				/* reparse the full chain for
				 * the next one */
				continue;
				}
			}
		break;
		}

	/* at this point, chain should contain a list of untrusted
	 * certificates.  We now need to add at least one trusted one,
	 * if possible, otherwise we complain. */

	/* Examine last certificate in chain and see if it
 	 * is self signed.
 	 */

	i=sk_X509_num(ctx->chain);
	x=sk_X509_value(ctx->chain,i-1);
	if (cert_self_signed(x))
		{
		/* we have a self signed certificate */
		if (sk_X509_num(ctx->chain) == 1)
			{
			/* We have a single self signed certificate: see if
			 * we can find it in the store. We must have an exact
			 * match to avoid possible impersonation.
			 */
			ok = ctx->get_issuer(&xtmp, ctx, x);
			if ((ok <= 0) || X509_cmp(x, xtmp)) 
				{
				ctx->error=X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
				ctx->current_cert=x;
				ctx->error_depth=i-1;
				if (ok == 1) X509_free(xtmp);
				bad_chain = 1;
				ok=cb(0,ctx);
				if (!ok) goto end;
				}
			else 
				{
				/* We have a match: replace certificate with store version
				 * so we get any trust settings.
				 */
				X509_free(x);
				x = xtmp;
				(void)sk_X509_set(ctx->chain, i - 1, x);
				ctx->last_untrusted=0;
				}
			}
		else
			{
			/* extract and save self signed certificate for later use */
			chain_ss=sk_X509_pop(ctx->chain);
			ctx->last_untrusted--;
			num--;
			x=sk_X509_value(ctx->chain,num-1);
			}
		}

	/* We now lookup certs from the certificate store */
	for (;;)
		{
		/* If we have enough, we break */
		if (depth < num) break;

		/* If we are self signed, we break */
		if (cert_self_signed(x))
			break;

		ok = ctx->get_issuer(&xtmp, ctx, x);

		if (ok < 0) goto end;
		if (ok == 0) break;

		x = xtmp;
		if (!sk_X509_push(ctx->chain,x))
			{
			X509_free(xtmp);
			OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
			ok = 0;
			goto end;
			}
		num++;
		}

	/* we now have our chain, lets check it... */

	i = check_trust(ctx);

	/* If explicitly rejected error */
	if (i == X509_TRUST_REJECTED)
		goto end;
	/* If not explicitly trusted then indicate error unless it's
	 * a single self signed certificate in which case we've indicated
	 * an error already and set bad_chain == 1
	 */
	if (i != X509_TRUST_TRUSTED && !bad_chain)
		{
		if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss))
			{
			if (ctx->last_untrusted >= num)
				ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
			else
				ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
			ctx->current_cert=x;
			}
		else
			{

			sk_X509_push(ctx->chain,chain_ss);
			num++;
			ctx->last_untrusted=num;
			ctx->current_cert=chain_ss;
			ctx->error=X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
			chain_ss=NULL;
			}

		ctx->error_depth=num-1;
		bad_chain = 1;
		ok=cb(0,ctx);
		if (!ok) goto end;
		}

	/* We have the chain complete: now we need to check its purpose */
	ok = check_chain_extensions(ctx);

	if (!ok) goto end;

	/* Check name constraints */

	ok = check_name_constraints(ctx);
	
	if (!ok) goto end;

	ok = check_id(ctx);

	if (!ok) goto end;

	/* Check revocation status: we do this after copying parameters
	 * because they may be needed for CRL signature verification.
	 */

	ok = ctx->check_revocation(ctx);
	if(!ok) goto end;

	i = X509_chain_check_suiteb(&ctx->error_depth, NULL, ctx->chain,
							ctx->param->flags);
	if (i != X509_V_OK)
		{
		ctx->error = i;
		ctx->current_cert = sk_X509_value(ctx->chain, ctx->error_depth);
		ok = cb(0, ctx);
		if (!ok)
			goto end;
		}

	/* At this point, we have a chain and need to verify it */
	if (ctx->verify != NULL)
		ok=ctx->verify(ctx);
	else
		ok=internal_verify(ctx);
	if(!ok) goto end;

	/* If we get this far evaluate policies */
	if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK))
		ok = ctx->check_policy(ctx);

end:
	if (sktmp != NULL) sk_X509_free(sktmp);
	if (chain_ss != NULL) X509_free(chain_ss);
	return ok;
	}


/* Given a STACK_OF(X509) find the issuer of cert (if any)
 */

static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x)
{
	size_t i;
	X509 *issuer;
	for (i = 0; i < sk_X509_num(sk); i++)
		{
		issuer = sk_X509_value(sk, i);
		if (ctx->check_issued(ctx, x, issuer))
			return issuer;
		}
	return NULL;
}

/* Given a possible certificate and issuer check them */

static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer)
{
	int ret;
	ret = X509_check_issued(issuer, x);
	if (ret == X509_V_OK)
		return 1;
	/* If we haven't asked for issuer errors don't set ctx */
	if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK))
		return 0;

	ctx->error = ret;
	ctx->current_cert = x;
	ctx->current_issuer = issuer;
	return ctx->verify_cb(0, ctx);
}

/* Alternative lookup method: look from a STACK stored in other_ctx */

static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
{
	*issuer = find_issuer(ctx, ctx->other_ctx, x);
	if (*issuer)
		{
		X509_up_ref(*issuer);
		return 1;
		}
	else
		return 0;
}
	

/* Check a certificate chains extensions for consistency
 * with the supplied purpose
 */

static int check_chain_extensions(X509_STORE_CTX *ctx)
{
	int i, ok=0, must_be_ca, plen = 0;
	X509 *x;
	int (*cb)(int xok,X509_STORE_CTX *xctx);
	int proxy_path_length = 0;
	int purpose;
	int allow_proxy_certs;
	cb=ctx->verify_cb;

	/* must_be_ca can have 1 of 3 values:
	   -1: we accept both CA and non-CA certificates, to allow direct
	       use of self-signed certificates (which are marked as CA).
	   0:  we only accept non-CA certificates.  This is currently not
	       used, but the possibility is present for future extensions.
	   1:  we only accept CA certificates.  This is currently used for
	       all certificates in the chain except the leaf certificate.
	*/
	must_be_ca = -1;

	/* CRL path validation */
	if (ctx->parent)
		{
		allow_proxy_certs = 0;
		purpose = X509_PURPOSE_CRL_SIGN;
		}
	else
		{
		allow_proxy_certs =
			!!(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
		/* A hack to keep people who don't want to modify their
		   software happy */
		if (getenv("OPENSSL_ALLOW_PROXY_CERTS"))
			allow_proxy_certs = 1;
		purpose = ctx->param->purpose;
		}

	/* Check all untrusted certificates */
	for (i = 0; i < ctx->last_untrusted; i++)
		{
		int ret;
		x = sk_X509_value(ctx->chain, i);
		if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
			&& (x->ex_flags & EXFLAG_CRITICAL))
			{
			ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
			ctx->error_depth = i;
			ctx->current_cert = x;
			ok=cb(0,ctx);
			if (!ok) goto end;
			}
		if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY))
			{
			ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
			ctx->error_depth = i;
			ctx->current_cert = x;
			ok=cb(0,ctx);
			if (!ok) goto end;
			}
		ret = X509_check_ca(x);
		switch(must_be_ca)
			{
		case -1:
			if ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
				&& (ret != 1) && (ret != 0))
				{
				ret = 0;
				ctx->error = X509_V_ERR_INVALID_CA;
				}
			else
				ret = 1;
			break;
		case 0:
			if (ret != 0)
				{
				ret = 0;
				ctx->error = X509_V_ERR_INVALID_NON_CA;
				}
			else
				ret = 1;
			break;
		default:
			if ((ret == 0)
				|| ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
					&& (ret != 1)))
				{
				ret = 0;
				ctx->error = X509_V_ERR_INVALID_CA;
				}
			else
				ret = 1;
			break;
			}
		if (ret == 0)
			{
			ctx->error_depth = i;
			ctx->current_cert = x;
			ok=cb(0,ctx);
			if (!ok) goto end;
			}
		if (ctx->param->purpose > 0)
			{
			ret = X509_check_purpose(x, purpose, must_be_ca > 0);
			if ((ret == 0)
				|| ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
					&& (ret != 1)))
				{
				ctx->error = X509_V_ERR_INVALID_PURPOSE;
				ctx->error_depth = i;
				ctx->current_cert = x;
				ok=cb(0,ctx);
				if (!ok) goto end;
				}
			}
		/* Check pathlen if not self issued */
		if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
			   && (x->ex_pathlen != -1)
			   && (plen > (x->ex_pathlen + proxy_path_length + 1)))
			{
			ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
			ctx->error_depth = i;
			ctx->current_cert = x;
			ok=cb(0,ctx);
			if (!ok) goto end;
			}
		/* Increment path length if not self issued */
		if (!(x->ex_flags & EXFLAG_SI))
			plen++;
		/* If this certificate is a proxy certificate, the next
		   certificate must be another proxy certificate or a EE
		   certificate.  If not, the next certificate must be a
		   CA certificate.  */
		if (x->ex_flags & EXFLAG_PROXY)
			{
			if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen)
				{
				ctx->error =
					X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
				ctx->error_depth = i;
				ctx->current_cert = x;
				ok=cb(0,ctx);
				if (!ok) goto end;
				}
			proxy_path_length++;
			must_be_ca = 0;
			}
		else
			must_be_ca = 1;
		}
	ok = 1;
 end:
	return ok;
}

static int check_name_constraints(X509_STORE_CTX *ctx)
	{
	X509 *x;
	int i, j, rv;
	/* Check name constraints for all certificates */
	for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--)
		{
		x = sk_X509_value(ctx->chain, i);
		/* Ignore self issued certs unless last in chain */
		if (i && (x->ex_flags & EXFLAG_SI))
			continue;
		/* Check against constraints for all certificates higher in
		 * chain including trust anchor. Trust anchor not strictly
		 * speaking needed but if it includes constraints it is to be
		 * assumed it expects them to be obeyed.
		 */
		for (j = sk_X509_num(ctx->chain) - 1; j > i; j--)
			{
			NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc;
			if (nc)
				{
				rv = NAME_CONSTRAINTS_check(x, nc);
				if (rv != X509_V_OK)
					{
					ctx->error = rv;
					ctx->error_depth = i;
					ctx->current_cert = x;
					if (!ctx->verify_cb(0,ctx))
						return 0;
					}
				}
			}
		}
	return 1;
	}

static int check_id_error(X509_STORE_CTX *ctx, int errcode)
	{
	ctx->error = errcode;
	ctx->current_cert = ctx->cert;
	ctx->error_depth = 0;
	return ctx->verify_cb(0, ctx);
	}

static int check_hosts(X509 *x, X509_VERIFY_PARAM_ID *id)
	{
	size_t i;
	size_t n = sk_OPENSSL_STRING_num(id->hosts);
	char *name;

	for (i = 0; i < n; ++i)
		{
		name = sk_OPENSSL_STRING_value(id->hosts, i);
		if (X509_check_host(x, name, strlen(name), id->hostflags,
				    &id->peername) > 0)
			return 1;
		}
	return n == 0;
	}

static int check_id(X509_STORE_CTX *ctx)
	{
	X509_VERIFY_PARAM *vpm = ctx->param;
	X509_VERIFY_PARAM_ID *id = vpm->id;
	X509 *x = ctx->cert;
	if (id->hosts && check_hosts(x, id) <= 0)
		{
		if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH))
			return 0;
		}
	if (id->email && X509_check_email(x, id->email, id->emaillen, 0) <= 0)
		{
		if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH))
			return 0;
		}
	if (id->ip && X509_check_ip(x, id->ip, id->iplen, 0) <= 0)
		{
		if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH))
			return 0;
		}
	return 1;
	}

static int check_trust(X509_STORE_CTX *ctx)
{
	size_t i;
	int ok;
	X509 *x = NULL;
	int (*cb)(int xok,X509_STORE_CTX *xctx);
	cb=ctx->verify_cb;
	/* Check all trusted certificates in chain */
	for (i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++)
		{
		x = sk_X509_value(ctx->chain, i);
		ok = X509_check_trust(x, ctx->param->trust, 0);
		/* If explicitly trusted return trusted */
		if (ok == X509_TRUST_TRUSTED)
			return X509_TRUST_TRUSTED;
		/* If explicitly rejected notify callback and reject if
		 * not overridden.
		 */
		if (ok == X509_TRUST_REJECTED)
			{
			ctx->error_depth = i;
			ctx->current_cert = x;
			ctx->error = X509_V_ERR_CERT_REJECTED;
			ok = cb(0, ctx);
			if (!ok)
				return X509_TRUST_REJECTED;
			}
		}
	/* If we accept partial chains and have at least one trusted
	 * certificate return success.
	 */
	if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN)
		{
		X509 *mx;
		if (ctx->last_untrusted < (int) sk_X509_num(ctx->chain))
			return X509_TRUST_TRUSTED;
		x = sk_X509_value(ctx->chain, 0);
		mx = lookup_cert_match(ctx, x);
		if (mx)
			{
			(void)sk_X509_set(ctx->chain, 0, mx);
			X509_free(x);
			ctx->last_untrusted = 0;
			return X509_TRUST_TRUSTED;
			}
		}

	/* If no trusted certs in chain at all return untrusted and
	 * allow standard (no issuer cert) etc errors to be indicated.
	 */
	return X509_TRUST_UNTRUSTED;
}

static int check_revocation(X509_STORE_CTX *ctx)
	{
	int i, last, ok;
	if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK))
		return 1;
	if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)
		last = sk_X509_num(ctx->chain) - 1;
	else
		{
		/* If checking CRL paths this isn't the EE certificate */
		if (ctx->parent)
			return 1;
		last = 0;
		}
	for(i = 0; i <= last; i++)
		{
		ctx->error_depth = i;
		ok = check_cert(ctx);
		if (!ok) return ok;
		}
	return 1;
	}

static int check_cert(X509_STORE_CTX *ctx)
                      OPENSSL_SUPPRESS_POTENTIALLY_UNINITIALIZED_WARNINGS
	{
	X509_CRL *crl = NULL, *dcrl = NULL;
	X509 *x;
	int ok, cnum;
	unsigned int last_reasons;
	cnum = ctx->error_depth;
	x = sk_X509_value(ctx->chain, cnum);
	ctx->current_cert = x;
	ctx->current_issuer = NULL;
	ctx->current_crl_score = 0;
	ctx->current_reasons = 0;
	while (ctx->current_reasons != CRLDP_ALL_REASONS)
		{
		last_reasons = ctx->current_reasons;
		/* Try to retrieve relevant CRL */
		if (ctx->get_crl)
			ok = ctx->get_crl(ctx, &crl, x);
		else
			ok = get_crl_delta(ctx, &crl, &dcrl, x);
		/* If error looking up CRL, nothing we can do except
		 * notify callback
		 */
		if(!ok)
			{
			ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
			ok = ctx->verify_cb(0, ctx);
			goto err;
			}
		ctx->current_crl = crl;
		ok = ctx->check_crl(ctx, crl);
		if (!ok)
			goto err;

		if (dcrl)
			{
			ok = ctx->check_crl(ctx, dcrl);
			if (!ok)
				goto err;
			ok = ctx->cert_crl(ctx, dcrl, x);
			if (!ok)
				goto err;
			}
		else
			ok = 1;

		/* Don't look in full CRL if delta reason is removefromCRL */
		if (ok != 2)
			{
			ok = ctx->cert_crl(ctx, crl, x);
			if (!ok)
				goto err;
			}

		X509_CRL_free(crl);
		X509_CRL_free(dcrl);
		crl = NULL;
		dcrl = NULL;
		/* If reasons not updated we wont get anywhere by
		 * another iteration, so exit loop.
		 */
		if (last_reasons == ctx->current_reasons)
			{
			ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
			ok = ctx->verify_cb(0, ctx);
			goto err;
			}
		}
	err:
	X509_CRL_free(crl);
	X509_CRL_free(dcrl);

	ctx->current_crl = NULL;
	return ok;

	}

/* Check CRL times against values in X509_STORE_CTX */

static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
	{
	time_t *ptime;
	int i;
	if (notify)
		ctx->current_crl = crl;
	if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
		ptime = &ctx->param->check_time;
	else
		ptime = NULL;

	i=X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime);
	if (i == 0)
		{
		if (!notify)
			return 0;
		ctx->error=X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD;
		if (!ctx->verify_cb(0, ctx))
			return 0;
		}

	if (i > 0)
		{
		if (!notify)
			return 0;
		ctx->error=X509_V_ERR_CRL_NOT_YET_VALID;
		if (!ctx->verify_cb(0, ctx))
			return 0;
		}

	if(X509_CRL_get_nextUpdate(crl))
		{
		i=X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime);

		if (i == 0)
			{
			if (!notify)
				return 0;
			ctx->error=X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD;
			if (!ctx->verify_cb(0, ctx))
				return 0;
			}
		/* Ignore expiry of base CRL is delta is valid */
		if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA))
			{
			if (!notify)
				return 0;
			ctx->error=X509_V_ERR_CRL_HAS_EXPIRED;
			if (!ctx->verify_cb(0, ctx))
				return 0;
			}
		}

	if (notify)
		ctx->current_crl = NULL;

	return 1;
	}

static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
			X509 **pissuer, int *pscore, unsigned int *preasons,
			STACK_OF(X509_CRL) *crls)
	{
	int crl_score, best_score = *pscore;
	size_t i;
	unsigned int reasons, best_reasons = 0;
	X509 *x = ctx->current_cert;
	X509_CRL *crl, *best_crl = NULL;
	X509 *crl_issuer = NULL, *best_crl_issuer = NULL;

	for (i = 0; i < sk_X509_CRL_num(crls); i++)
		{
		crl = sk_X509_CRL_value(crls, i);
		reasons = *preasons;
		crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x);

		if (crl_score > best_score)
			{
			best_crl = crl;
			best_crl_issuer = crl_issuer;
			best_score = crl_score;
			best_reasons = reasons;
			}
		}

	if (best_crl)
		{
		if (*pcrl)
			X509_CRL_free(*pcrl);
		*pcrl = best_crl;
		*pissuer = best_crl_issuer;
		*pscore = best_score;
		*preasons = best_reasons;
		X509_CRL_up_ref(best_crl);
		if (*pdcrl)
			{
			X509_CRL_free(*pdcrl);
			*pdcrl = NULL;
			}
		get_delta_sk(ctx, pdcrl, pscore, best_crl, crls);
		}

	if (best_score >= CRL_SCORE_VALID)
		return 1;

	return 0;
	}

/* Compare two CRL extensions for delta checking purposes. They should be
 * both present or both absent. If both present all fields must be identical.
 */

static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid)
	{
	ASN1_OCTET_STRING *exta, *extb;
	int i;
	i = X509_CRL_get_ext_by_NID(a, nid, -1);
	if (i >= 0)
		{
		/* Can't have multiple occurrences */
		if (X509_CRL_get_ext_by_NID(a, nid, i) != -1)
			return 0;
		exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i));
		}
	else
		exta = NULL;

	i = X509_CRL_get_ext_by_NID(b, nid, -1);

	if (i >= 0)
		{

		if (X509_CRL_get_ext_by_NID(b, nid, i) != -1)
			return 0;
		extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i));
		}
	else
		extb = NULL;

	if (!exta && !extb)
		return 1;

	if (!exta || !extb)
		return 0;


	if (ASN1_OCTET_STRING_cmp(exta, extb))
		return 0;

	return 1;
	}

/* See if a base and delta are compatible */

static int check_delta_base(X509_CRL *delta, X509_CRL *base)
	{
	/* Delta CRL must be a delta */
	if (!delta->base_crl_number)
			return 0;
	/* Base must have a CRL number */
	if (!base->crl_number)
			return 0;
	/* Issuer names must match */
	if (X509_NAME_cmp(X509_CRL_get_issuer(base),
				X509_CRL_get_issuer(delta)))
		return 0;
	/* AKID and IDP must match */
	if (!crl_extension_match(delta, base, NID_authority_key_identifier))
			return 0;
	if (!crl_extension_match(delta, base, NID_issuing_distribution_point))
			return 0;
	/* Delta CRL base number must not exceed Full CRL number. */
	if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0)
			return 0;
	/* Delta CRL number must exceed full CRL number */
	if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0)
			return 1;
	return 0;
	}

/* For a given base CRL find a delta... maybe extend to delta scoring
 * or retrieve a chain of deltas...
 */

static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore,
			X509_CRL *base, STACK_OF(X509_CRL) *crls)
	{
	X509_CRL *delta;
	size_t i;
	if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS))
		return;
	if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST))
		return;
	for (i = 0; i < sk_X509_CRL_num(crls); i++)
		{
		delta = sk_X509_CRL_value(crls, i);
		if (check_delta_base(delta, base))
			{
			if (check_crl_time(ctx, delta, 0))
				*pscore |= CRL_SCORE_TIME_DELTA;
			X509_CRL_up_ref(delta);
			*dcrl = delta;
			return;
			}
		}
	*dcrl = NULL;
	}

/* For a given CRL return how suitable it is for the supplied certificate 'x'.
 * The return value is a mask of several criteria.
 * If the issuer is not the certificate issuer this is returned in *pissuer.
 * The reasons mask is also used to determine if the CRL is suitable: if
 * no new reasons the CRL is rejected, otherwise reasons is updated.
 */

static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
			unsigned int *preasons,
			X509_CRL *crl, X509 *x)
	{

	int crl_score = 0;
	unsigned int tmp_reasons = *preasons, crl_reasons;

	/* First see if we can reject CRL straight away */

	/* Invalid IDP cannot be processed */
	if (crl->idp_flags & IDP_INVALID)
		return 0;
	/* Reason codes or indirect CRLs need extended CRL support */
	if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
		{
		if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS))
			return 0;
		}
	else if (crl->idp_flags & IDP_REASONS)
		{
		/* If no new reasons reject */
		if (!(crl->idp_reasons & ~tmp_reasons))
			return 0;
		}
	/* Don't process deltas at this stage */
	else if (crl->base_crl_number)
		return 0;
	/* If issuer name doesn't match certificate need indirect CRL */
	if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl)))
		{
		if (!(crl->idp_flags & IDP_INDIRECT))
			return 0;
		}
	else
		crl_score |= CRL_SCORE_ISSUER_NAME;

	if (!(crl->flags & EXFLAG_CRITICAL))
		crl_score |= CRL_SCORE_NOCRITICAL;

	/* Check expiry */
	if (check_crl_time(ctx, crl, 0))
		crl_score |= CRL_SCORE_TIME;

	/* Check authority key ID and locate certificate issuer */
	crl_akid_check(ctx, crl, pissuer, &crl_score);

	/* If we can't locate certificate issuer at this point forget it */

	if (!(crl_score & CRL_SCORE_AKID))
		return 0;

	/* Check cert for matching CRL distribution points */

	if (crl_crldp_check(x, crl, crl_score, &crl_reasons))
		{
		/* If no new reasons reject */
		if (!(crl_reasons & ~tmp_reasons))
			return 0;
		tmp_reasons |= crl_reasons;
		crl_score |= CRL_SCORE_SCOPE;
		}

	*preasons = tmp_reasons;

	return crl_score;

	}

static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
				X509 **pissuer, int *pcrl_score)
	{
	X509 *crl_issuer = NULL;
	X509_NAME *cnm = X509_CRL_get_issuer(crl);
	int cidx = ctx->error_depth;
	size_t i;

	if ((size_t) cidx != sk_X509_num(ctx->chain) - 1)
		cidx++;

	crl_issuer = sk_X509_value(ctx->chain, cidx);

	if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK)
		{
		if (*pcrl_score & CRL_SCORE_ISSUER_NAME)
			{
			*pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_ISSUER_CERT;
			*pissuer = crl_issuer;
			return;
			}
		}

	for (cidx++; cidx < (int) sk_X509_num(ctx->chain); cidx++)
		{
		crl_issuer = sk_X509_value(ctx->chain, cidx);
		if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
			continue;
		if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK)
			{
			*pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_SAME_PATH;
			*pissuer = crl_issuer;
			return;
			}
		}

	/* Anything else needs extended CRL support */

	if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
		return;

	/* Otherwise the CRL issuer is not on the path. Look for it in the
	 * set of untrusted certificates.
	 */
	for (i = 0; i < sk_X509_num(ctx->untrusted); i++)
		{
		crl_issuer = sk_X509_value(ctx->untrusted, i);
		if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
			continue;
		if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK)
			{
			*pissuer = crl_issuer;
			*pcrl_score |= CRL_SCORE_AKID;
			return;
			}
		}
	}

/* Check the path of a CRL issuer certificate. This creates a new
 * X509_STORE_CTX and populates it with most of the parameters from the
 * parent. This could be optimised somewhat since a lot of path checking
 * will be duplicated by the parent, but this will rarely be used in 
 * practice.
 */

static int check_crl_path(X509_STORE_CTX *ctx, X509 *x)
	{
	X509_STORE_CTX crl_ctx;
	int ret;
	/* Don't allow recursive CRL path validation */
	if (ctx->parent)
		return 0;
	if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted))
		return -1;

	crl_ctx.crls = ctx->crls;
	/* Copy verify params across */
	X509_STORE_CTX_set0_param(&crl_ctx, ctx->param);

	crl_ctx.parent = ctx;
	crl_ctx.verify_cb = ctx->verify_cb;

	/* Verify CRL issuer */
	ret = X509_verify_cert(&crl_ctx);

	if (ret <= 0)
		goto err;

	/* Check chain is acceptable */

	ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain);
	err:
	X509_STORE_CTX_cleanup(&crl_ctx);
	return ret;
	}

/* RFC3280 says nothing about the relationship between CRL path
 * and certificate path, which could lead to situations where a
 * certificate could be revoked or validated by a CA not authorised
 * to do so. RFC5280 is more strict and states that the two paths must
 * end in the same trust anchor, though some discussions remain...
 * until this is resolved we use the RFC5280 version
 */

static int check_crl_chain(X509_STORE_CTX *ctx,
			STACK_OF(X509) *cert_path,
			STACK_OF(X509) *crl_path)
	{
	X509 *cert_ta, *crl_ta;
	cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1);
	crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1);
	if (!X509_cmp(cert_ta, crl_ta))
		return 1;
	return 0;
	}

/* Check for match between two dist point names: three separate cases.
 * 1. Both are relative names and compare X509_NAME types.
 * 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES.
 * 3. Both are full names and compare two GENERAL_NAMES.
 * 4. One is NULL: automatic match.
 */


static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b)
	{
	X509_NAME *nm = NULL;
	GENERAL_NAMES *gens = NULL;
	GENERAL_NAME *gena, *genb;
	size_t i, j;
	if (!a || !b)
		return 1;
	if (a->type == 1)
		{
		if (!a->dpname)
			return 0;
		/* Case 1: two X509_NAME */
		if (b->type == 1)
			{
			if (!b->dpname)
				return 0;
			if (!X509_NAME_cmp(a->dpname, b->dpname))
				return 1;
			else
				return 0;
			}
		/* Case 2: set name and GENERAL_NAMES appropriately */
		nm = a->dpname;
		gens = b->name.fullname;
		}
	else if (b->type == 1)
		{
		if (!b->dpname)
			return 0;
		/* Case 2: set name and GENERAL_NAMES appropriately */
		gens = a->name.fullname;
		nm = b->dpname;
		}

	/* Handle case 2 with one GENERAL_NAMES and one X509_NAME */
	if (nm)
		{
		for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
			{
			gena = sk_GENERAL_NAME_value(gens, i);	
			if (gena->type != GEN_DIRNAME)
				continue;
			if (!X509_NAME_cmp(nm, gena->d.directoryName))
				return 1;
			}
		return 0;
		}

	/* Else case 3: two GENERAL_NAMES */

	for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++)
		{
		gena = sk_GENERAL_NAME_value(a->name.fullname, i);
		for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++)
			{
			genb = sk_GENERAL_NAME_value(b->name.fullname, j);
			if (!GENERAL_NAME_cmp(gena, genb))
				return 1;
			}
		}

	return 0;

	}

static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score)
	{
	size_t i;
	X509_NAME *nm = X509_CRL_get_issuer(crl);
	/* If no CRLissuer return is successful iff don't need a match */
	if (!dp->CRLissuer)
		return !!(crl_score & CRL_SCORE_ISSUER_NAME);
	for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++)
		{
		GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
		if (gen->type != GEN_DIRNAME)
			continue;
		if (!X509_NAME_cmp(gen->d.directoryName, nm))
			return 1;
		}
	return 0;
	}

/* Check CRLDP and IDP */

static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
				unsigned int *preasons)
	{
	size_t i;
	if (crl->idp_flags & IDP_ONLYATTR)
		return 0;
	if (x->ex_flags & EXFLAG_CA)
		{
		if (crl->idp_flags & IDP_ONLYUSER)
			return 0;
		}
	else
		{
		if (crl->idp_flags & IDP_ONLYCA)
			return 0;
		}
	*preasons = crl->idp_reasons;
	for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
		{
		DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i);
		if (crldp_check_crlissuer(dp, crl, crl_score))
			{
			if (!crl->idp ||
			     idp_check_dp(dp->distpoint, crl->idp->distpoint))
				{
				*preasons &= dp->dp_reasons;
				return 1;
				}
			}
		}
	if ((!crl->idp || !crl->idp->distpoint) && (crl_score & CRL_SCORE_ISSUER_NAME))
		return 1;
	return 0;
	}

/* Retrieve CRL corresponding to current certificate.
 * If deltas enabled try to find a delta CRL too
 */
	
static int get_crl_delta(X509_STORE_CTX *ctx,
				X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x)
	{
	int ok;
	X509 *issuer = NULL;
	int crl_score = 0;
	unsigned int reasons;
	X509_CRL *crl = NULL, *dcrl = NULL;
	STACK_OF(X509_CRL) *skcrl;
	X509_NAME *nm = X509_get_issuer_name(x);
	reasons = ctx->current_reasons;
	ok = get_crl_sk(ctx, &crl, &dcrl, 
				&issuer, &crl_score, &reasons, ctx->crls);

	if (ok)
		goto done;

	/* Lookup CRLs from store */

	skcrl = ctx->lookup_crls(ctx, nm);

	/* If no CRLs found and a near match from get_crl_sk use that */
	if (!skcrl && crl)
		goto done;

	get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl);

	sk_X509_CRL_pop_free(skcrl, X509_CRL_free);

	done:

	/* If we got any kind of CRL use it and return success */
	if (crl)
		{
		ctx->current_issuer = issuer;
		ctx->current_crl_score = crl_score;
		ctx->current_reasons = reasons;
		*pcrl = crl;
		*pdcrl = dcrl;
		return 1;
		}

	return 0;
	}

/* Check CRL validity */
static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
	{
	X509 *issuer = NULL;
	EVP_PKEY *ikey = NULL;
	int ok = 0, chnum, cnum;
	cnum = ctx->error_depth;
	chnum = sk_X509_num(ctx->chain) - 1;
	/* if we have an alternative CRL issuer cert use that */
	if (ctx->current_issuer)
		issuer = ctx->current_issuer;

	/* Else find CRL issuer: if not last certificate then issuer
	 * is next certificate in chain.
	 */
	else if (cnum < chnum)
		issuer = sk_X509_value(ctx->chain, cnum + 1);
	else
		{
		issuer = sk_X509_value(ctx->chain, chnum);
		/* If not self signed, can't check signature */
		if(!ctx->check_issued(ctx, issuer, issuer))
			{
			ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER;
			ok = ctx->verify_cb(0, ctx);
			if(!ok) goto err;
			}
		}

	if(issuer)
		{
		/* Skip most tests for deltas because they have already
		 * been done
		 */
		if (!crl->base_crl_number)
			{
			/* Check for cRLSign bit if keyUsage present */
			if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
				!(issuer->ex_kusage & KU_CRL_SIGN))
				{
				ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
				ok = ctx->verify_cb(0, ctx);
				if(!ok) goto err;
				}

			if (!(ctx->current_crl_score & CRL_SCORE_SCOPE))
				{
				ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE;
				ok = ctx->verify_cb(0, ctx);
				if(!ok) goto err;
				}

			if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH))
				{
				if (check_crl_path(ctx, ctx->current_issuer) <= 0)
					{
					ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR;
					ok = ctx->verify_cb(0, ctx);
					if(!ok) goto err;
					}
				}

			if (crl->idp_flags & IDP_INVALID)
				{
				ctx->error = X509_V_ERR_INVALID_EXTENSION;
				ok = ctx->verify_cb(0, ctx);
				if(!ok) goto err;
				}


			}

		if (!(ctx->current_crl_score & CRL_SCORE_TIME))
			{
			ok = check_crl_time(ctx, crl, 1);
			if (!ok)
				goto err;
			}

		/* Attempt to get issuer certificate public key */
		ikey = X509_get_pubkey(issuer);

		if(!ikey)
			{
			ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
			ok = ctx->verify_cb(0, ctx);
			if (!ok) goto err;
			}
		else
			{
			int rv;
			rv = X509_CRL_check_suiteb(crl, ikey, ctx->param->flags);
			if (rv != X509_V_OK)
				{
				ctx->error=rv;
				ok = ctx->verify_cb(0, ctx);
				if (!ok)
					goto err;
				}
			/* Verify CRL signature */
			if(X509_CRL_verify(crl, ikey) <= 0)
				{
				ctx->error=X509_V_ERR_CRL_SIGNATURE_FAILURE;
				ok = ctx->verify_cb(0, ctx);
				if (!ok) goto err;
				}
			}
		}

	ok = 1;

	err:
	EVP_PKEY_free(ikey);
	return ok;
	}

/* Check certificate against CRL */
static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
	{
	int ok;
	X509_REVOKED *rev;
	/* The rules changed for this... previously if a CRL contained
	 * unhandled critical extensions it could still be used to indicate
	 * a certificate was revoked. This has since been changed since 
	 * critical extension can change the meaning of CRL entries.
	 */
	if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
		&& (crl->flags & EXFLAG_CRITICAL))
		{
		ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
		ok = ctx->verify_cb(0, ctx);
		if(!ok)
			return 0;
		}
	/* Look for serial number of certificate in CRL
	 * If found make sure reason is not removeFromCRL.
	 */
	if (X509_CRL_get0_by_cert(crl, &rev, x))
		{
		if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
			return 2;
		ctx->error = X509_V_ERR_CERT_REVOKED;
		ok = ctx->verify_cb(0, ctx);
		if (!ok)
			return 0;
		}

	return 1;
	}

static int check_policy(X509_STORE_CTX *ctx)
	{
	int ret;
	if (ctx->parent)
		return 1;
	ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain,
				ctx->param->policies, ctx->param->flags);
	if (ret == 0)
		{
		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
		return 0;
		}
	/* Invalid or inconsistent extensions */
	if (ret == -1)
		{
		/* Locate certificates with bad extensions and notify
		 * callback.
		 */
		X509 *x;
		size_t i;
		for (i = 1; i < sk_X509_num(ctx->chain); i++)
			{
			x = sk_X509_value(ctx->chain, i);
			if (!(x->ex_flags & EXFLAG_INVALID_POLICY))
				continue;
			ctx->current_cert = x;
			ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION;
			if(!ctx->verify_cb(0, ctx))
				return 0;
			}
		return 1;
		}
	if (ret == -2)
		{
		ctx->current_cert = NULL;
		ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY;
		return ctx->verify_cb(0, ctx);
		}

	if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY)
		{
		ctx->current_cert = NULL;
		ctx->error = X509_V_OK;
		if (!ctx->verify_cb(2, ctx))
			return 0;
		}

	return 1;
	}

static int check_cert_time(X509_STORE_CTX *ctx, X509 *x)
	{
	time_t *ptime;
	int i;

	if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
		ptime = &ctx->param->check_time;
	else
		ptime = NULL;

	i=X509_cmp_time(X509_get_notBefore(x), ptime);
	if (i == 0)
		{
		ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
		ctx->current_cert=x;
		if (!ctx->verify_cb(0, ctx))
			return 0;
		}

	if (i > 0)
		{
		ctx->error=X509_V_ERR_CERT_NOT_YET_VALID;
		ctx->current_cert=x;
		if (!ctx->verify_cb(0, ctx))
			return 0;
		}

	i=X509_cmp_time(X509_get_notAfter(x), ptime);
	if (i == 0)
		{
		ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
		ctx->current_cert=x;
		if (!ctx->verify_cb(0, ctx))
			return 0;
		}

	if (i < 0)
		{
		ctx->error=X509_V_ERR_CERT_HAS_EXPIRED;
		ctx->current_cert=x;
		if (!ctx->verify_cb(0, ctx))
			return 0;
		}

	return 1;
	}

static int internal_verify(X509_STORE_CTX *ctx)
	{
	int ok=0,n;
	X509 *xs,*xi;
	EVP_PKEY *pkey=NULL;
	int (*cb)(int xok,X509_STORE_CTX *xctx);

	cb=ctx->verify_cb;

	n=sk_X509_num(ctx->chain);
	ctx->error_depth=n-1;
	n--;
	xi=sk_X509_value(ctx->chain,n);

	if (ctx->check_issued(ctx, xi, xi))
		xs=xi;
	else
		{
		if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN)
			{
			xs = xi;
			goto check_cert;
			}
		if (n <= 0)
			{
			ctx->error=X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
			ctx->current_cert=xi;
			ok=cb(0,ctx);
			goto end;
			}
		else
			{
			n--;
			ctx->error_depth=n;
			xs=sk_X509_value(ctx->chain,n);
			}
		}

/*	ctx->error=0;  not needed */
	while (n >= 0)
		{
		ctx->error_depth=n;

		/* Skip signature check for self signed certificates unless
		 * explicitly asked for. It doesn't add any security and
		 * just wastes time.
		 */
		if (!xs->valid && (xs != xi || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE)))
			{
			if ((pkey=X509_get_pubkey(xi)) == NULL)
				{
				ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
				ctx->current_cert=xi;
				ok=(*cb)(0,ctx);
				if (!ok) goto end;
				}
			else if (X509_verify(xs,pkey) <= 0)
				{
				ctx->error=X509_V_ERR_CERT_SIGNATURE_FAILURE;
				ctx->current_cert=xs;
				ok=(*cb)(0,ctx);
				if (!ok)
					{
					EVP_PKEY_free(pkey);
					goto end;
					}
				}
			EVP_PKEY_free(pkey);
			pkey=NULL;
			}

		xs->valid = 1;

		check_cert:
		ok = check_cert_time(ctx, xs);
		if (!ok)
			goto end;

		/* The last error (if any) is still in the error value */
		ctx->current_issuer=xi;
		ctx->current_cert=xs;
		ok=(*cb)(1,ctx);
		if (!ok) goto end;

		n--;
		if (n >= 0)
			{
			xi=xs;
			xs=sk_X509_value(ctx->chain,n);
			}
		}
	ok=1;
end:
	return ok;
	}

int X509_cmp_current_time(const ASN1_TIME *ctm)
{
	return X509_cmp_time(ctm, NULL);
}

int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
	{
	char *str;
	ASN1_TIME atm;
	long offset;
	char buff1[24],buff2[24],*p;
	int i, j, remaining;

	p=buff1;
	remaining = ctm->length;
	str=(char *)ctm->data;
	/* Note that the following (historical) code allows much more slack in
	 * the time format than RFC5280. In RFC5280, the representation is
	 * fixed:
	 * UTCTime: YYMMDDHHMMSSZ
	 * GeneralizedTime: YYYYMMDDHHMMSSZ */
	if (ctm->type == V_ASN1_UTCTIME)
		{
		/* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */
		int min_length = sizeof("YYMMDDHHMMZ") - 1;
		int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1;
		if (remaining < min_length || remaining > max_length)
			return 0;
		memcpy(p,str,10);
		p+=10;
		str+=10;
		remaining -= 10;
		}
	else
		{
		/* YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm */
		int min_length = sizeof("YYYYMMDDHHMMZ") - 1;
		int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1;
		if (remaining < min_length || remaining > max_length)
			return 0;
		memcpy(p,str,12);
		p+=12;
		str+=12;
		remaining -= 12;
		}

	if ((*str == 'Z') || (*str == '-') || (*str == '+'))
		{ *(p++)='0'; *(p++)='0'; }
	else
		{ 
		/* SS (seconds) */
		if (remaining < 2)
			return 0;
		*(p++)= *(str++);
		*(p++)= *(str++);
		remaining -= 2;
		/* Skip any (up to three) fractional seconds...
		 * TODO(emilia): in RFC5280, fractional seconds are forbidden.
		 * Can we just kill them altogether? */
		if (remaining && *str == '.')
			{
			str++;
			remaining--;
			for (i = 0; i < 3 && remaining; i++, str++, remaining--)
				{
				if (*str < '0' || *str > '9')
					break;
				}
			}
		
		}
	*(p++)='Z';
	*(p++)='\0';

	/* We now need either a terminating 'Z' or an offset. */
	if (!remaining)
		return 0;
	if (*str == 'Z')
		{
		if (remaining != 1)
			return 0;
		offset=0;
		}
	else
		{
		/* (+-)HHMM */
		if ((*str != '+') && (*str != '-'))
			return 0;
		/* Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. */
		if (remaining != 5)
			return 0;
		if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' ||
			str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9')
			return 0;
		offset=((str[1]-'0')*10+(str[2]-'0'))*60;
		offset+=(str[3]-'0')*10+(str[4]-'0');
		if (*str == '-')
			offset= -offset;
		}
	atm.type=ctm->type;
	atm.flags = 0;
	atm.length=sizeof(buff2);
	atm.data=(unsigned char *)buff2;

	if (X509_time_adj(&atm, offset*60, cmp_time) == NULL)
		return 0;

	if (ctm->type == V_ASN1_UTCTIME)
		{
		i=(buff1[0]-'0')*10+(buff1[1]-'0');
		if (i < 50) i+=100; /* cf. RFC 2459 */
		j=(buff2[0]-'0')*10+(buff2[1]-'0');
		if (j < 50) j+=100;

		if (i < j) return -1;
		if (i > j) return 1;
		}
	i=strcmp(buff1,buff2);
	if (i == 0) /* wait a second then return younger :-) */
		return -1;
	else
		return i;
	}

ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj)
{
	return X509_time_adj(s, adj, NULL);
}

ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm)
	{
	return X509_time_adj_ex(s, 0, offset_sec, in_tm);
	}

ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
				int offset_day, long offset_sec, time_t *in_tm)
	{
	time_t t = 0;

	if (in_tm) t = *in_tm;
	else time(&t);

	if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING))
		{
		if (s->type == V_ASN1_UTCTIME)
			return ASN1_UTCTIME_adj(s,t, offset_day, offset_sec);
		if (s->type == V_ASN1_GENERALIZEDTIME)
			return ASN1_GENERALIZEDTIME_adj(s, t, offset_day,
								offset_sec);
		}
	return ASN1_TIME_adj(s, t, offset_day, offset_sec);
	}

/* Make a delta CRL as the diff between two full CRLs */

X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
			EVP_PKEY *skey, const EVP_MD *md, unsigned int flags)
	{
	X509_CRL *crl = NULL;
	int i;
	size_t j;
	STACK_OF(X509_REVOKED) *revs = NULL;
	/* CRLs can't be delta already */
	if (base->base_crl_number || newer->base_crl_number)
			{
			OPENSSL_PUT_ERROR(X509, X509_R_CRL_ALREADY_DELTA);
			return NULL;
			}
	/* Base and new CRL must have a CRL number */
	if (!base->crl_number || !newer->crl_number)
			{
			OPENSSL_PUT_ERROR(X509, X509_R_NO_CRL_NUMBER);
			return NULL;
			}
	/* Issuer names must match */
	if (X509_NAME_cmp(X509_CRL_get_issuer(base),
				X509_CRL_get_issuer(newer)))
			{
			OPENSSL_PUT_ERROR(X509, X509_R_ISSUER_MISMATCH);
			return NULL;
			}
	/* AKID and IDP must match */
	if (!crl_extension_match(base, newer, NID_authority_key_identifier))
			{
			OPENSSL_PUT_ERROR(X509, X509_R_AKID_MISMATCH);
			return NULL;
			}
	if (!crl_extension_match(base, newer, NID_issuing_distribution_point))
			{
			OPENSSL_PUT_ERROR(X509, X509_R_IDP_MISMATCH);
			return NULL;
			}
	/* Newer CRL number must exceed full CRL number */
	if (ASN1_INTEGER_cmp(newer->crl_number, base->crl_number) <= 0)
			{
			OPENSSL_PUT_ERROR(X509, X509_R_NEWER_CRL_NOT_NEWER);
			return NULL;
			}
	/* CRLs must verify */
	if (skey && (X509_CRL_verify(base, skey) <= 0 ||
			X509_CRL_verify(newer, skey) <= 0))
		{
		OPENSSL_PUT_ERROR(X509, X509_R_CRL_VERIFY_FAILURE);
		return NULL;
		}
	/* Create new CRL */
	crl = X509_CRL_new();
	if (!crl || !X509_CRL_set_version(crl, 1))
		goto memerr;
	/* Set issuer name */
	if (!X509_CRL_set_issuer_name(crl, X509_CRL_get_issuer(newer)))
		goto memerr;

	if (!X509_CRL_set_lastUpdate(crl, X509_CRL_get_lastUpdate(newer)))
		goto memerr;
	if (!X509_CRL_set_nextUpdate(crl, X509_CRL_get_nextUpdate(newer)))
		goto memerr;

	/* Set base CRL number: must be critical */

	if (!X509_CRL_add1_ext_i2d(crl, NID_delta_crl, base->crl_number, 1, 0))
		goto memerr;

	/* Copy extensions across from newest CRL to delta: this will set
	 * CRL number to correct value too.
	 */

	for (i = 0; i < X509_CRL_get_ext_count(newer); i++)
		{
		X509_EXTENSION *ext;
		ext = X509_CRL_get_ext(newer, i);
		if (!X509_CRL_add_ext(crl, ext, -1))
			goto memerr;
		}

	/* Go through revoked entries, copying as needed */

	revs = X509_CRL_get_REVOKED(newer);

	for (j = 0; j < sk_X509_REVOKED_num(revs); j++)
		{
		X509_REVOKED *rvn, *rvtmp;
		rvn = sk_X509_REVOKED_value(revs, j);
		/* Add only if not also in base.
		 * TODO: need something cleverer here for some more complex
		 * CRLs covering multiple CAs.
		 */
		if (!X509_CRL_get0_by_serial(base, &rvtmp, rvn->serialNumber))
			{
			rvtmp = X509_REVOKED_dup(rvn);
			if (!rvtmp)
				goto memerr;
			if (!X509_CRL_add0_revoked(crl, rvtmp))
				{
				X509_REVOKED_free(rvtmp);
				goto memerr;
				}
			}
		}
	/* TODO: optionally prune deleted entries */

	if (skey && md && !X509_CRL_sign(crl, skey, md))
		goto memerr;
	
	return crl;

	memerr:
	OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
	if (crl)
		X509_CRL_free(crl);
	return NULL;
	}

int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
	{
	/* This function is (usually) called only once, by
	 * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). */
	int index;
	if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp,
			dup_func, free_func))
		{
		return -1;
		}
	return index;
	}

int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data)
	{
	return CRYPTO_set_ex_data(&ctx->ex_data,idx,data);
	}

void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx)
	{
	return CRYPTO_get_ex_data(&ctx->ex_data,idx);
	}

int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx)
	{
	return ctx->error;
	}

void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err)
	{
	ctx->error=err;
	}

int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx)
	{
	return ctx->error_depth;
	}

X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx)
	{
	return ctx->current_cert;
	}

STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx)
	{
	return ctx->chain;
	}

STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx)
	{
	if (!ctx->chain)
		return NULL;
	return X509_chain_up_ref(ctx->chain);
	}

X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx)
	{
	return ctx->current_issuer;
	}

X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx)
	{
	return ctx->current_crl;
	}

X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx)
	{
	return ctx->parent;
	}

void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x)
	{
	ctx->cert=x;
	}

void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
	{
	ctx->untrusted=sk;
	}

void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk)
	{
	ctx->crls=sk;
	}

int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose)
	{
	return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
	}

int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust)
	{
	return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
	}

/* This function is used to set the X509_STORE_CTX purpose and trust
 * values. This is intended to be used when another structure has its
 * own trust and purpose values which (if set) will be inherited by
 * the ctx. If they aren't set then we will usually have a default
 * purpose in mind which should then be used to set the trust value.
 * An example of this is SSL use: an SSL structure will have its own
 * purpose and trust settings which the application can set: if they
 * aren't set then we use the default of SSL client/server.
 */

int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
				int purpose, int trust)
{
	int idx;
	/* If purpose not set use default */
	if (!purpose) purpose = def_purpose;
	/* If we have a purpose then check it is valid */
	if (purpose)
		{
		X509_PURPOSE *ptmp;
		idx = X509_PURPOSE_get_by_id(purpose);
		if (idx == -1)
			{
			OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
			return 0;
			}
		ptmp = X509_PURPOSE_get0(idx);
		if (ptmp->trust == X509_TRUST_DEFAULT)
			{
			idx = X509_PURPOSE_get_by_id(def_purpose);
			if (idx == -1)
				{
				OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
				return 0;
				}
			ptmp = X509_PURPOSE_get0(idx);
			}
		/* If trust not set then get from purpose default */
		if (!trust) trust = ptmp->trust;
		}
	if (trust)
		{
		idx = X509_TRUST_get_by_id(trust);
		if (idx == -1)
			{
			OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_TRUST_ID);
			return 0;
			}
		}

	if (purpose && !ctx->param->purpose) ctx->param->purpose = purpose;
	if (trust && !ctx->param->trust) ctx->param->trust = trust;
	return 1;
}

X509_STORE_CTX *X509_STORE_CTX_new(void)
{
	X509_STORE_CTX *ctx;
	ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX));
	if (!ctx)
		{
		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
		return NULL;
		}
	memset(ctx, 0, sizeof(X509_STORE_CTX));
	return ctx;
}

void X509_STORE_CTX_free(X509_STORE_CTX *ctx)
{
	X509_STORE_CTX_cleanup(ctx);
	OPENSSL_free(ctx);
}

int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
	     STACK_OF(X509) *chain)
	{
	int ret = 1;

	memset(ctx, 0, sizeof(X509_STORE_CTX));
	ctx->ctx=store;
	ctx->cert=x509;
	ctx->untrusted=chain;

	CRYPTO_new_ex_data(&ctx->ex_data);

	ctx->param = X509_VERIFY_PARAM_new();
	if (!ctx->param)
		goto err;

	/* Inherit callbacks and flags from X509_STORE if not set
	 * use defaults. */

	if (store)
		ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
	else
		ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT|X509_VP_FLAG_ONCE;

	if (store)
		{
		ctx->verify_cb = store->verify_cb;
		ctx->cleanup = store->cleanup;
		}
	else
		ctx->cleanup = 0;

	if (ret)
		ret = X509_VERIFY_PARAM_inherit(ctx->param,
					X509_VERIFY_PARAM_lookup("default"));

	if (ret == 0)
		goto err;

	if (store && store->check_issued)
		ctx->check_issued = store->check_issued;
	else
		ctx->check_issued = check_issued;

	if (store && store->get_issuer)
		ctx->get_issuer = store->get_issuer;
	else
		ctx->get_issuer = X509_STORE_CTX_get1_issuer;

	if (store && store->verify_cb)
		ctx->verify_cb = store->verify_cb;
	else
		ctx->verify_cb = null_callback;

	if (store && store->verify)
		ctx->verify = store->verify;
	else
		ctx->verify = internal_verify;

	if (store && store->check_revocation)
		ctx->check_revocation = store->check_revocation;
	else
		ctx->check_revocation = check_revocation;

	if (store && store->get_crl)
		ctx->get_crl = store->get_crl;
	else
		ctx->get_crl = NULL;

	if (store && store->check_crl)
		ctx->check_crl = store->check_crl;
	else
		ctx->check_crl = check_crl;

	if (store && store->cert_crl)
		ctx->cert_crl = store->cert_crl;
	else
		ctx->cert_crl = cert_crl;

	if (store && store->lookup_certs)
		ctx->lookup_certs = store->lookup_certs;
	else
		ctx->lookup_certs = X509_STORE_get1_certs;

	if (store && store->lookup_crls)
		ctx->lookup_crls = store->lookup_crls;
	else
		ctx->lookup_crls = X509_STORE_get1_crls;

	ctx->check_policy = check_policy;

	return 1;

err:
	CRYPTO_free_ex_data(&g_ex_data_class, ctx, &ctx->ex_data);
	if (ctx->param != NULL)
		{
		X509_VERIFY_PARAM_free(ctx->param);
		}

	memset(ctx, 0, sizeof(X509_STORE_CTX));
	OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
	return 0;
	}

/* Set alternative lookup method: just a STACK of trusted certificates.
 * This avoids X509_STORE nastiness where it isn't needed.
 */

void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
{
	ctx->other_ctx = sk;
	ctx->get_issuer = get_issuer_sk;
}

void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx)
	{
	if (ctx->cleanup) ctx->cleanup(ctx);
	if (ctx->param != NULL)
		{
		if (ctx->parent == NULL)
			X509_VERIFY_PARAM_free(ctx->param);
		ctx->param=NULL;
		}
	if (ctx->tree != NULL)
		{
		X509_policy_tree_free(ctx->tree);
		ctx->tree=NULL;
		}
	if (ctx->chain != NULL)
		{
		sk_X509_pop_free(ctx->chain,X509_free);
		ctx->chain=NULL;
		}
	CRYPTO_free_ex_data(&g_ex_data_class, ctx, &(ctx->ex_data));
	memset(&ctx->ex_data,0,sizeof(CRYPTO_EX_DATA));
	}

void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth)
	{
	X509_VERIFY_PARAM_set_depth(ctx->param, depth);
	}

void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags)
	{
	X509_VERIFY_PARAM_set_flags(ctx->param, flags);
	}

void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, time_t t)
	{
	X509_VERIFY_PARAM_set_time(ctx->param, t);
	}

void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
				  int (*verify_cb)(int, X509_STORE_CTX *))
	{
	ctx->verify_cb=verify_cb;
	}

X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx)
	{
	return ctx->tree;
	}

int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx)
	{
	return ctx->explicit_policy;
	}

int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name)
	{
	const X509_VERIFY_PARAM *param;
	param = X509_VERIFY_PARAM_lookup(name);
	if (!param)
		return 0;
	return X509_VERIFY_PARAM_inherit(ctx->param, param);
	}

X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx)
	{
	return ctx->param;
	}

void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param)
	{
	if (ctx->param)
		X509_VERIFY_PARAM_free(ctx->param);
	ctx->param = param;
	}

IMPLEMENT_ASN1_SET_OF(X509)
IMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE)
