/* 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->levels)
		{
		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_DATA *data;

	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;

	}

