/* v3_purp.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
 * project 2001.
 */
/* ====================================================================
 * Copyright (c) 1999-2004 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). */

#include <stdio.h>

#include <string.h>

#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/digest.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/thread.h>
#include <openssl/x509_vfy.h>
#include <openssl/x509v3.h>

#include "../internal.h"


#define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
#define ku_reject(x, usage) \
	(((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
#define xku_reject(x, usage) \
	(((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage)))
#define ns_reject(x, usage) \
	(((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage)))

static void x509v3_cache_extensions(X509 *x);

static int check_ssl_ca(const X509 *x);
static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca);
static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca);
static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca);
static int purpose_smime(const X509 *x, int ca);
static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca);
static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca);
static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca);
static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, int ca);
static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca);
static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca);

static int xp_cmp(const X509_PURPOSE **a, const X509_PURPOSE **b);
static void xptable_free(X509_PURPOSE *p);

static X509_PURPOSE xstandard[] = {
	{X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, 0, check_purpose_ssl_client, (char *) "SSL client", (char *) "sslclient", NULL},
	{X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ssl_server, (char *) "SSL server", (char *) "sslserver", NULL},
	{X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ns_ssl_server, (char *) "Netscape SSL server", (char *) "nssslserver", NULL},
	{X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign, (char *) "S/MIME signing", (char *) "smimesign", NULL},
	{X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0, check_purpose_smime_encrypt, (char *) "S/MIME encryption", (char *) "smimeencrypt", NULL},
	{X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, (char *) "CRL signing", (char *) "crlsign", NULL},
	{X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, (char *) "Any Purpose", (char *) "any", NULL},
	{X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper, (char *) "OCSP helper", (char *) "ocsphelper", NULL},
	{X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0, check_purpose_timestamp_sign, (char *) "Time Stamp signing", (char *) "timestampsign", NULL},
};

#define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE))

static STACK_OF(X509_PURPOSE) *xptable = NULL;

static int xp_cmp(const X509_PURPOSE **a, const X509_PURPOSE **b)
{
	return (*a)->purpose - (*b)->purpose;
}

/* As much as I'd like to make X509_check_purpose use a "const" X509*
 * I really can't because it does recalculate hashes and do other non-const
 * things. */
int X509_check_purpose(X509 *x, int id, int ca)
{
	int idx;
	const X509_PURPOSE *pt;
	if(!(x->ex_flags & EXFLAG_SET)) {
		x509v3_cache_extensions(x);
	}
	if(id == -1) return 1;
	idx = X509_PURPOSE_get_by_id(id);
	if(idx == -1) return -1;
	pt = X509_PURPOSE_get0(idx);
	return pt->check_purpose(pt, x, ca);
}

int X509_PURPOSE_set(int *p, int purpose)
{
	if(X509_PURPOSE_get_by_id(purpose) == -1) {
		OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_PURPOSE);
		return 0;
	}
	*p = purpose;
	return 1;
}

int X509_PURPOSE_get_count(void)
{
	if(!xptable) return X509_PURPOSE_COUNT;
	return sk_X509_PURPOSE_num(xptable) + X509_PURPOSE_COUNT;
}

X509_PURPOSE * X509_PURPOSE_get0(int idx)
{
	if(idx < 0) return NULL;
	if(idx < (int)X509_PURPOSE_COUNT) return xstandard + idx;
	return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT);
}

int X509_PURPOSE_get_by_sname(char *sname)
{
	int i;
	X509_PURPOSE *xptmp;
	for(i = 0; i < X509_PURPOSE_get_count(); i++) {
		xptmp = X509_PURPOSE_get0(i);
		if(!strcmp(xptmp->sname, sname)) return i;
	}
	return -1;
}

int X509_PURPOSE_get_by_id(int purpose)
{
	X509_PURPOSE tmp;
	size_t idx;

	if((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX))
		return purpose - X509_PURPOSE_MIN;
	tmp.purpose = purpose;
	if(!xptable) return -1;

	if (!sk_X509_PURPOSE_find(xptable, &idx, &tmp))
		return -1;
	return idx + X509_PURPOSE_COUNT;
}

int X509_PURPOSE_add(int id, int trust, int flags,
			int (*ck)(const X509_PURPOSE *, const X509 *, int),
					char *name, char *sname, void *arg)
{
	int idx;
	X509_PURPOSE *ptmp;
	char *name_dup, *sname_dup;

	/* This is set according to what we change: application can't set it */
	flags &= ~X509_PURPOSE_DYNAMIC;
	/* This will always be set for application modified trust entries */
	flags |= X509_PURPOSE_DYNAMIC_NAME;
	/* Get existing entry if any */
	idx = X509_PURPOSE_get_by_id(id);
	/* Need a new entry */
	if(idx == -1) {
		if(!(ptmp = OPENSSL_malloc(sizeof(X509_PURPOSE)))) {
			OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
			return 0;
		}
		ptmp->flags = X509_PURPOSE_DYNAMIC;
	} else ptmp = X509_PURPOSE_get0(idx);

	/* Duplicate the supplied names. */
	name_dup = BUF_strdup(name);
	sname_dup = BUF_strdup(sname);
	if (name_dup == NULL || sname_dup == NULL) {
		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
		if (name_dup != NULL)
			OPENSSL_free(name_dup);
		if (sname_dup != NULL)
			OPENSSL_free(sname_dup);
		if (idx == -1)
			OPENSSL_free(ptmp);
		return 0;
	}

	/* OPENSSL_free existing name if dynamic */
	if(ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) {
		OPENSSL_free(ptmp->name);
		OPENSSL_free(ptmp->sname);
	}
	/* dup supplied name */
	ptmp->name = name_dup;
	ptmp->sname = sname_dup;
	/* Keep the dynamic flag of existing entry */
	ptmp->flags &= X509_PURPOSE_DYNAMIC;
	/* Set all other flags */
	ptmp->flags |= flags;

	ptmp->purpose = id;
	ptmp->trust = trust;
	ptmp->check_purpose = ck;
	ptmp->usr_data = arg;

	/* If its a new entry manage the dynamic table */
	if(idx == -1) {
		if(!xptable && !(xptable = sk_X509_PURPOSE_new(xp_cmp))) {
			OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
			xptable_free(ptmp);
			return 0;
		}
		if (!sk_X509_PURPOSE_push(xptable, ptmp)) {
			OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
			xptable_free(ptmp);
			return 0;
		}
	}
	return 1;
}

static void xptable_free(X509_PURPOSE *p)
	{
	if(!p) return;
	if (p->flags & X509_PURPOSE_DYNAMIC) 
		{
		if (p->flags & X509_PURPOSE_DYNAMIC_NAME) {
			OPENSSL_free(p->name);
			OPENSSL_free(p->sname);
		}
		OPENSSL_free(p);
		}
	}

void X509_PURPOSE_cleanup(void)
{
	unsigned int i;
	sk_X509_PURPOSE_pop_free(xptable, xptable_free);
	for(i = 0; i < X509_PURPOSE_COUNT; i++) xptable_free(xstandard + i);
	xptable = NULL;
}

int X509_PURPOSE_get_id(X509_PURPOSE *xp)
{
	return xp->purpose;
}

char *X509_PURPOSE_get0_name(X509_PURPOSE *xp)
{
	return xp->name;
}

char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp)
{
	return xp->sname;
}

int X509_PURPOSE_get_trust(X509_PURPOSE *xp)
{
	return xp->trust;
}

static int nid_cmp(const void *void_a, const void *void_b)
	{
	const int *a = void_a, *b = void_b;

	return *a - *b;
	}

int X509_supported_extension(X509_EXTENSION *ex)
	{
	/* This table is a list of the NIDs of supported extensions:
	 * that is those which are used by the verify process. If
	 * an extension is critical and doesn't appear in this list
	 * then the verify process will normally reject the certificate.
	 * The list must be kept in numerical order because it will be
	 * searched using bsearch.
	 */

	static const int supported_nids[] = {
		NID_netscape_cert_type, /* 71 */
        	NID_key_usage,		/* 83 */
		NID_subject_alt_name,	/* 85 */
		NID_basic_constraints,	/* 87 */
		NID_certificate_policies, /* 89 */
        	NID_ext_key_usage,	/* 126 */
		NID_policy_constraints,	/* 401 */
		NID_proxyCertInfo,	/* 663 */
		NID_name_constraints,	/* 666 */
		NID_policy_mappings,	/* 747 */
		NID_inhibit_any_policy	/* 748 */
	};

	int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex));

	if (ex_nid == NID_undef) 
		return 0;

	if (bsearch(&ex_nid, supported_nids, sizeof(supported_nids)/sizeof(int), sizeof(int), nid_cmp) != NULL)
		return 1;
	return 0;
	}

static void setup_dp(X509 *x, DIST_POINT *dp)
	{
	X509_NAME *iname = NULL;
	size_t i;
	if (dp->reasons)
		{
		if (dp->reasons->length > 0)
			dp->dp_reasons = dp->reasons->data[0];
		if (dp->reasons->length > 1)
			dp->dp_reasons |= (dp->reasons->data[1] << 8);
		dp->dp_reasons &= CRLDP_ALL_REASONS;
		}
	else
		dp->dp_reasons = CRLDP_ALL_REASONS;
	if (!dp->distpoint || (dp->distpoint->type != 1))
		return;
	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)
			{
			iname = gen->d.directoryName;
			break;
			}
		}
	if (!iname)
		iname = X509_get_issuer_name(x);

	DIST_POINT_set_dpname(dp->distpoint, iname);

	}

static void setup_crldp(X509 *x)
	{
	size_t i;
	x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL);
	for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
		setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
	}

/* g_x509_cache_extensions_lock is used to protect against concurrent calls to
 * |x509v3_cache_extensions|. Ideally this would be done with a |CRYPTO_once_t|
 * in the |X509| structure, but |CRYPTO_once_t| isn't public.
 *
 * Note: it's not entirely clear whether this lock is needed. Not all paths to
 * this function took a lock in OpenSSL. */
static struct CRYPTO_STATIC_MUTEX g_x509_cache_extensions_lock =
    CRYPTO_STATIC_MUTEX_INIT;

static void x509v3_cache_extensions(X509 *x)
{
	BASIC_CONSTRAINTS *bs;
	PROXY_CERT_INFO_EXTENSION *pci;
	ASN1_BIT_STRING *usage;
	ASN1_BIT_STRING *ns;
	EXTENDED_KEY_USAGE *extusage;
	X509_EXTENSION *ex;
	size_t i;
	int j;

	CRYPTO_STATIC_MUTEX_lock_write(&g_x509_cache_extensions_lock);

	if(x->ex_flags & EXFLAG_SET)
		{
		CRYPTO_STATIC_MUTEX_unlock(&g_x509_cache_extensions_lock);
		return;
		}

	X509_digest(x, EVP_sha1(), x->sha1_hash, NULL);
	/* V1 should mean no extensions ... */
	if(!X509_get_version(x)) x->ex_flags |= EXFLAG_V1;
	/* Handle basic constraints */
	if((bs=X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) {
		if(bs->ca) x->ex_flags |= EXFLAG_CA;
		if(bs->pathlen) {
			if((bs->pathlen->type == V_ASN1_NEG_INTEGER)
						|| !bs->ca) {
				x->ex_flags |= EXFLAG_INVALID;
				x->ex_pathlen = 0;
			} else x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen);
		} else x->ex_pathlen = -1;
		BASIC_CONSTRAINTS_free(bs);
		x->ex_flags |= EXFLAG_BCONS;
	}
	/* Handle proxy certificates */
	if((pci=X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) {
		if (x->ex_flags & EXFLAG_CA
		    || X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0
		    || X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) {
			x->ex_flags |= EXFLAG_INVALID;
		}
		if (pci->pcPathLengthConstraint) {
			x->ex_pcpathlen =
				ASN1_INTEGER_get(pci->pcPathLengthConstraint);
		} else x->ex_pcpathlen = -1;
		PROXY_CERT_INFO_EXTENSION_free(pci);
		x->ex_flags |= EXFLAG_PROXY;
	}
	/* Handle key usage */
	if((usage=X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) {
		if(usage->length > 0) {
			x->ex_kusage = usage->data[0];
			if(usage->length > 1) 
				x->ex_kusage |= usage->data[1] << 8;
		} else x->ex_kusage = 0;
		x->ex_flags |= EXFLAG_KUSAGE;
		ASN1_BIT_STRING_free(usage);
	}
	x->ex_xkusage = 0;
	if((extusage=X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) {
		x->ex_flags |= EXFLAG_XKUSAGE;
		for(i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) {
			switch(OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage,i))) {
				case NID_server_auth:
				x->ex_xkusage |= XKU_SSL_SERVER;
				break;

				case NID_client_auth:
				x->ex_xkusage |= XKU_SSL_CLIENT;
				break;

				case NID_email_protect:
				x->ex_xkusage |= XKU_SMIME;
				break;

				case NID_code_sign:
				x->ex_xkusage |= XKU_CODE_SIGN;
				break;

				case NID_ms_sgc:
				case NID_ns_sgc:
				x->ex_xkusage |= XKU_SGC;
				break;

				case NID_OCSP_sign:
				x->ex_xkusage |= XKU_OCSP_SIGN;
				break;

				case NID_time_stamp:
				x->ex_xkusage |= XKU_TIMESTAMP;
				break;

				case NID_dvcs:
				x->ex_xkusage |= XKU_DVCS;
				break;

				case NID_anyExtendedKeyUsage:
				x->ex_xkusage |= XKU_ANYEKU;
				break;
			}
		}
		sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
	}

	if((ns=X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) {
		if(ns->length > 0) x->ex_nscert = ns->data[0];
		else x->ex_nscert = 0;
		x->ex_flags |= EXFLAG_NSCERT;
		ASN1_BIT_STRING_free(ns);
	}
	x->skid =X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL);
	x->akid =X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL);
	/* Does subject name match issuer ? */
	if(!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x)))
			{
			x->ex_flags |= EXFLAG_SI;
			/* If SKID matches AKID also indicate self signed */
			if (X509_check_akid(x, x->akid) == X509_V_OK &&
				!ku_reject(x, KU_KEY_CERT_SIGN))
				x->ex_flags |= EXFLAG_SS;
			}
	x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
	x->nc = X509_get_ext_d2i(x, NID_name_constraints, &j, NULL);
	if (!x->nc && (j != -1))
		x->ex_flags |= EXFLAG_INVALID;
	setup_crldp(x);

	for (j = 0; j < X509_get_ext_count(x); j++)
		{
		ex = X509_get_ext(x, j);
		if (OBJ_obj2nid(X509_EXTENSION_get_object(ex))
					== NID_freshest_crl)
			x->ex_flags |= EXFLAG_FRESHEST;
		if (!X509_EXTENSION_get_critical(ex))
			continue;
		if (!X509_supported_extension(ex))
			{
			x->ex_flags |= EXFLAG_CRITICAL;
			break;
			}
		}
	x->ex_flags |= EXFLAG_SET;

	CRYPTO_STATIC_MUTEX_unlock(&g_x509_cache_extensions_lock);
}

/* CA checks common to all purposes
 * return codes:
 * 0 not a CA
 * 1 is a CA
 * 2 basicConstraints absent so "maybe" a CA
 * 3 basicConstraints absent but self signed V1.
 * 4 basicConstraints absent but keyUsage present and keyCertSign asserted.
 */

static int check_ca(const X509 *x)
{
	/* keyUsage if present should allow cert signing */
	if(ku_reject(x, KU_KEY_CERT_SIGN)) return 0;
	if(x->ex_flags & EXFLAG_BCONS) {
		if(x->ex_flags & EXFLAG_CA) return 1;
		/* If basicConstraints says not a CA then say so */
		else return 0;
	} else {
		/* we support V1 roots for...  uh, I don't really know why. */
		if((x->ex_flags & V1_ROOT) == V1_ROOT) return 3;
		/* If key usage present it must have certSign so tolerate it */
		else if (x->ex_flags & EXFLAG_KUSAGE) return 4;
		/* Older certificates could have Netscape-specific CA types */
		else if (x->ex_flags & EXFLAG_NSCERT
			 && x->ex_nscert & NS_ANY_CA) return 5;
		/* can this still be regarded a CA certificate?  I doubt it */
		return 0;
	}
}

int X509_check_ca(X509 *x)
{
	if(!(x->ex_flags & EXFLAG_SET)) {
		x509v3_cache_extensions(x);
	}

	return check_ca(x);
}

/* Check SSL CA: common checks for SSL client and server */
static int check_ssl_ca(const X509 *x)
{
	int ca_ret;
	ca_ret = check_ca(x);
	if(!ca_ret) return 0;
	/* check nsCertType if present */
	if(ca_ret != 5 || x->ex_nscert & NS_SSL_CA) return ca_ret;
	else return 0;
}


static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca)
{
	if(xku_reject(x,XKU_SSL_CLIENT)) return 0;
	if(ca) return check_ssl_ca(x);
	/* We need to do digital signatures or key agreement */
	if(ku_reject(x,KU_DIGITAL_SIGNATURE|KU_KEY_AGREEMENT)) return 0;
	/* nsCertType if present should allow SSL client use */	
	if(ns_reject(x, NS_SSL_CLIENT)) return 0;
	return 1;
}
/* Key usage needed for TLS/SSL server: digital signature, encipherment or
 * key agreement. The ssl code can check this more thoroughly for individual
 * key types.
 */
#define KU_TLS \
	KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT|KU_KEY_AGREEMENT

static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca)
{
	if(xku_reject(x,XKU_SSL_SERVER|XKU_SGC)) return 0;
	if(ca) return check_ssl_ca(x);

	if(ns_reject(x, NS_SSL_SERVER)) return 0;
	if(ku_reject(x, KU_TLS)) return 0;
	
	return 1;

}

static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca)
{
	int ret;
	ret = check_purpose_ssl_server(xp, x, ca);
	if(!ret || ca) return ret;
	/* We need to encipher or Netscape complains */
	if(ku_reject(x, KU_KEY_ENCIPHERMENT)) return 0;
	return ret;
}

/* common S/MIME checks */
static int purpose_smime(const X509 *x, int ca)
{
	if(xku_reject(x,XKU_SMIME)) return 0;
	if(ca) {
		int ca_ret;
		ca_ret = check_ca(x);
		if(!ca_ret) return 0;
		/* check nsCertType if present */
		if(ca_ret != 5 || x->ex_nscert & NS_SMIME_CA) return ca_ret;
		else return 0;
	}
	if(x->ex_flags & EXFLAG_NSCERT) {
		if(x->ex_nscert & NS_SMIME) return 1;
		/* Workaround for some buggy certificates */
		if(x->ex_nscert & NS_SSL_CLIENT) return 2;
		return 0;
	}
	return 1;
}

static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca)
{
	int ret;
	ret = purpose_smime(x, ca);
	if(!ret || ca) return ret;
	if(ku_reject(x, KU_DIGITAL_SIGNATURE|KU_NON_REPUDIATION)) return 0;
	return ret;
}

static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca)
{
	int ret;
	ret = purpose_smime(x, ca);
	if(!ret || ca) return ret;
	if(ku_reject(x, KU_KEY_ENCIPHERMENT)) return 0;
	return ret;
}

static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca)
{
	if(ca) {
		int ca_ret;
		if((ca_ret = check_ca(x)) != 2) return ca_ret;
		else return 0;
	}
	if(ku_reject(x, KU_CRL_SIGN)) return 0;
	return 1;
}

/* OCSP helper: this is *not* a full OCSP check. It just checks that
 * each CA is valid. Additional checks must be made on the chain.
 */

static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca)
{
	/* Must be a valid CA.  Should we really support the "I don't know"
	   value (2)? */
	if(ca) return check_ca(x);
	/* leaf certificate is checked in OCSP_verify() */
	return 1;
}

static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
					int ca)
{
	int i_ext;

	/* If ca is true we must return if this is a valid CA certificate. */
	if (ca) return check_ca(x);

	/* 
	 * Check the optional key usage field:
	 * if Key Usage is present, it must be one of digitalSignature 
	 * and/or nonRepudiation (other values are not consistent and shall
	 * be rejected).
	 */
	if ((x->ex_flags & EXFLAG_KUSAGE)
	    && ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) ||
		!(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE))))
		return 0;

	/* Only time stamp key usage is permitted and it's required. */
	if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP)
		return 0;

	/* Extended Key Usage MUST be critical */
	i_ext = X509_get_ext_by_NID((X509 *) x, NID_ext_key_usage, -1);
	if (i_ext >= 0)
		{
		X509_EXTENSION *ext = X509_get_ext((X509 *) x, i_ext);
		if (!X509_EXTENSION_get_critical(ext))
			return 0;
		}

	return 1;
}

static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca)
{
	return 1;
}

/* Various checks to see if one certificate issued the second.
 * This can be used to prune a set of possible issuer certificates
 * which have been looked up using some simple method such as by
 * subject name.
 * These are:
 * 1. Check issuer_name(subject) == subject_name(issuer)
 * 2. If akid(subject) exists check it matches issuer
 * 3. If key_usage(issuer) exists check it supports certificate signing
 * returns 0 for OK, positive for reason for mismatch, reasons match
 * codes for X509_verify_cert()
 */

int X509_check_issued(X509 *issuer, X509 *subject)
{
	if(X509_NAME_cmp(X509_get_subject_name(issuer),
			X509_get_issuer_name(subject)))
				return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
	x509v3_cache_extensions(issuer);
	x509v3_cache_extensions(subject);

	if(subject->akid)
		{
		int ret = X509_check_akid(issuer, subject->akid);
		if (ret != X509_V_OK)
			return ret;
		}

	if(subject->ex_flags & EXFLAG_PROXY)
		{
		if(ku_reject(issuer, KU_DIGITAL_SIGNATURE))
			return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE;
		}
	else if(ku_reject(issuer, KU_KEY_CERT_SIGN))
		return X509_V_ERR_KEYUSAGE_NO_CERTSIGN;
	return X509_V_OK;
}

int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid)
	{

	if(!akid)
		return X509_V_OK;

	/* Check key ids (if present) */
	if(akid->keyid && issuer->skid &&
		 ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid) )
				return X509_V_ERR_AKID_SKID_MISMATCH;
	/* Check serial number */
	if(akid->serial &&
		ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial))
				return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
	/* Check issuer name */
	if(akid->issuer)
		{
		/* Ugh, for some peculiar reason AKID includes
		 * SEQUENCE OF GeneralName. So look for a DirName.
		 * There may be more than one but we only take any
		 * notice of the first.
		 */
		GENERAL_NAMES *gens;
		GENERAL_NAME *gen;
		X509_NAME *nm = NULL;
		size_t i;
		gens = akid->issuer;
		for(i = 0; i < sk_GENERAL_NAME_num(gens); i++)
			{
			gen = sk_GENERAL_NAME_value(gens, i);
			if(gen->type == GEN_DIRNAME)
				{
				nm = gen->d.dirn;
				break;
				}
			}
		if(nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer)))
			return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
		}
	return X509_V_OK;
	}

