/*
 * 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 "internal/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)
{
    BIO *err = BIO_new_fp(stderr, BIO_NOCLOSE);
    X509_POLICY_LEVEL *plev;

    if (err == NULL)
        return;
    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++) {
        int i;

        BIO_printf(err, "Level %ld, flags = %x\n",
                   (long)(plev - tree->levels), plev->flags);
        for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++) {
            X509_POLICY_NODE *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);
}
#endif

/*-
 * Return value: <= 0 on error, or positive bit mask:
 *
 * X509_PCY_TREE_VALID: valid tree
 * X509_PCY_TREE_EMPTY: empty tree (including bare TA case)
 * X509_PCY_TREE_EXPLICIT: explicit policy required
 */
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;
    int ret = X509_PCY_TREE_VALID;
    int n = sk_X509_num(certs) - 1; /* RFC5280 paths omit the TA */
    int explicit_policy = (flags & X509_V_FLAG_EXPLICIT_POLICY) ? 0 : n+1;
    int any_skip = (flags & X509_V_FLAG_INHIBIT_ANY) ? 0 : n+1;
    int map_skip = (flags & X509_V_FLAG_INHIBIT_MAP) ? 0 : n+1;
    int i;

    *ptree = NULL;

    /* Can't do anything with just a trust anchor */
    if (n == 0)
        return X509_PCY_TREE_EMPTY;

    /*
     * First setup the policy cache in all n non-TA certificates, this will be
     * used in X509_verify_cert() which will invoke the verify callback for all
     * certificates with invalid policy extensions.
     */
    for (i = n - 1; i >= 0; i--) {
        X509 *x = sk_X509_value(certs, i);

        /* Call for side-effect of computing hash and caching extensions */
        X509_check_purpose(x, -1, 0);

        /* If cache is NULL, likely ENOMEM: return immediately */
        if ((cache = policy_cache_set(x)) == NULL)
            return X509_PCY_TREE_INTERNAL;
    }

    /*
     * At this point check for invalid policies and required explicit policy.
     * Note that the explicit_policy counter is a count-down to zero, with the
     * requirement kicking in if and once it does that.  The counter is
     * decremented for every non-self-issued certificate in the path, but may
     * be further reduced by policy constraints in a non-leaf certificate.
     *
     * The ultimate policy set is the interesection of all the policies along
     * the path, if we hit a certificate with an empty policy set, and explicit
     * policy is required we're done.
     */
    for (i = n - 1;
         i >= 0 && (explicit_policy > 0 || (ret & X509_PCY_TREE_EMPTY) == 0);
         i--) {
        X509 *x = sk_X509_value(certs, i);
        uint32_t ex_flags = X509_get_extension_flags(x);

        /* All the policies are already cached, we can return early */
        if (ex_flags & EXFLAG_INVALID_POLICY)
            return X509_PCY_TREE_INVALID;

        /* Access the cache which we now know exists */
        cache = policy_cache_set(x);

        if ((ret & X509_PCY_TREE_VALID) && cache->data == NULL)
            ret = X509_PCY_TREE_EMPTY;
        if (explicit_policy > 0) {
            if (!(ex_flags & EXFLAG_SI))
                explicit_policy--;
            if ((cache->explicit_skip >= 0)
                && (cache->explicit_skip < explicit_policy))
                explicit_policy = cache->explicit_skip;
        }
    }

    if (explicit_policy == 0)
        ret |= X509_PCY_TREE_EXPLICIT;
    if ((ret & X509_PCY_TREE_VALID) == 0)
        return ret;

    /* If we get this far initialize the tree */
    if ((tree = OPENSSL_zalloc(sizeof(*tree))) == NULL)
        return X509_PCY_TREE_INTERNAL;

    /*
     * http://tools.ietf.org/html/rfc5280#section-6.1.2, figure 3.
     *
     * The top level is implicitly for the trust anchor with valid expected
     * policies of anyPolicy.  (RFC 5280 has the TA at depth 0 and the leaf at
     * depth n, we have the leaf at depth 0 and the TA at depth n).
     */
    if ((tree->levels = OPENSSL_zalloc(sizeof(*tree->levels)*(n+1))) == NULL) {
        OPENSSL_free(tree);
        return X509_PCY_TREE_INTERNAL;
    }
    tree->nlevel = n+1;
    level = tree->levels;
    if ((data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0)) == NULL)
        goto bad_tree;
    if (level_add_node(level, data, NULL, tree) == NULL) {
        policy_data_free(data);
        goto bad_tree;
    }

    /*
     * In this pass initialize all the tree levels and whether anyPolicy and
     * policy mapping are inhibited at each level.
     */
    for (i = n - 1; i >= 0; i--) {
        X509 *x = sk_X509_value(certs, i);
        uint32_t ex_flags = X509_get_extension_flags(x);

        /* Access the cache which we now know exists */
        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 only if certificate is self issued and not
             * the last in the chain.
             */
            if (!(ex_flags & EXFLAG_SI) || (i == 0))
                level->flags |= X509_V_FLAG_INHIBIT_ANY;
        } else {
            if (!(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 (!(ex_flags & EXFLAG_SI))
                map_skip--;
            if ((cache->map_skip >= 0) && (cache->map_skip < map_skip))
                map_skip = cache->map_skip;
        }
    }

    *ptree = tree;
    return ret;

 bad_tree:
    X509_policy_tree_free(tree);
    return X509_PCY_TREE_INTERNAL;
}

/*
 * Return value: 1 on success, 0 otherwise
 */
static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
                                    X509_POLICY_DATA *data)
{
    X509_POLICY_LEVEL *last = curr - 1;
    int i, matched = 0;

    /* Iterate through all in nodes linking matches */
    for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) {
        X509_POLICY_NODE *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) == NULL)
                return 0;
            matched = 1;
        }
    }
    if (!matched && last->anyPolicy) {
        if (level_add_node(curr, data, last->anyPolicy, NULL) == 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.
 *
 * Return value: 1 on success, 0 otherwise.
 */
static int tree_link_nodes(X509_POLICY_LEVEL *curr,
                           const X509_POLICY_CACHE *cache)
{
    int i;

    for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) {
        X509_POLICY_DATA *data = sk_X509_POLICY_DATA_value(cache->data, i);

        /* 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.
 *
 * Return value: 1 on success, 0 otherwise.
 */
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.
     */
    if ((data = policy_data_new(NULL, id, node_critical(node))) == 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) == NULL) {
        policy_data_free(data);
        return 0;
    }
    return 1;
}

/*
 * Return value: 1 on success, 0 otherwise.
 */
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;
}

/*
 * Return value: 1 on success, 0 otherwise
 */
static int tree_link_any(X509_POLICY_LEVEL *curr,
                         const X509_POLICY_CACHE *cache,
                         X509_POLICY_TREE *tree)
{
    int i;
    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;
    }
    /* Finally add link to anyPolicy */
    if (last->anyPolicy &&
        level_add_node(curr, cache->anyPolicy, last->anyPolicy, NULL) == 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.
 *
 * Return value: <= 0 error, otherwise one of:
 *
 * X509_PCY_TREE_VALID: valid tree
 * X509_PCY_TREE_EMPTY: empty tree
 */
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 X509_PCY_TREE_EMPTY;
            break;
        }
    }
    return X509_PCY_TREE_VALID;
}

/*
 * Return value: 1 on success, 0 otherwise.
 */
static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes,
                              X509_POLICY_NODE *pcy)
{
    if (*pnodes == NULL &&
        (*pnodes = policy_node_cmp_new()) == NULL)
        return 0;
    if (sk_X509_POLICY_NODE_find(*pnodes, pcy) != -1)
        return 1;
    return sk_X509_POLICY_NODE_push(*pnodes, pcy) != 0;
}

#define TREE_CALC_FAILURE 0
#define TREE_CALC_OK_NOFREE 1
#define TREE_CALC_OK_DOFREE 2

/*-
 * 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.
 *
 * Return value:
 *  TREE_CALC_FAILURE on failure,
 *  TREE_CALC_OK_NOFREE on success and pnodes need not be freed,
 *  TREE_CALC_OK_DOFREE on success and pnodes needs to 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 TREE_CALC_FAILURE;
        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) == NULL)
            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)) {
                if (addnodes == pnodes) {
                    sk_X509_POLICY_NODE_free(*pnodes);
                    *pnodes = NULL;
                }
                return TREE_CALC_FAILURE;
            }
        }
    }
    if (addnodes == pnodes)
        return TREE_CALC_OK_DOFREE;

    *pnodes = tree->auth_policies;
    return TREE_CALC_OK_NOFREE;
}

/*
 * Return value: 1 on success, 0 otherwise.
 */
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 == NULL)
                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;
}

/*-
 * Return value: <= 0 error, otherwise one of:
 *  X509_PCY_TREE_VALID: valid tree
 *  X509_PCY_TREE_EMPTY: empty tree
 * (see tree_prune()).
 */
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 X509_PCY_TREE_INTERNAL;

        if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)
            && !tree_link_any(curr, cache, tree))
            return X509_PCY_TREE_INTERNAL;
#ifdef OPENSSL_POLICY_DEBUG
        tree_print("before tree_prune()", tree, curr);
#endif
        ret = tree_prune(tree, curr);
        if (ret != X509_PCY_TREE_VALID)
            return ret;
    }
    return X509_PCY_TREE_VALID;
}

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++) {
        X509_free(curr->cert);
        sk_X509_POLICY_NODE_pop_free(curr->nodes, policy_node_free);
        policy_node_free(curr->anyPolicy);
    }

    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:
 *  X509_PCY_TREE_FAILURE:  Failure to satisfy explicit policy
 *  X509_PCY_TREE_INVALID:  Inconsistent or invalid extensions
 *  X509_PCY_TREE_INTERNAL: Internal error, most likely malloc
 *  X509_PCY_TREE_VALID:    Success (null tree if empty or bare TA)
 */
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 init_ret;
    int ret;
    X509_POLICY_TREE *tree = NULL;
    STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL;

    *ptree = NULL;
    *pexplicit_policy = 0;
    init_ret = tree_init(&tree, certs, flags);

    if (init_ret <= 0)
        return init_ret;

    if ((init_ret & X509_PCY_TREE_EXPLICIT) == 0) {
        if (init_ret & X509_PCY_TREE_EMPTY) {
            X509_policy_tree_free(tree);
            return X509_PCY_TREE_VALID;
        }
    } else {
        *pexplicit_policy = 1;
        /* Tree empty and requireExplicit True: Error */
        if (init_ret & X509_PCY_TREE_EMPTY)
            return X509_PCY_TREE_FAILURE;
    }

    ret = tree_evaluate(tree);
#ifdef OPENSSL_POLICY_DEBUG
    tree_print("tree_evaluate()", tree, NULL);
#endif
    if (ret <= 0)
        goto error;

    if (ret == X509_PCY_TREE_EMPTY) {
        X509_policy_tree_free(tree);
        if (init_ret & X509_PCY_TREE_EXPLICIT)
            return X509_PCY_TREE_FAILURE;
        return X509_PCY_TREE_VALID;
    }

    /* Tree is not empty: continue */
    if ((ret = tree_calculate_authority_set(tree, &auth_nodes)) == 0 ||
        !tree_calculate_user_set(tree, policy_oids, auth_nodes))
        goto error;
    if (ret == TREE_CALC_OK_DOFREE)
        sk_X509_POLICY_NODE_free(auth_nodes);

    *ptree = tree;

    if (init_ret & X509_PCY_TREE_EXPLICIT) {
        nodes = X509_policy_tree_get0_user_policies(tree);
        if (sk_X509_POLICY_NODE_num(nodes) <= 0)
            return X509_PCY_TREE_FAILURE;
    }
    return X509_PCY_TREE_VALID;

 error:
    X509_policy_tree_free(tree);
    return X509_PCY_TREE_INTERNAL;
}
