/* 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 <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/stack.h>
#include <openssl/thread.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 matched = 0;
	size_t i;
	/* 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)
	{
	size_t 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;
	size_t 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)
	{
	size_t 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, NULL, pcy))
		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;
	size_t 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)
	{
	size_t 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;

	}

