/* 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"

/* Enable this to print out the complete policy tree at various point during
 * evaluation.
 */

/*#define OPENSSL_POLICY_DEBUG*/

#ifdef OPENSSL_POLICY_DEBUG

static void expected_print(BIO *err, X509_POLICY_LEVEL *lev,
				X509_POLICY_NODE *node, int indent)
	{
	if (	    (lev->flags & X509_V_FLAG_INHIBIT_MAP)
		|| !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK))
		BIO_puts(err, "  Not Mapped\n");
	else
		{
		int i;
		STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set;
		ASN1_OBJECT *oid;
		BIO_puts(err, "  Expected: ");
		for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++)
			{
			oid = sk_ASN1_OBJECT_value(pset, i);
			if (i)
				BIO_puts(err, ", ");
			i2a_ASN1_OBJECT(err, oid);
			}
		BIO_puts(err, "\n");
		}
	}

static void tree_print(char *str, X509_POLICY_TREE *tree,
			X509_POLICY_LEVEL *curr)
	{
	X509_POLICY_LEVEL *plev;
	X509_POLICY_NODE *node;
	int i;
	BIO *err;
	err = BIO_new_fp(stderr, BIO_NOCLOSE);
	if (!curr)
		curr = tree->levels + tree->nlevel;
	else
		curr++;
	BIO_printf(err, "Level print after %s\n", str);
	BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels);
	for (plev = tree->levels; plev != curr; plev++)
		{
		BIO_printf(err, "Level %ld, flags = %x\n",
				plev - tree->levels, plev->flags);
		for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++)
			{
			node = sk_X509_POLICY_NODE_value(plev->nodes, i);
			X509_POLICY_NODE_print(err, node, 2);
			expected_print(err, plev, node, 2);
			BIO_printf(err, "  Flags: %x\n", node->data->flags);
			}
		if (plev->anyPolicy)
			X509_POLICY_NODE_print(err, plev->anyPolicy, 2);
		}

	BIO_free(err);

	}
#else

#define tree_print(a,b,c) /* */

#endif

/* 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);

#if 0
	/* Disable policy mapping for now... */
	flags |= X509_V_FLAG_INHIBIT_MAP;
#endif

	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
			{
			if (!(x->ex_flags & EXFLAG_SI))
				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;

	}

static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
				const X509_POLICY_DATA *data)
	{
	X509_POLICY_LEVEL *last = curr - 1;
	X509_POLICY_NODE *node;
	int i, matched = 0;
	/* Iterate through all in nodes linking matches */
	for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
		{
		node = sk_X509_POLICY_NODE_value(last->nodes, i);
		if (policy_node_match(last, node, data->valid_policy))
			{
			if (!level_add_node(curr, data, node, NULL))
				return 0;
			matched = 1;
			}
		}
	if (!matched && last->anyPolicy)
		{
		if (!level_add_node(curr, data, last->anyPolicy, NULL))
			return 0;
		}
	return 1;
	}

/* This corresponds to RFC3280 6.1.3(d)(1):
 * 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;
	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 0
		if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY)
			&& !(curr->flags & X509_V_FLAG_INHIBIT_ANY))
			continue;
#endif
		/* Look for matching nodes in previous level */
		if (!tree_link_matching_nodes(curr, data))
				return 0;
		}
	return 1;
	}

/* This corresponds to RFC3280 6.1.3(d)(2):
 * Create new data for any unmatched policies in the parent and link
 * to anyPolicy.
 */

static int tree_add_unmatched(X509_POLICY_LEVEL *curr,
			const X509_POLICY_CACHE *cache,
			const ASN1_OBJECT *id,
			X509_POLICY_NODE *node,
			X509_POLICY_TREE *tree)
	{
	X509_POLICY_DATA *data;
	if (id == NULL)
		id = node->data->valid_policy;
	/* Create a new node with qualifiers from anyPolicy and
	 * id from unmatched node.
	 */
	data = policy_data_new(NULL, id, 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;
		}

	return 1;
	}

static int tree_link_unmatched(X509_POLICY_LEVEL *curr,
			const X509_POLICY_CACHE *cache,
			X509_POLICY_NODE *node,
			X509_POLICY_TREE *tree)
	{
	const X509_POLICY_LEVEL *last = curr - 1;
	int i;

	if (	    (last->flags & X509_V_FLAG_INHIBIT_MAP)
		|| !(node->data->flags & POLICY_DATA_FLAG_MAPPED))
		{
		/* If no policy mapping: matched if one child present */
		if (node->nchild)
			return 1;
		if (!tree_add_unmatched(curr, cache, NULL, node, tree))
			return 0;
		/* Add it */
		}
	else
		{
		/* If mapping: matched if one child per expected policy set */
		STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set;
		if (node->nchild == sk_ASN1_OBJECT_num(expset))
			return 1;
		/* Locate unmatched nodes */
		for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++)
			{
			ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i);
			if (level_find_node(curr, node, oid))
				continue;
			if (!tree_add_unmatched(curr, cache, oid, node, tree))
				return 0;
			}

		}

	return 1;

	}

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 = curr - 1;

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

		if (!tree_link_unmatched(curr, cache, node, tree))
			return 0;

#if 0

		/* 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;
			}

#endif

		}
	/* 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)
	{
	STACK_OF(X509_POLICY_NODE) *nodes;
	X509_POLICY_NODE *node;
	int i;
	nodes = curr->nodes;
	if (curr->flags & X509_V_FLAG_INHIBIT_MAP)
		{
		for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--)
			{
			node = sk_X509_POLICY_NODE_value(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(nodes,i);
				}
			}
		}

	for(;;)	{
		--curr;
		nodes = curr->nodes;
		for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--)
			{
			node = sk_X509_POLICY_NODE_value(nodes, i);
			if (node->nchild == 0)
				{
				node->parent->nchild--;
				OPENSSL_free(node);
				(void)sk_X509_POLICY_NODE_delete(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;
	tree_print("before tree_prune()", tree, curr);
		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 -1:
		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);

	tree_print("tree_evaluate()", tree, NULL);

	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;

	}

