/*
 * 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 <string.h>

#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"
#include "../internal.h"
#include "../x509/internal.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 occurred.
 * -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;
    }

    OPENSSL_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);
        X509_up_ref(x);
        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,
                                    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 RFC 3280 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 RFC 3280 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 ((size_t)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 RFC 3280 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;
        }
    }

}

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 {
      sk_X509_POLICY_NODE_sort(*pnodes);
      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;
    int calc_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 */

    calc_ret = tree_calculate_authority_set(tree, &auth_nodes);

    if (!calc_ret)
        goto error;

    ret = tree_calculate_user_set(tree, policy_oids, auth_nodes);

    if (calc_ret == 2)
        sk_X509_POLICY_NODE_free(auth_nodes);

    if (!ret)
        goto error;


    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;

}
