/* pcy_tree.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
 * project 2004.
 */
/* ====================================================================
 * Copyright (c) 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 "cryptlib.h"
#include <openssl/x509.h>
#include <openssl/x509v3.h>

#include "pcy_int.h"

/* Initialize policy tree. Return values:
 *  0 Some internal error occured.
 * -1 Inconsistent or invalid extensions in certificates.
 *  1 Tree initialized OK.
 *  2 Policy tree is empty.
 *  5 Tree OK and requireExplicitPolicy true.
 *  6 Tree empty and requireExplicitPolicy true.
 */

static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
			unsigned int flags)
	{
	X509_POLICY_TREE *tree;
	X509_POLICY_LEVEL *level;
	const X509_POLICY_CACHE *cache;
	X509_POLICY_DATA *data = NULL;
	X509 *x;
	int ret = 1;
	int i, n;
	int explicit_policy;
	int any_skip;
	int map_skip;
	*ptree = NULL;
	n = sk_X509_num(certs);

	/* Disable policy mapping for now... */
	flags |= X509_V_FLAG_INHIBIT_MAP;

	if (flags & X509_V_FLAG_EXPLICIT_POLICY)
		explicit_policy = 0;
	else
		explicit_policy = n + 1;

	if (flags & X509_V_FLAG_INHIBIT_ANY)
		any_skip = 0;
	else
		any_skip = n + 1;

	if (flags & X509_V_FLAG_INHIBIT_MAP)
		map_skip = 0;
	else
		map_skip = n + 1;

	/* Can't do anything with just a trust anchor */
	if (n == 1)
		return 1;
	/* First setup policy cache in all certificates apart from the
	 * trust anchor. Note any bad cache results on the way. Also can
	 * calculate explicit_policy value at this point.
	 */
	for (i = n - 2; i >= 0; i--)
		{
		x = sk_X509_value(certs, i);
		X509_check_purpose(x, -1, -1);
		cache = policy_cache_set(x);
		/* If cache NULL something bad happened: return immediately */
		if (cache == NULL)
			return 0;
		/* If inconsistent extensions keep a note of it but continue */
		if (x->ex_flags & EXFLAG_INVALID_POLICY)
			ret = -1;
		/* Otherwise if we have no data (hence no CertificatePolicies)
		 * and haven't already set an inconsistent code note it.
		 */
		else if ((ret == 1) && !cache->data)
			ret = 2;
		if (explicit_policy > 0)
			{
			if (!(x->ex_flags & EXFLAG_SI))
				explicit_policy--;
			if ((cache->explicit_skip != -1)
				&& (cache->explicit_skip < explicit_policy))
				explicit_policy = cache->explicit_skip;
			}
		}

	if (ret != 1)
		{
		if (ret == 2 && !explicit_policy)
			return 6;
		return ret;
		}


	/* If we get this far initialize the tree */

	tree = OPENSSL_malloc(sizeof(X509_POLICY_TREE));

	if (!tree)
		return 0;

	tree->flags = 0;
	tree->levels = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL) * n);
	tree->nlevel = 0;
	tree->extra_data = NULL;
	tree->auth_policies = NULL;
	tree->user_policies = NULL;

	if (!tree)
		{
		OPENSSL_free(tree);
		return 0;
		}

	memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL));

	tree->nlevel = n;

	level = tree->levels;

	/* Root data: initialize to anyPolicy */

	data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0);

	if (!data || !level_add_node(level, data, NULL, tree))
		goto bad_tree;

	for (i = n - 2; i >= 0; i--)
		{
		level++;
		x = sk_X509_value(certs, i);
		cache = policy_cache_set(x);

		CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
		level->cert = x;

		if (!cache->anyPolicy)
				level->flags |= X509_V_FLAG_INHIBIT_ANY;

		/* Determine inhibit any and inhibit map flags */
		if (any_skip == 0)
			{
			/* Any matching allowed if certificate is self
			 * issued and not the last in the chain.
			 */
			if (!(x->ex_flags & EXFLAG_SI) || (i == 0))
				level->flags |= X509_V_FLAG_INHIBIT_ANY;
			}
		else
			{
			if (!(x->ex_flags & EXFLAG_SI))
				any_skip--;
			if ((cache->any_skip >= 0)
				&& (cache->any_skip < any_skip))
				any_skip = cache->any_skip;
			}

		if (map_skip == 0)
			level->flags |= X509_V_FLAG_INHIBIT_MAP;
		else
			{
			map_skip--;
			if ((cache->map_skip >= 0)
				&& (cache->map_skip < map_skip))
				map_skip = cache->map_skip;
			}


		}

	*ptree = tree;

	if (explicit_policy)
		return 1;
	else
		return 5;

	bad_tree:

	X509_policy_tree_free(tree);

	return 0;

	}

/* This corresponds to RFC3280 XXXX XXXXX:
 * link any data from CertificatePolicies onto matching parent
 * or anyPolicy if no match.
 */

static int tree_link_nodes(X509_POLICY_LEVEL *curr,
				const X509_POLICY_CACHE *cache)
	{
	int i;
	X509_POLICY_LEVEL *last;
	X509_POLICY_DATA *data;
	X509_POLICY_NODE *parent;
	last = curr - 1;
	for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++)
		{
		data = sk_X509_POLICY_DATA_value(cache->data, i);
		/* If a node is mapped any it doesn't have a corresponding
		 * CertificatePolicies entry. 
		 * However such an identical node would be created
		 * if anyPolicy matching is enabled because there would be
		 * no match with the parent valid_policy_set. So we create
		 * link because then it will have the mapping flags
		 * right and we can prune it later.
		 */
		if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY)
			&& !(curr->flags & X509_V_FLAG_INHIBIT_ANY))
			continue;
		/* Look for matching node in parent */
		parent = level_find_node(last, data->valid_policy);
		/* If no match link to anyPolicy */
		if (!parent)
			parent = last->anyPolicy;
		if (parent && !level_add_node(curr, data, parent, NULL))
				return 0;
		}
	return 1;
	}

/* This corresponds to RFC3280 XXXX XXXXX:
 * Create new data for any unmatched policies in the parent and link
 * to anyPolicy.
 */

static int tree_link_any(X509_POLICY_LEVEL *curr,
			const X509_POLICY_CACHE *cache,
			X509_POLICY_TREE *tree)
	{
	int i;
	X509_POLICY_DATA *data;
	X509_POLICY_NODE *node;
	X509_POLICY_LEVEL *last;

	last = curr - 1;

	for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
		{
		node = sk_X509_POLICY_NODE_value(last->nodes, i);

		/* Skip any node with any children: we only want unmathced
		 * nodes.
		 *
		 * Note: need something better for policy mapping
		 * because each node may have multiple children 
		 */
		if (node->nchild)
			continue;
		/* Create a new node with qualifiers from anyPolicy and
		 * id from unmatched node.
		 */
		data = policy_data_new(NULL, node->data->valid_policy, 
						node_critical(node));

		if (data == NULL)
			return 0;
		/* Curr may not have anyPolicy */
		data->qualifier_set = cache->anyPolicy->qualifier_set;
		data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
		if (!level_add_node(curr, data, node, tree))
			{
			policy_data_free(data);
			return 0;
			}
		}
	/* Finally add link to anyPolicy */
	if (last->anyPolicy)
		{
		if (!level_add_node(curr, cache->anyPolicy,
						last->anyPolicy, NULL))
			return 0;
		}
	return 1;
	}

/* Prune the tree: delete any child mapped child data on the current level
 * then proceed up the tree deleting any data with no children. If we ever
 * have no data on a level we can halt because the tree will be empty.
 */

static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
	{
	X509_POLICY_NODE *node;
	int i;
	for (i = sk_X509_POLICY_NODE_num(curr->nodes) - 1; i >= 0; i--)
		{
		node = sk_X509_POLICY_NODE_value(curr->nodes, i);
		/* Delete any mapped data: see RFC3280 XXXX */
		if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK)
			{
			node->parent->nchild--;
			OPENSSL_free(node);
			(void)sk_X509_POLICY_NODE_delete(curr->nodes, i);
			}
		}

	for(;;)	{
		--curr;
		for (i = sk_X509_POLICY_NODE_num(curr->nodes) - 1; i >= 0; i--)
			{
			node = sk_X509_POLICY_NODE_value(curr->nodes, i);
			if (node->nchild == 0)
				{
				node->parent->nchild--;
				OPENSSL_free(node);
				(void)sk_X509_POLICY_NODE_delete(curr->nodes, i);
				}
			}
		if (curr->anyPolicy && !curr->anyPolicy->nchild)
			{
			if (curr->anyPolicy->parent)
				curr->anyPolicy->parent->nchild--;
			OPENSSL_free(curr->anyPolicy);
			curr->anyPolicy = NULL;
			}
		if (curr == tree->levels)
			{
			/* If we zapped anyPolicy at top then tree is empty */
			if (!curr->anyPolicy)
					return 2;
			return 1;
			}
		}

	return 1;

	}

static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes,
						 X509_POLICY_NODE *pcy)
	{
	if (!*pnodes)
		{
		*pnodes = policy_node_cmp_new();
		if (!*pnodes)
			return 0;
		}
	else if (sk_X509_POLICY_NODE_find(*pnodes, pcy) != -1)
		return 1;

	if (!sk_X509_POLICY_NODE_push(*pnodes, pcy))
		return 0;

	return 1;

	}

/* Calculate the authority set based on policy tree.
 * The 'pnodes' parameter is used as a store for the set of policy nodes
 * used to calculate the user set. If the authority set is not anyPolicy
 * then pnodes will just point to the authority set. If however the authority
 * set is anyPolicy then the set of valid policies (other than anyPolicy)
 * is store in pnodes. The return value of '2' is used in this case to indicate
 * that pnodes should be freed.
 */

static int tree_calculate_authority_set(X509_POLICY_TREE *tree,
					STACK_OF(X509_POLICY_NODE) **pnodes)
	{
	X509_POLICY_LEVEL *curr;
	X509_POLICY_NODE *node, *anyptr;
	STACK_OF(X509_POLICY_NODE) **addnodes;
	int i, j;
	curr = tree->levels + tree->nlevel - 1;

	/* If last level contains anyPolicy set is anyPolicy */
	if (curr->anyPolicy)
		{
		if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy))
			return 0;
		addnodes = pnodes;
		}
	else
		/* Add policies to authority set */
		addnodes = &tree->auth_policies;

	curr = tree->levels;
	for (i = 1; i < tree->nlevel; i++)
		{
		/* If no anyPolicy node on this this level it can't
		 * appear on lower levels so end search.
		 */
		if (!(anyptr = curr->anyPolicy))
			break;
		curr++;
		for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++)
			{
			node = sk_X509_POLICY_NODE_value(curr->nodes, j);
			if ((node->parent == anyptr)
				&& !tree_add_auth_node(addnodes, node))
					return 0;
			}
		}

	if (addnodes == pnodes)
		return 2;

	*pnodes = tree->auth_policies;

	return 1;
	}

static int tree_calculate_user_set(X509_POLICY_TREE *tree,
				STACK_OF(ASN1_OBJECT) *policy_oids,
				STACK_OF(X509_POLICY_NODE) *auth_nodes)
	{
	int i;
	X509_POLICY_NODE *node;
	ASN1_OBJECT *oid;

	X509_POLICY_NODE *anyPolicy;
	X509_POLICY_DATA *extra;

	/* Check if anyPolicy present in authority constrained policy set:
	 * this will happen if it is a leaf node.
	 */

	if (sk_ASN1_OBJECT_num(policy_oids) <= 0)
		return 1;

	anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy;

	for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++)
		{
		oid = sk_ASN1_OBJECT_value(policy_oids, i);
		if (OBJ_obj2nid(oid) == NID_any_policy)
			{
			tree->flags |= POLICY_FLAG_ANY_POLICY;
			return 1;
			}
		}

	for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++)
		{
		oid = sk_ASN1_OBJECT_value(policy_oids, i);
		node = tree_find_sk(auth_nodes, oid);
		if (!node)
			{
			if (!anyPolicy)
				continue;
			/* Create a new node with policy ID from user set
			 * and qualifiers from anyPolicy.
			 */
			extra = policy_data_new(NULL, oid,
						node_critical(anyPolicy));
			if (!extra)
				return 0;
			extra->qualifier_set = anyPolicy->data->qualifier_set;
			extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS
						| POLICY_DATA_FLAG_EXTRA_NODE;
			node = level_add_node(NULL, extra, anyPolicy->parent,
						tree);
			}
		if (!tree->user_policies)
			{
			tree->user_policies = sk_X509_POLICY_NODE_new_null();
			if (!tree->user_policies)
				return 1;
			}
		if (!sk_X509_POLICY_NODE_push(tree->user_policies, node))
			return 0;
		}
	return 1;

	}

static int tree_evaluate(X509_POLICY_TREE *tree)
	{
	int ret, i;
	X509_POLICY_LEVEL *curr = tree->levels + 1;
	const X509_POLICY_CACHE *cache;

	for(i = 1; i < tree->nlevel; i++, curr++)
		{
		cache = policy_cache_set(curr->cert);
		if (!tree_link_nodes(curr, cache))
			return 0;

		if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)
			&& !tree_link_any(curr, cache, tree))
			return 0;
		ret = tree_prune(tree, curr);
		if (ret != 1)
			return ret;
		}

	return 1;

	}

static void exnode_free(X509_POLICY_NODE *node)
	{
	if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE))
		OPENSSL_free(node);
	}


void X509_policy_tree_free(X509_POLICY_TREE *tree)
	{
	X509_POLICY_LEVEL *curr;
	int i;

	if (!tree)
		return;

	sk_X509_POLICY_NODE_free(tree->auth_policies);
	sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free);

	for(i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++)
		{
		if (curr->cert)
			X509_free(curr->cert);
		if (curr->nodes)
			sk_X509_POLICY_NODE_pop_free(curr->nodes,
						policy_node_free);
		if (curr->anyPolicy)
			policy_node_free(curr->anyPolicy);
		}

	if (tree->extra_data)
		sk_X509_POLICY_DATA_pop_free(tree->extra_data,
						policy_data_free);

	OPENSSL_free(tree->levels);
	OPENSSL_free(tree);

	}

/* Application policy checking function.
 * Return codes:
 *  0 	Internal Error.
 *  1   Successful.
 * -1   One or more certificates contain invalid or inconsistent extensions
 * -2	User constrained policy set empty and requireExplicit true.
 */

int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
			STACK_OF(X509) *certs,
			STACK_OF(ASN1_OBJECT) *policy_oids,
			unsigned int flags)
	{
	int ret;
	X509_POLICY_TREE *tree = NULL;
	STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL;
	*ptree = NULL;

	*pexplicit_policy = 0;
	ret = tree_init(&tree, certs, flags);


	switch (ret)
		{

		/* Tree empty requireExplicit False: OK */
		case 2:
		return 1;

		/* Some internal error */
		case 0:
		return 0;

		/* Tree empty requireExplicit True: Error */

		case 6:
		*pexplicit_policy = 1;
		return -2;

		/* Tree OK requireExplicit True: OK and continue */
		case 5:
		*pexplicit_policy = 1;
		break;

		/* Tree OK: continue */

		case 1:
		if (!tree)
			/*
			 * tree_init() returns success and a null tree
			 * if it's just looking at a trust anchor.
			 * I'm not sure that returning success here is
			 * correct, but I'm sure that reporting this
			 * as an internal error which our caller
			 * interprets as a malloc failure is wrong.
			 */
			return 1;
		break;
		}

	if (!tree) goto error;
	ret = tree_evaluate(tree);

	if (ret <= 0)
		goto error;

	/* Return value 2 means tree empty */
	if (ret == 2)
		{
		X509_policy_tree_free(tree);
		if (*pexplicit_policy)
			return -2;
		else
			return 1;
		}

	/* Tree is not empty: continue */

	ret = tree_calculate_authority_set(tree, &auth_nodes);

	if (!ret)
		goto error;

	if (!tree_calculate_user_set(tree, policy_oids, auth_nodes))
		goto error;
	
	if (ret == 2)
		sk_X509_POLICY_NODE_free(auth_nodes);

	if (tree)
		*ptree = tree;

	if (*pexplicit_policy)
		{
		nodes = X509_policy_tree_get0_user_policies(tree);
		if (sk_X509_POLICY_NODE_num(nodes) <= 0)
			return -2;
		}

	return 1;

	error:

	X509_policy_tree_free(tree);

	return 0;

	}

