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

}
