/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
 * project 1999. */
/* ====================================================================
 * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com). */

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


static int tr_cmp(const X509_TRUST **a,
		const X509_TRUST **b);
static void trtable_free(X509_TRUST *p);

static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags);
static int trust_1oid(X509_TRUST *trust, X509 *x, int flags);
static int trust_compat(X509_TRUST *trust, X509 *x, int flags);

static int obj_trust(int id, X509 *x, int flags);
static int (*default_trust)(int id, X509 *x, int flags) = obj_trust;

/* WARNING: the following table should be kept in order of trust
 * and without any gaps so we can just subtract the minimum trust
 * value to get an index into the table
 */

static X509_TRUST trstandard[] = {
{X509_TRUST_COMPAT, 0, trust_compat, (char *) "compatible", 0, NULL},
{X509_TRUST_SSL_CLIENT, 0, trust_1oidany, (char *) "SSL Client", NID_client_auth, NULL},
{X509_TRUST_SSL_SERVER, 0, trust_1oidany, (char *) "SSL Server", NID_server_auth, NULL},
{X509_TRUST_EMAIL, 0, trust_1oidany, (char *) "S/MIME email", NID_email_protect, NULL},
{X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, (char *) "Object Signer", NID_code_sign, NULL},
{X509_TRUST_OCSP_SIGN, 0, trust_1oid, (char *) "OCSP responder", NID_OCSP_sign, NULL},
{X509_TRUST_OCSP_REQUEST, 0, trust_1oid, (char *) "OCSP request", NID_ad_OCSP, NULL},
{X509_TRUST_TSA, 0, trust_1oidany, (char *) "TSA server", NID_time_stamp, NULL}
};

#define X509_TRUST_COUNT	(sizeof(trstandard)/sizeof(X509_TRUST))

static STACK_OF(X509_TRUST) *trtable = NULL;

static int tr_cmp(const X509_TRUST **a,
		const X509_TRUST **b)
{
	return (*a)->trust - (*b)->trust;
}

int (*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int)
{
	int (*oldtrust)(int , X509 *, int);
	oldtrust = default_trust;
	default_trust = trust;
	return oldtrust;
}


int X509_check_trust(X509 *x, int id, int flags)
{
	X509_TRUST *pt;
	int idx;
	if(id == -1) return 1;
	/* We get this as a default value */
	if (id == 0)
		{
		int rv;
		rv = obj_trust(NID_anyExtendedKeyUsage, x, 0);
		if (rv != X509_TRUST_UNTRUSTED)
			return rv;
		return trust_compat(NULL, x, 0);
		}
	idx = X509_TRUST_get_by_id(id);
	if(idx == -1) return default_trust(id, x, flags);
	pt = X509_TRUST_get0(idx);
	return pt->check_trust(pt, x, flags);
}

int X509_TRUST_get_count(void)
{
	if(!trtable) return X509_TRUST_COUNT;
	return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT;
}

X509_TRUST * X509_TRUST_get0(int idx)
{
	if(idx < 0) return NULL;
	if(idx < (int)X509_TRUST_COUNT) return trstandard + idx;
	return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT);
}

int X509_TRUST_get_by_id(int id)
{
	X509_TRUST tmp;
	size_t idx;

	if((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX))
				 return id - X509_TRUST_MIN;
	tmp.trust = id;
	if(!trtable) return -1;
	if (!sk_X509_TRUST_find(trtable, &idx, &tmp)) {
		return -1;
	}
	return idx + X509_TRUST_COUNT;
}

int X509_TRUST_set(int *t, int trust)
{
	if(X509_TRUST_get_by_id(trust) == -1) {
		OPENSSL_PUT_ERROR(X509, X509_R_INVALID_TRUST);
		return 0;
	}
	*t = trust;
	return 1;
}

int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int),
					char *name, int arg1, void *arg2)
{
	int idx;
	X509_TRUST *trtmp;
	char *name_dup;

	/* This is set according to what we change: application can't set it */
	flags &= ~X509_TRUST_DYNAMIC;
	/* This will always be set for application modified trust entries */
	flags |= X509_TRUST_DYNAMIC_NAME;
	/* Get existing entry if any */
	idx = X509_TRUST_get_by_id(id);
	/* Need a new entry */
	if(idx == -1) {
		if(!(trtmp = OPENSSL_malloc(sizeof(X509_TRUST)))) {
			OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
			return 0;
		}
		trtmp->flags = X509_TRUST_DYNAMIC;
	} else trtmp = X509_TRUST_get0(idx);

	/* Duplicate the supplied name. */
	name_dup = BUF_strdup(name);
	if (name_dup == NULL) {
		OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
		if (idx == -1)
			OPENSSL_free(trtmp);
		return 0;
	}

	/* OPENSSL_free existing name if dynamic */
	if (trtmp->flags & X509_TRUST_DYNAMIC_NAME) OPENSSL_free(trtmp->name);
	trtmp->name = name_dup;
	/* Keep the dynamic flag of existing entry */
	trtmp->flags &= X509_TRUST_DYNAMIC;
	/* Set all other flags */
	trtmp->flags |= flags;

	trtmp->trust = id;
	trtmp->check_trust = ck;
	trtmp->arg1 = arg1;
	trtmp->arg2 = arg2;

	/* If its a new entry manage the dynamic table */
	if(idx == -1) {
		if(!trtable && !(trtable = sk_X509_TRUST_new(tr_cmp))) {
			OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
			trtable_free(trtmp);
			return 0;
		}
		if (!sk_X509_TRUST_push(trtable, trtmp)) {
			OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
			trtable_free(trtmp);
			return 0;
		}
	}
	return 1;
}

static void trtable_free(X509_TRUST *p)
	{
	if(!p) return;
	if (p->flags & X509_TRUST_DYNAMIC) 
		{
		if (p->flags & X509_TRUST_DYNAMIC_NAME)
			OPENSSL_free(p->name);
		OPENSSL_free(p);
		}
	}

void X509_TRUST_cleanup(void)
{
	unsigned int i;
	for(i = 0; i < X509_TRUST_COUNT; i++) trtable_free(trstandard + i);
	sk_X509_TRUST_pop_free(trtable, trtable_free);
	trtable = NULL;
}

int X509_TRUST_get_flags(X509_TRUST *xp)
{
	return xp->flags;
}

char *X509_TRUST_get0_name(X509_TRUST *xp)
{
	return xp->name;
}

int X509_TRUST_get_trust(X509_TRUST *xp)
{
	return xp->trust;
}

static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags)
{
	if(x->aux && (x->aux->trust || x->aux->reject))
		return obj_trust(trust->arg1, x, flags);
	/* we don't have any trust settings: for compatibility
	 * we return trusted if it is self signed
	 */
	return trust_compat(trust, x, flags);
}

static int trust_1oid(X509_TRUST *trust, X509 *x, int flags)
{
	if(x->aux) return obj_trust(trust->arg1, x, flags);
	return X509_TRUST_UNTRUSTED;
}

static int trust_compat(X509_TRUST *trust, X509 *x, int flags)
{
	X509_check_purpose(x, -1, 0);
	if(x->ex_flags & EXFLAG_SS) return X509_TRUST_TRUSTED;
	else return X509_TRUST_UNTRUSTED;
}

static int obj_trust(int id, X509 *x, int flags)
{
	ASN1_OBJECT *obj;
	size_t i;
	X509_CERT_AUX *ax;
	ax = x->aux;
	if(!ax) return X509_TRUST_UNTRUSTED;
	if(ax->reject) {
		for(i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) {
			obj = sk_ASN1_OBJECT_value(ax->reject, i);
			if(OBJ_obj2nid(obj) == id) return X509_TRUST_REJECTED;
		}
	}	
	if(ax->trust) {
		for(i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) {
			obj = sk_ASN1_OBJECT_value(ax->trust, i);
			if(OBJ_obj2nid(obj) == id) return X509_TRUST_TRUSTED;
		}
	}
	return X509_TRUST_UNTRUSTED;
}

