Home | History | Annotate | Download | only in x509v3
      1 /*
      2  * Written by Dr Stephen N Henson (steve (at) openssl.org) for the OpenSSL project
      3  * 2004.
      4  */
      5 /* ====================================================================
      6  * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  *
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  *
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in
     17  *    the documentation and/or other materials provided with the
     18  *    distribution.
     19  *
     20  * 3. All advertising materials mentioning features or use of this
     21  *    software must display the following acknowledgment:
     22  *    "This product includes software developed by the OpenSSL Project
     23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
     24  *
     25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
     26  *    endorse or promote products derived from this software without
     27  *    prior written permission. For written permission, please contact
     28  *    licensing (at) OpenSSL.org.
     29  *
     30  * 5. Products derived from this software may not be called "OpenSSL"
     31  *    nor may "OpenSSL" appear in their names without prior written
     32  *    permission of the OpenSSL Project.
     33  *
     34  * 6. Redistributions of any form whatsoever must retain the following
     35  *    acknowledgment:
     36  *    "This product includes software developed by the OpenSSL Project
     37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
     38  *
     39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
     40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
     43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     50  * OF THE POSSIBILITY OF SUCH DAMAGE.
     51  * ====================================================================
     52  *
     53  * This product includes cryptographic software written by Eric Young
     54  * (eay (at) cryptsoft.com).  This product includes software written by Tim
     55  * Hudson (tjh (at) cryptsoft.com).
     56  *
     57  */
     58 
     59 #include <string.h>
     60 
     61 #include <openssl/mem.h>
     62 #include <openssl/obj.h>
     63 #include <openssl/stack.h>
     64 #include <openssl/thread.h>
     65 #include <openssl/x509.h>
     66 #include <openssl/x509v3.h>
     67 
     68 #include "pcy_int.h"
     69 #include "../internal.h"
     70 
     71 /*
     72  * Enable this to print out the complete policy tree at various point during
     73  * evaluation.
     74  */
     75 
     76 /*
     77  * #define OPENSSL_POLICY_DEBUG
     78  */
     79 
     80 #ifdef OPENSSL_POLICY_DEBUG
     81 
     82 static void expected_print(BIO *err, X509_POLICY_LEVEL *lev,
     83                            X509_POLICY_NODE *node, int indent)
     84 {
     85     if ((lev->flags & X509_V_FLAG_INHIBIT_MAP)
     86         || !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK))
     87         BIO_puts(err, "  Not Mapped\n");
     88     else {
     89         int i;
     90         STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set;
     91         ASN1_OBJECT *oid;
     92         BIO_puts(err, "  Expected: ");
     93         for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++) {
     94             oid = sk_ASN1_OBJECT_value(pset, i);
     95             if (i)
     96                 BIO_puts(err, ", ");
     97             i2a_ASN1_OBJECT(err, oid);
     98         }
     99         BIO_puts(err, "\n");
    100     }
    101 }
    102 
    103 static void tree_print(char *str, X509_POLICY_TREE *tree,
    104                        X509_POLICY_LEVEL *curr)
    105 {
    106     X509_POLICY_LEVEL *plev;
    107     X509_POLICY_NODE *node;
    108     int i;
    109     BIO *err;
    110     err = BIO_new_fp(stderr, BIO_NOCLOSE);
    111     if (!curr)
    112         curr = tree->levels + tree->nlevel;
    113     else
    114         curr++;
    115     BIO_printf(err, "Level print after %s\n", str);
    116     BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels);
    117     for (plev = tree->levels; plev != curr; plev++) {
    118         BIO_printf(err, "Level %ld, flags = %x\n",
    119                    plev - tree->levels, plev->flags);
    120         for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++) {
    121             node = sk_X509_POLICY_NODE_value(plev->nodes, i);
    122             X509_POLICY_NODE_print(err, node, 2);
    123             expected_print(err, plev, node, 2);
    124             BIO_printf(err, "  Flags: %x\n", node->data->flags);
    125         }
    126         if (plev->anyPolicy)
    127             X509_POLICY_NODE_print(err, plev->anyPolicy, 2);
    128     }
    129 
    130     BIO_free(err);
    131 
    132 }
    133 #else
    134 
    135 # define tree_print(a,b,c)      /* */
    136 
    137 #endif
    138 
    139 /*-
    140  * Initialize policy tree. Return values:
    141  *  0 Some internal error occurred.
    142  * -1 Inconsistent or invalid extensions in certificates.
    143  *  1 Tree initialized OK.
    144  *  2 Policy tree is empty.
    145  *  5 Tree OK and requireExplicitPolicy true.
    146  *  6 Tree empty and requireExplicitPolicy true.
    147  */
    148 
    149 static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
    150                      unsigned int flags)
    151 {
    152     X509_POLICY_TREE *tree;
    153     X509_POLICY_LEVEL *level;
    154     const X509_POLICY_CACHE *cache;
    155     X509_POLICY_DATA *data = NULL;
    156     X509 *x;
    157     int ret = 1;
    158     int i, n;
    159     int explicit_policy;
    160     int any_skip;
    161     int map_skip;
    162     *ptree = NULL;
    163     n = sk_X509_num(certs);
    164 
    165 #if 0
    166     /* Disable policy mapping for now... */
    167     flags |= X509_V_FLAG_INHIBIT_MAP;
    168 #endif
    169 
    170     if (flags & X509_V_FLAG_EXPLICIT_POLICY)
    171         explicit_policy = 0;
    172     else
    173         explicit_policy = n + 1;
    174 
    175     if (flags & X509_V_FLAG_INHIBIT_ANY)
    176         any_skip = 0;
    177     else
    178         any_skip = n + 1;
    179 
    180     if (flags & X509_V_FLAG_INHIBIT_MAP)
    181         map_skip = 0;
    182     else
    183         map_skip = n + 1;
    184 
    185     /* Can't do anything with just a trust anchor */
    186     if (n == 1)
    187         return 1;
    188     /*
    189      * First setup policy cache in all certificates apart from the trust
    190      * anchor. Note any bad cache results on the way. Also can calculate
    191      * explicit_policy value at this point.
    192      */
    193     for (i = n - 2; i >= 0; i--) {
    194         x = sk_X509_value(certs, i);
    195         X509_check_purpose(x, -1, -1);
    196         cache = policy_cache_set(x);
    197         /* If cache NULL something bad happened: return immediately */
    198         if (cache == NULL)
    199             return 0;
    200         /*
    201          * If inconsistent extensions keep a note of it but continue
    202          */
    203         if (x->ex_flags & EXFLAG_INVALID_POLICY)
    204             ret = -1;
    205         /*
    206          * Otherwise if we have no data (hence no CertificatePolicies) and
    207          * haven't already set an inconsistent code note it.
    208          */
    209         else if ((ret == 1) && !cache->data)
    210             ret = 2;
    211         if (explicit_policy > 0) {
    212             if (!(x->ex_flags & EXFLAG_SI))
    213                 explicit_policy--;
    214             if ((cache->explicit_skip != -1)
    215                 && (cache->explicit_skip < explicit_policy))
    216                 explicit_policy = cache->explicit_skip;
    217         }
    218     }
    219 
    220     if (ret != 1) {
    221         if (ret == 2 && !explicit_policy)
    222             return 6;
    223         return ret;
    224     }
    225 
    226     /* If we get this far initialize the tree */
    227 
    228     tree = OPENSSL_malloc(sizeof(X509_POLICY_TREE));
    229 
    230     if (!tree)
    231         return 0;
    232 
    233     tree->flags = 0;
    234     tree->levels = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL) * n);
    235     tree->nlevel = 0;
    236     tree->extra_data = NULL;
    237     tree->auth_policies = NULL;
    238     tree->user_policies = NULL;
    239 
    240     if (!tree->levels) {
    241         OPENSSL_free(tree);
    242         return 0;
    243     }
    244 
    245     OPENSSL_memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL));
    246 
    247     tree->nlevel = n;
    248 
    249     level = tree->levels;
    250 
    251     /* Root data: initialize to anyPolicy */
    252 
    253     data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0);
    254 
    255     if (!data || !level_add_node(level, data, NULL, tree))
    256         goto bad_tree;
    257 
    258     for (i = n - 2; i >= 0; i--) {
    259         level++;
    260         x = sk_X509_value(certs, i);
    261         cache = policy_cache_set(x);
    262         X509_up_ref(x);
    263         level->cert = x;
    264 
    265         if (!cache->anyPolicy)
    266             level->flags |= X509_V_FLAG_INHIBIT_ANY;
    267 
    268         /* Determine inhibit any and inhibit map flags */
    269         if (any_skip == 0) {
    270             /*
    271              * Any matching allowed if certificate is self issued and not the
    272              * last in the chain.
    273              */
    274             if (!(x->ex_flags & EXFLAG_SI) || (i == 0))
    275                 level->flags |= X509_V_FLAG_INHIBIT_ANY;
    276         } else {
    277             if (!(x->ex_flags & EXFLAG_SI))
    278                 any_skip--;
    279             if ((cache->any_skip >= 0)
    280                 && (cache->any_skip < any_skip))
    281                 any_skip = cache->any_skip;
    282         }
    283 
    284         if (map_skip == 0)
    285             level->flags |= X509_V_FLAG_INHIBIT_MAP;
    286         else {
    287             if (!(x->ex_flags & EXFLAG_SI))
    288                 map_skip--;
    289             if ((cache->map_skip >= 0)
    290                 && (cache->map_skip < map_skip))
    291                 map_skip = cache->map_skip;
    292         }
    293 
    294     }
    295 
    296     *ptree = tree;
    297 
    298     if (explicit_policy)
    299         return 1;
    300     else
    301         return 5;
    302 
    303  bad_tree:
    304 
    305     X509_policy_tree_free(tree);
    306 
    307     return 0;
    308 
    309 }
    310 
    311 static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
    312                                     X509_POLICY_DATA *data)
    313 {
    314     X509_POLICY_LEVEL *last = curr - 1;
    315     X509_POLICY_NODE *node;
    316     int matched = 0;
    317     size_t i;
    318     /* Iterate through all in nodes linking matches */
    319     for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) {
    320         node = sk_X509_POLICY_NODE_value(last->nodes, i);
    321         if (policy_node_match(last, node, data->valid_policy)) {
    322             if (!level_add_node(curr, data, node, NULL))
    323                 return 0;
    324             matched = 1;
    325         }
    326     }
    327     if (!matched && last->anyPolicy) {
    328         if (!level_add_node(curr, data, last->anyPolicy, NULL))
    329             return 0;
    330     }
    331     return 1;
    332 }
    333 
    334 /*
    335  * This corresponds to RFC3280 6.1.3(d)(1): link any data from
    336  * CertificatePolicies onto matching parent or anyPolicy if no match.
    337  */
    338 
    339 static int tree_link_nodes(X509_POLICY_LEVEL *curr,
    340                            const X509_POLICY_CACHE *cache)
    341 {
    342     size_t i;
    343     X509_POLICY_DATA *data;
    344 
    345     for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) {
    346         data = sk_X509_POLICY_DATA_value(cache->data, i);
    347         /*
    348          * If a node is mapped any it doesn't have a corresponding
    349          * CertificatePolicies entry. However such an identical node would
    350          * be created if anyPolicy matching is enabled because there would be
    351          * no match with the parent valid_policy_set. So we create link
    352          * because then it will have the mapping flags right and we can prune
    353          * it later.
    354          */
    355 #if 0
    356         if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY)
    357             && !(curr->flags & X509_V_FLAG_INHIBIT_ANY))
    358             continue;
    359 #endif
    360         /* Look for matching nodes in previous level */
    361         if (!tree_link_matching_nodes(curr, data))
    362             return 0;
    363     }
    364     return 1;
    365 }
    366 
    367 /*
    368  * This corresponds to RFC3280 6.1.3(d)(2): Create new data for any unmatched
    369  * policies in the parent and link to anyPolicy.
    370  */
    371 
    372 static int tree_add_unmatched(X509_POLICY_LEVEL *curr,
    373                               const X509_POLICY_CACHE *cache,
    374                               const ASN1_OBJECT *id,
    375                               X509_POLICY_NODE *node, X509_POLICY_TREE *tree)
    376 {
    377     X509_POLICY_DATA *data;
    378     if (id == NULL)
    379         id = node->data->valid_policy;
    380     /*
    381      * Create a new node with qualifiers from anyPolicy and id from unmatched
    382      * node.
    383      */
    384     data = policy_data_new(NULL, id, node_critical(node));
    385 
    386     if (data == NULL)
    387         return 0;
    388     /* Curr may not have anyPolicy */
    389     data->qualifier_set = cache->anyPolicy->qualifier_set;
    390     data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
    391     if (!level_add_node(curr, data, node, tree)) {
    392         policy_data_free(data);
    393         return 0;
    394     }
    395 
    396     return 1;
    397 }
    398 
    399 static int tree_link_unmatched(X509_POLICY_LEVEL *curr,
    400                                const X509_POLICY_CACHE *cache,
    401                                X509_POLICY_NODE *node, X509_POLICY_TREE *tree)
    402 {
    403     const X509_POLICY_LEVEL *last = curr - 1;
    404     size_t i;
    405 
    406     if ((last->flags & X509_V_FLAG_INHIBIT_MAP)
    407         || !(node->data->flags & POLICY_DATA_FLAG_MAPPED)) {
    408         /* If no policy mapping: matched if one child present */
    409         if (node->nchild)
    410             return 1;
    411         if (!tree_add_unmatched(curr, cache, NULL, node, tree))
    412             return 0;
    413         /* Add it */
    414     } else {
    415         /* If mapping: matched if one child per expected policy set */
    416         STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set;
    417         if ((size_t)node->nchild == sk_ASN1_OBJECT_num(expset))
    418             return 1;
    419         /* Locate unmatched nodes */
    420         for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++) {
    421             ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i);
    422             if (level_find_node(curr, node, oid))
    423                 continue;
    424             if (!tree_add_unmatched(curr, cache, oid, node, tree))
    425                 return 0;
    426         }
    427 
    428     }
    429 
    430     return 1;
    431 
    432 }
    433 
    434 static int tree_link_any(X509_POLICY_LEVEL *curr,
    435                          const X509_POLICY_CACHE *cache,
    436                          X509_POLICY_TREE *tree)
    437 {
    438     size_t i;
    439     /*
    440      * X509_POLICY_DATA *data;
    441      */
    442     X509_POLICY_NODE *node;
    443     X509_POLICY_LEVEL *last = curr - 1;
    444 
    445     for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) {
    446         node = sk_X509_POLICY_NODE_value(last->nodes, i);
    447 
    448         if (!tree_link_unmatched(curr, cache, node, tree))
    449             return 0;
    450 
    451 #if 0
    452 
    453         /*
    454          * Skip any node with any children: we only want unmathced nodes.
    455          * Note: need something better for policy mapping because each node
    456          * may have multiple children
    457          */
    458         if (node->nchild)
    459             continue;
    460 
    461         /*
    462          * Create a new node with qualifiers from anyPolicy and id from
    463          * unmatched node.
    464          */
    465         data = policy_data_new(NULL, node->data->valid_policy,
    466                                node_critical(node));
    467 
    468         if (data == NULL)
    469             return 0;
    470         /* Curr may not have anyPolicy */
    471         data->qualifier_set = cache->anyPolicy->qualifier_set;
    472         data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
    473         if (!level_add_node(curr, data, node, tree)) {
    474             policy_data_free(data);
    475             return 0;
    476         }
    477 #endif
    478 
    479     }
    480     /* Finally add link to anyPolicy */
    481     if (last->anyPolicy) {
    482         if (!level_add_node(curr, cache->anyPolicy, last->anyPolicy, NULL))
    483             return 0;
    484     }
    485     return 1;
    486 }
    487 
    488 /*
    489  * Prune the tree: delete any child mapped child data on the current level
    490  * then proceed up the tree deleting any data with no children. If we ever
    491  * have no data on a level we can halt because the tree will be empty.
    492  */
    493 
    494 static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
    495 {
    496     STACK_OF(X509_POLICY_NODE) *nodes;
    497     X509_POLICY_NODE *node;
    498     int i;
    499     nodes = curr->nodes;
    500     if (curr->flags & X509_V_FLAG_INHIBIT_MAP) {
    501         for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) {
    502             node = sk_X509_POLICY_NODE_value(nodes, i);
    503             /* Delete any mapped data: see RFC3280 XXXX */
    504             if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) {
    505                 node->parent->nchild--;
    506                 OPENSSL_free(node);
    507                 (void)sk_X509_POLICY_NODE_delete(nodes, i);
    508             }
    509         }
    510     }
    511 
    512     for (;;) {
    513         --curr;
    514         nodes = curr->nodes;
    515         for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) {
    516             node = sk_X509_POLICY_NODE_value(nodes, i);
    517             if (node->nchild == 0) {
    518                 node->parent->nchild--;
    519                 OPENSSL_free(node);
    520                 (void)sk_X509_POLICY_NODE_delete(nodes, i);
    521             }
    522         }
    523         if (curr->anyPolicy && !curr->anyPolicy->nchild) {
    524             if (curr->anyPolicy->parent)
    525                 curr->anyPolicy->parent->nchild--;
    526             OPENSSL_free(curr->anyPolicy);
    527             curr->anyPolicy = NULL;
    528         }
    529         if (curr == tree->levels) {
    530             /* If we zapped anyPolicy at top then tree is empty */
    531             if (!curr->anyPolicy)
    532                 return 2;
    533             return 1;
    534         }
    535     }
    536 
    537 }
    538 
    539 static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes,
    540                               X509_POLICY_NODE *pcy)
    541 {
    542     if (!*pnodes) {
    543         *pnodes = policy_node_cmp_new();
    544         if (!*pnodes)
    545             return 0;
    546     } else if (sk_X509_POLICY_NODE_find(*pnodes, NULL, pcy))
    547         return 1;
    548 
    549     if (!sk_X509_POLICY_NODE_push(*pnodes, pcy))
    550         return 0;
    551 
    552     return 1;
    553 
    554 }
    555 
    556 /*
    557  * Calculate the authority set based on policy tree. The 'pnodes' parameter
    558  * is used as a store for the set of policy nodes used to calculate the user
    559  * set. If the authority set is not anyPolicy then pnodes will just point to
    560  * the authority set. If however the authority set is anyPolicy then the set
    561  * of valid policies (other than anyPolicy) is store in pnodes. The return
    562  * value of '2' is used in this case to indicate that pnodes should be freed.
    563  */
    564 
    565 static int tree_calculate_authority_set(X509_POLICY_TREE *tree,
    566                                         STACK_OF(X509_POLICY_NODE) **pnodes)
    567 {
    568     X509_POLICY_LEVEL *curr;
    569     X509_POLICY_NODE *node, *anyptr;
    570     STACK_OF(X509_POLICY_NODE) **addnodes;
    571     int i;
    572     size_t j;
    573     curr = tree->levels + tree->nlevel - 1;
    574 
    575     /* If last level contains anyPolicy set is anyPolicy */
    576     if (curr->anyPolicy) {
    577         if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy))
    578             return 0;
    579         addnodes = pnodes;
    580     } else
    581         /* Add policies to authority set */
    582         addnodes = &tree->auth_policies;
    583 
    584     curr = tree->levels;
    585     for (i = 1; i < tree->nlevel; i++) {
    586         /*
    587          * If no anyPolicy node on this this level it can't appear on lower
    588          * levels so end search.
    589          */
    590         if (!(anyptr = curr->anyPolicy))
    591             break;
    592         curr++;
    593         for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++) {
    594             node = sk_X509_POLICY_NODE_value(curr->nodes, j);
    595             if ((node->parent == anyptr)
    596                 && !tree_add_auth_node(addnodes, node))
    597                 return 0;
    598         }
    599     }
    600 
    601     if (addnodes == pnodes)
    602         return 2;
    603 
    604     *pnodes = tree->auth_policies;
    605 
    606     return 1;
    607 }
    608 
    609 static int tree_calculate_user_set(X509_POLICY_TREE *tree,
    610                                    STACK_OF(ASN1_OBJECT) *policy_oids,
    611                                    STACK_OF(X509_POLICY_NODE) *auth_nodes)
    612 {
    613     size_t i;
    614     X509_POLICY_NODE *node;
    615     ASN1_OBJECT *oid;
    616 
    617     X509_POLICY_NODE *anyPolicy;
    618     X509_POLICY_DATA *extra;
    619 
    620     /*
    621      * Check if anyPolicy present in authority constrained policy set: this
    622      * will happen if it is a leaf node.
    623      */
    624 
    625     if (sk_ASN1_OBJECT_num(policy_oids) <= 0)
    626         return 1;
    627 
    628     anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy;
    629 
    630     for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) {
    631         oid = sk_ASN1_OBJECT_value(policy_oids, i);
    632         if (OBJ_obj2nid(oid) == NID_any_policy) {
    633             tree->flags |= POLICY_FLAG_ANY_POLICY;
    634             return 1;
    635         }
    636     }
    637 
    638     for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) {
    639         oid = sk_ASN1_OBJECT_value(policy_oids, i);
    640         node = tree_find_sk(auth_nodes, oid);
    641         if (!node) {
    642             if (!anyPolicy)
    643                 continue;
    644             /*
    645              * Create a new node with policy ID from user set and qualifiers
    646              * from anyPolicy.
    647              */
    648             extra = policy_data_new(NULL, oid, node_critical(anyPolicy));
    649             if (!extra)
    650                 return 0;
    651             extra->qualifier_set = anyPolicy->data->qualifier_set;
    652             extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS
    653                 | POLICY_DATA_FLAG_EXTRA_NODE;
    654             node = level_add_node(NULL, extra, anyPolicy->parent, tree);
    655         }
    656         if (!tree->user_policies) {
    657             tree->user_policies = sk_X509_POLICY_NODE_new_null();
    658             if (!tree->user_policies)
    659                 return 1;
    660         }
    661         if (!sk_X509_POLICY_NODE_push(tree->user_policies, node))
    662             return 0;
    663     }
    664     return 1;
    665 
    666 }
    667 
    668 static int tree_evaluate(X509_POLICY_TREE *tree)
    669 {
    670     int ret, i;
    671     X509_POLICY_LEVEL *curr = tree->levels + 1;
    672     const X509_POLICY_CACHE *cache;
    673 
    674     for (i = 1; i < tree->nlevel; i++, curr++) {
    675         cache = policy_cache_set(curr->cert);
    676         if (!tree_link_nodes(curr, cache))
    677             return 0;
    678 
    679         if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)
    680             && !tree_link_any(curr, cache, tree))
    681             return 0;
    682         tree_print("before tree_prune()", tree, curr);
    683         ret = tree_prune(tree, curr);
    684         if (ret != 1)
    685             return ret;
    686     }
    687 
    688     return 1;
    689 
    690 }
    691 
    692 static void exnode_free(X509_POLICY_NODE *node)
    693 {
    694     if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE))
    695         OPENSSL_free(node);
    696 }
    697 
    698 void X509_policy_tree_free(X509_POLICY_TREE *tree)
    699 {
    700     X509_POLICY_LEVEL *curr;
    701     int i;
    702 
    703     if (!tree)
    704         return;
    705 
    706     sk_X509_POLICY_NODE_free(tree->auth_policies);
    707     sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free);
    708 
    709     for (i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++) {
    710         if (curr->cert)
    711             X509_free(curr->cert);
    712         if (curr->nodes)
    713             sk_X509_POLICY_NODE_pop_free(curr->nodes, policy_node_free);
    714         if (curr->anyPolicy)
    715             policy_node_free(curr->anyPolicy);
    716     }
    717 
    718     if (tree->extra_data)
    719         sk_X509_POLICY_DATA_pop_free(tree->extra_data, policy_data_free);
    720 
    721     OPENSSL_free(tree->levels);
    722     OPENSSL_free(tree);
    723 
    724 }
    725 
    726 /*-
    727  * Application policy checking function.
    728  * Return codes:
    729  *  0   Internal Error.
    730  *  1   Successful.
    731  * -1   One or more certificates contain invalid or inconsistent extensions
    732  * -2   User constrained policy set empty and requireExplicit true.
    733  */
    734 
    735 int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
    736                       STACK_OF(X509) *certs,
    737                       STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags)
    738 {
    739     int ret;
    740     int calc_ret;
    741     X509_POLICY_TREE *tree = NULL;
    742     STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL;
    743     *ptree = NULL;
    744 
    745     *pexplicit_policy = 0;
    746     ret = tree_init(&tree, certs, flags);
    747 
    748     switch (ret) {
    749 
    750         /* Tree empty requireExplicit False: OK */
    751     case 2:
    752         return 1;
    753 
    754         /* Some internal error */
    755     case -1:
    756         return -1;
    757 
    758         /* Some internal error */
    759     case 0:
    760         return 0;
    761 
    762         /* Tree empty requireExplicit True: Error */
    763 
    764     case 6:
    765         *pexplicit_policy = 1;
    766         return -2;
    767 
    768         /* Tree OK requireExplicit True: OK and continue */
    769     case 5:
    770         *pexplicit_policy = 1;
    771         break;
    772 
    773         /* Tree OK: continue */
    774 
    775     case 1:
    776         if (!tree)
    777             /*
    778              * tree_init() returns success and a null tree
    779              * if it's just looking at a trust anchor.
    780              * I'm not sure that returning success here is
    781              * correct, but I'm sure that reporting this
    782              * as an internal error which our caller
    783              * interprets as a malloc failure is wrong.
    784              */
    785             return 1;
    786         break;
    787     }
    788 
    789     if (!tree)
    790         goto error;
    791     ret = tree_evaluate(tree);
    792 
    793     tree_print("tree_evaluate()", tree, NULL);
    794 
    795     if (ret <= 0)
    796         goto error;
    797 
    798     /* Return value 2 means tree empty */
    799     if (ret == 2) {
    800         X509_policy_tree_free(tree);
    801         if (*pexplicit_policy)
    802             return -2;
    803         else
    804             return 1;
    805     }
    806 
    807     /* Tree is not empty: continue */
    808 
    809     calc_ret = tree_calculate_authority_set(tree, &auth_nodes);
    810 
    811     if (!calc_ret)
    812         goto error;
    813 
    814     ret = tree_calculate_user_set(tree, policy_oids, auth_nodes);
    815 
    816     if (calc_ret == 2)
    817         sk_X509_POLICY_NODE_free(auth_nodes);
    818 
    819     if (!ret)
    820         goto error;
    821 
    822 
    823     if (tree)
    824         *ptree = tree;
    825 
    826     if (*pexplicit_policy) {
    827         nodes = X509_policy_tree_get0_user_policies(tree);
    828         if (sk_X509_POLICY_NODE_num(nodes) <= 0)
    829             return -2;
    830     }
    831 
    832     return 1;
    833 
    834  error:
    835 
    836     X509_policy_tree_free(tree);
    837 
    838     return 0;
    839 
    840 }
    841