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: 0 Some internal error occured. -1
    141  * Inconsistent or invalid extensions in certificates.  1 Tree initialized
    142  * OK.  2 Policy tree is empty.  5 Tree OK and requireExplicitPolicy true.  6
    143  * Tree empty and requireExplicitPolicy true.
    144  */
    145 
    146 static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
    147                      unsigned int flags)
    148 {
    149     X509_POLICY_TREE *tree;
    150     X509_POLICY_LEVEL *level;
    151     const X509_POLICY_CACHE *cache;
    152     X509_POLICY_DATA *data = NULL;
    153     X509 *x;
    154     int ret = 1;
    155     int i, n;
    156     int explicit_policy;
    157     int any_skip;
    158     int map_skip;
    159     *ptree = NULL;
    160     n = sk_X509_num(certs);
    161 
    162 #if 0
    163     /* Disable policy mapping for now... */
    164     flags |= X509_V_FLAG_INHIBIT_MAP;
    165 #endif
    166 
    167     if (flags & X509_V_FLAG_EXPLICIT_POLICY)
    168         explicit_policy = 0;
    169     else
    170         explicit_policy = n + 1;
    171 
    172     if (flags & X509_V_FLAG_INHIBIT_ANY)
    173         any_skip = 0;
    174     else
    175         any_skip = n + 1;
    176 
    177     if (flags & X509_V_FLAG_INHIBIT_MAP)
    178         map_skip = 0;
    179     else
    180         map_skip = n + 1;
    181 
    182     /* Can't do anything with just a trust anchor */
    183     if (n == 1)
    184         return 1;
    185     /*
    186      * First setup policy cache in all certificates apart from the trust
    187      * anchor. Note any bad cache results on the way. Also can calculate
    188      * explicit_policy value at this point.
    189      */
    190     for (i = n - 2; i >= 0; i--) {
    191         x = sk_X509_value(certs, i);
    192         X509_check_purpose(x, -1, -1);
    193         cache = policy_cache_set(x);
    194         /* If cache NULL something bad happened: return immediately */
    195         if (cache == NULL)
    196             return 0;
    197         /*
    198          * If inconsistent extensions keep a note of it but continue
    199          */
    200         if (x->ex_flags & EXFLAG_INVALID_POLICY)
    201             ret = -1;
    202         /*
    203          * Otherwise if we have no data (hence no CertificatePolicies) and
    204          * haven't already set an inconsistent code note it.
    205          */
    206         else if ((ret == 1) && !cache->data)
    207             ret = 2;
    208         if (explicit_policy > 0) {
    209             if (!(x->ex_flags & EXFLAG_SI))
    210                 explicit_policy--;
    211             if ((cache->explicit_skip != -1)
    212                 && (cache->explicit_skip < explicit_policy))
    213                 explicit_policy = cache->explicit_skip;
    214         }
    215     }
    216 
    217     if (ret != 1) {
    218         if (ret == 2 && !explicit_policy)
    219             return 6;
    220         return ret;
    221     }
    222 
    223     /* If we get this far initialize the tree */
    224 
    225     tree = OPENSSL_malloc(sizeof(X509_POLICY_TREE));
    226 
    227     if (!tree)
    228         return 0;
    229 
    230     tree->flags = 0;
    231     tree->levels = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL) * n);
    232     tree->nlevel = 0;
    233     tree->extra_data = NULL;
    234     tree->auth_policies = NULL;
    235     tree->user_policies = NULL;
    236 
    237     if (!tree->levels) {
    238         OPENSSL_free(tree);
    239         return 0;
    240     }
    241 
    242     OPENSSL_memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL));
    243 
    244     tree->nlevel = n;
    245 
    246     level = tree->levels;
    247 
    248     /* Root data: initialize to anyPolicy */
    249 
    250     data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0);
    251 
    252     if (!data || !level_add_node(level, data, NULL, tree))
    253         goto bad_tree;
    254 
    255     for (i = n - 2; i >= 0; i--) {
    256         level++;
    257         x = sk_X509_value(certs, i);
    258         cache = policy_cache_set(x);
    259         X509_up_ref(x);
    260         level->cert = x;
    261 
    262         if (!cache->anyPolicy)
    263             level->flags |= X509_V_FLAG_INHIBIT_ANY;
    264 
    265         /* Determine inhibit any and inhibit map flags */
    266         if (any_skip == 0) {
    267             /*
    268              * Any matching allowed if certificate is self issued and not the
    269              * last in the chain.
    270              */
    271             if (!(x->ex_flags & EXFLAG_SI) || (i == 0))
    272                 level->flags |= X509_V_FLAG_INHIBIT_ANY;
    273         } else {
    274             if (!(x->ex_flags & EXFLAG_SI))
    275                 any_skip--;
    276             if ((cache->any_skip >= 0)
    277                 && (cache->any_skip < any_skip))
    278                 any_skip = cache->any_skip;
    279         }
    280 
    281         if (map_skip == 0)
    282             level->flags |= X509_V_FLAG_INHIBIT_MAP;
    283         else {
    284             if (!(x->ex_flags & EXFLAG_SI))
    285                 map_skip--;
    286             if ((cache->map_skip >= 0)
    287                 && (cache->map_skip < map_skip))
    288                 map_skip = cache->map_skip;
    289         }
    290 
    291     }
    292 
    293     *ptree = tree;
    294 
    295     if (explicit_policy)
    296         return 1;
    297     else
    298         return 5;
    299 
    300  bad_tree:
    301 
    302     X509_policy_tree_free(tree);
    303 
    304     return 0;
    305 
    306 }
    307 
    308 static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
    309                                     const X509_POLICY_DATA *data)
    310 {
    311     X509_POLICY_LEVEL *last = curr - 1;
    312     X509_POLICY_NODE *node;
    313     int matched = 0;
    314     size_t i;
    315     /* Iterate through all in nodes linking matches */
    316     for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) {
    317         node = sk_X509_POLICY_NODE_value(last->nodes, i);
    318         if (policy_node_match(last, node, data->valid_policy)) {
    319             if (!level_add_node(curr, data, node, NULL))
    320                 return 0;
    321             matched = 1;
    322         }
    323     }
    324     if (!matched && last->anyPolicy) {
    325         if (!level_add_node(curr, data, last->anyPolicy, NULL))
    326             return 0;
    327     }
    328     return 1;
    329 }
    330 
    331 /*
    332  * This corresponds to RFC3280 6.1.3(d)(1): link any data from
    333  * CertificatePolicies onto matching parent or anyPolicy if no match.
    334  */
    335 
    336 static int tree_link_nodes(X509_POLICY_LEVEL *curr,
    337                            const X509_POLICY_CACHE *cache)
    338 {
    339     size_t i;
    340     X509_POLICY_DATA *data;
    341 
    342     for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) {
    343         data = sk_X509_POLICY_DATA_value(cache->data, i);
    344         /*
    345          * If a node is mapped any it doesn't have a corresponding
    346          * CertificatePolicies entry. However such an identical node would
    347          * be created if anyPolicy matching is enabled because there would be
    348          * no match with the parent valid_policy_set. So we create link
    349          * because then it will have the mapping flags right and we can prune
    350          * it later.
    351          */
    352 #if 0
    353         if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY)
    354             && !(curr->flags & X509_V_FLAG_INHIBIT_ANY))
    355             continue;
    356 #endif
    357         /* Look for matching nodes in previous level */
    358         if (!tree_link_matching_nodes(curr, data))
    359             return 0;
    360     }
    361     return 1;
    362 }
    363 
    364 /*
    365  * This corresponds to RFC3280 6.1.3(d)(2): Create new data for any unmatched
    366  * policies in the parent and link to anyPolicy.
    367  */
    368 
    369 static int tree_add_unmatched(X509_POLICY_LEVEL *curr,
    370                               const X509_POLICY_CACHE *cache,
    371                               const ASN1_OBJECT *id,
    372                               X509_POLICY_NODE *node, X509_POLICY_TREE *tree)
    373 {
    374     X509_POLICY_DATA *data;
    375     if (id == NULL)
    376         id = node->data->valid_policy;
    377     /*
    378      * Create a new node with qualifiers from anyPolicy and id from unmatched
    379      * node.
    380      */
    381     data = policy_data_new(NULL, id, node_critical(node));
    382 
    383     if (data == NULL)
    384         return 0;
    385     /* Curr may not have anyPolicy */
    386     data->qualifier_set = cache->anyPolicy->qualifier_set;
    387     data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
    388     if (!level_add_node(curr, data, node, tree)) {
    389         policy_data_free(data);
    390         return 0;
    391     }
    392 
    393     return 1;
    394 }
    395 
    396 static int tree_link_unmatched(X509_POLICY_LEVEL *curr,
    397                                const X509_POLICY_CACHE *cache,
    398                                X509_POLICY_NODE *node, X509_POLICY_TREE *tree)
    399 {
    400     const X509_POLICY_LEVEL *last = curr - 1;
    401     size_t i;
    402 
    403     if ((last->flags & X509_V_FLAG_INHIBIT_MAP)
    404         || !(node->data->flags & POLICY_DATA_FLAG_MAPPED)) {
    405         /* If no policy mapping: matched if one child present */
    406         if (node->nchild)
    407             return 1;
    408         if (!tree_add_unmatched(curr, cache, NULL, node, tree))
    409             return 0;
    410         /* Add it */
    411     } else {
    412         /* If mapping: matched if one child per expected policy set */
    413         STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set;
    414         if ((size_t)node->nchild == sk_ASN1_OBJECT_num(expset))
    415             return 1;
    416         /* Locate unmatched nodes */
    417         for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++) {
    418             ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i);
    419             if (level_find_node(curr, node, oid))
    420                 continue;
    421             if (!tree_add_unmatched(curr, cache, oid, node, tree))
    422                 return 0;
    423         }
    424 
    425     }
    426 
    427     return 1;
    428 
    429 }
    430 
    431 static int tree_link_any(X509_POLICY_LEVEL *curr,
    432                          const X509_POLICY_CACHE *cache,
    433                          X509_POLICY_TREE *tree)
    434 {
    435     size_t i;
    436     /*
    437      * X509_POLICY_DATA *data;
    438      */
    439     X509_POLICY_NODE *node;
    440     X509_POLICY_LEVEL *last = curr - 1;
    441 
    442     for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) {
    443         node = sk_X509_POLICY_NODE_value(last->nodes, i);
    444 
    445         if (!tree_link_unmatched(curr, cache, node, tree))
    446             return 0;
    447 
    448 #if 0
    449 
    450         /*
    451          * Skip any node with any children: we only want unmathced nodes.
    452          * Note: need something better for policy mapping because each node
    453          * may have multiple children
    454          */
    455         if (node->nchild)
    456             continue;
    457 
    458         /*
    459          * Create a new node with qualifiers from anyPolicy and id from
    460          * unmatched node.
    461          */
    462         data = policy_data_new(NULL, node->data->valid_policy,
    463                                node_critical(node));
    464 
    465         if (data == NULL)
    466             return 0;
    467         /* Curr may not have anyPolicy */
    468         data->qualifier_set = cache->anyPolicy->qualifier_set;
    469         data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
    470         if (!level_add_node(curr, data, node, tree)) {
    471             policy_data_free(data);
    472             return 0;
    473         }
    474 #endif
    475 
    476     }
    477     /* Finally add link to anyPolicy */
    478     if (last->anyPolicy) {
    479         if (!level_add_node(curr, cache->anyPolicy, last->anyPolicy, NULL))
    480             return 0;
    481     }
    482     return 1;
    483 }
    484 
    485 /*
    486  * Prune the tree: delete any child mapped child data on the current level
    487  * then proceed up the tree deleting any data with no children. If we ever
    488  * have no data on a level we can halt because the tree will be empty.
    489  */
    490 
    491 static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
    492 {
    493     STACK_OF(X509_POLICY_NODE) *nodes;
    494     X509_POLICY_NODE *node;
    495     int i;
    496     nodes = curr->nodes;
    497     if (curr->flags & X509_V_FLAG_INHIBIT_MAP) {
    498         for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) {
    499             node = sk_X509_POLICY_NODE_value(nodes, i);
    500             /* Delete any mapped data: see RFC3280 XXXX */
    501             if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) {
    502                 node->parent->nchild--;
    503                 OPENSSL_free(node);
    504                 (void)sk_X509_POLICY_NODE_delete(nodes, i);
    505             }
    506         }
    507     }
    508 
    509     for (;;) {
    510         --curr;
    511         nodes = curr->nodes;
    512         for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) {
    513             node = sk_X509_POLICY_NODE_value(nodes, i);
    514             if (node->nchild == 0) {
    515                 node->parent->nchild--;
    516                 OPENSSL_free(node);
    517                 (void)sk_X509_POLICY_NODE_delete(nodes, i);
    518             }
    519         }
    520         if (curr->anyPolicy && !curr->anyPolicy->nchild) {
    521             if (curr->anyPolicy->parent)
    522                 curr->anyPolicy->parent->nchild--;
    523             OPENSSL_free(curr->anyPolicy);
    524             curr->anyPolicy = NULL;
    525         }
    526         if (curr == tree->levels) {
    527             /* If we zapped anyPolicy at top then tree is empty */
    528             if (!curr->anyPolicy)
    529                 return 2;
    530             return 1;
    531         }
    532     }
    533 
    534 }
    535 
    536 static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes,
    537                               X509_POLICY_NODE *pcy)
    538 {
    539     if (!*pnodes) {
    540         *pnodes = policy_node_cmp_new();
    541         if (!*pnodes)
    542             return 0;
    543     } else if (sk_X509_POLICY_NODE_find(*pnodes, NULL, pcy))
    544         return 1;
    545 
    546     if (!sk_X509_POLICY_NODE_push(*pnodes, pcy))
    547         return 0;
    548 
    549     return 1;
    550 
    551 }
    552 
    553 /*
    554  * Calculate the authority set based on policy tree. The 'pnodes' parameter
    555  * is used as a store for the set of policy nodes used to calculate the user
    556  * set. If the authority set is not anyPolicy then pnodes will just point to
    557  * the authority set. If however the authority set is anyPolicy then the set
    558  * of valid policies (other than anyPolicy) is store in pnodes. The return
    559  * value of '2' is used in this case to indicate that pnodes should be freed.
    560  */
    561 
    562 static int tree_calculate_authority_set(X509_POLICY_TREE *tree,
    563                                         STACK_OF(X509_POLICY_NODE) **pnodes)
    564 {
    565     X509_POLICY_LEVEL *curr;
    566     X509_POLICY_NODE *node, *anyptr;
    567     STACK_OF(X509_POLICY_NODE) **addnodes;
    568     int i;
    569     size_t j;
    570     curr = tree->levels + tree->nlevel - 1;
    571 
    572     /* If last level contains anyPolicy set is anyPolicy */
    573     if (curr->anyPolicy) {
    574         if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy))
    575             return 0;
    576         addnodes = pnodes;
    577     } else
    578         /* Add policies to authority set */
    579         addnodes = &tree->auth_policies;
    580 
    581     curr = tree->levels;
    582     for (i = 1; i < tree->nlevel; i++) {
    583         /*
    584          * If no anyPolicy node on this this level it can't appear on lower
    585          * levels so end search.
    586          */
    587         if (!(anyptr = curr->anyPolicy))
    588             break;
    589         curr++;
    590         for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++) {
    591             node = sk_X509_POLICY_NODE_value(curr->nodes, j);
    592             if ((node->parent == anyptr)
    593                 && !tree_add_auth_node(addnodes, node))
    594                 return 0;
    595         }
    596     }
    597 
    598     if (addnodes == pnodes)
    599         return 2;
    600 
    601     *pnodes = tree->auth_policies;
    602 
    603     return 1;
    604 }
    605 
    606 static int tree_calculate_user_set(X509_POLICY_TREE *tree,
    607                                    STACK_OF(ASN1_OBJECT) *policy_oids,
    608                                    STACK_OF(X509_POLICY_NODE) *auth_nodes)
    609 {
    610     size_t i;
    611     X509_POLICY_NODE *node;
    612     ASN1_OBJECT *oid;
    613 
    614     X509_POLICY_NODE *anyPolicy;
    615     X509_POLICY_DATA *extra;
    616 
    617     /*
    618      * Check if anyPolicy present in authority constrained policy set: this
    619      * will happen if it is a leaf node.
    620      */
    621 
    622     if (sk_ASN1_OBJECT_num(policy_oids) <= 0)
    623         return 1;
    624 
    625     anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy;
    626 
    627     for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) {
    628         oid = sk_ASN1_OBJECT_value(policy_oids, i);
    629         if (OBJ_obj2nid(oid) == NID_any_policy) {
    630             tree->flags |= POLICY_FLAG_ANY_POLICY;
    631             return 1;
    632         }
    633     }
    634 
    635     for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) {
    636         oid = sk_ASN1_OBJECT_value(policy_oids, i);
    637         node = tree_find_sk(auth_nodes, oid);
    638         if (!node) {
    639             if (!anyPolicy)
    640                 continue;
    641             /*
    642              * Create a new node with policy ID from user set and qualifiers
    643              * from anyPolicy.
    644              */
    645             extra = policy_data_new(NULL, oid, node_critical(anyPolicy));
    646             if (!extra)
    647                 return 0;
    648             extra->qualifier_set = anyPolicy->data->qualifier_set;
    649             extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS
    650                 | POLICY_DATA_FLAG_EXTRA_NODE;
    651             node = level_add_node(NULL, extra, anyPolicy->parent, tree);
    652         }
    653         if (!tree->user_policies) {
    654             tree->user_policies = sk_X509_POLICY_NODE_new_null();
    655             if (!tree->user_policies)
    656                 return 1;
    657         }
    658         if (!sk_X509_POLICY_NODE_push(tree->user_policies, node))
    659             return 0;
    660     }
    661     return 1;
    662 
    663 }
    664 
    665 static int tree_evaluate(X509_POLICY_TREE *tree)
    666 {
    667     int ret, i;
    668     X509_POLICY_LEVEL *curr = tree->levels + 1;
    669     const X509_POLICY_CACHE *cache;
    670 
    671     for (i = 1; i < tree->nlevel; i++, curr++) {
    672         cache = policy_cache_set(curr->cert);
    673         if (!tree_link_nodes(curr, cache))
    674             return 0;
    675 
    676         if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)
    677             && !tree_link_any(curr, cache, tree))
    678             return 0;
    679         tree_print("before tree_prune()", tree, curr);
    680         ret = tree_prune(tree, curr);
    681         if (ret != 1)
    682             return ret;
    683     }
    684 
    685     return 1;
    686 
    687 }
    688 
    689 static void exnode_free(X509_POLICY_NODE *node)
    690 {
    691     if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE))
    692         OPENSSL_free(node);
    693 }
    694 
    695 void X509_policy_tree_free(X509_POLICY_TREE *tree)
    696 {
    697     X509_POLICY_LEVEL *curr;
    698     int i;
    699 
    700     if (!tree)
    701         return;
    702 
    703     sk_X509_POLICY_NODE_free(tree->auth_policies);
    704     sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free);
    705 
    706     for (i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++) {
    707         if (curr->cert)
    708             X509_free(curr->cert);
    709         if (curr->nodes)
    710             sk_X509_POLICY_NODE_pop_free(curr->nodes, policy_node_free);
    711         if (curr->anyPolicy)
    712             policy_node_free(curr->anyPolicy);
    713     }
    714 
    715     if (tree->extra_data)
    716         sk_X509_POLICY_DATA_pop_free(tree->extra_data, policy_data_free);
    717 
    718     OPENSSL_free(tree->levels);
    719     OPENSSL_free(tree);
    720 
    721 }
    722 
    723 /*
    724  * Application policy checking function. Return codes: 0 Internal Error.  1
    725  * Successful. -1 One or more certificates contain invalid or inconsistent
    726  * extensions -2 User constrained policy set empty and requireExplicit true.
    727  */
    728 
    729 int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
    730                       STACK_OF(X509) *certs,
    731                       STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags)
    732 {
    733     int ret;
    734     X509_POLICY_TREE *tree = NULL;
    735     STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL;
    736     *ptree = NULL;
    737 
    738     *pexplicit_policy = 0;
    739     ret = tree_init(&tree, certs, flags);
    740 
    741     switch (ret) {
    742 
    743         /* Tree empty requireExplicit False: OK */
    744     case 2:
    745         return 1;
    746 
    747         /* Some internal error */
    748     case -1:
    749         return -1;
    750 
    751         /* Some internal error */
    752     case 0:
    753         return 0;
    754 
    755         /* Tree empty requireExplicit True: Error */
    756 
    757     case 6:
    758         *pexplicit_policy = 1;
    759         return -2;
    760 
    761         /* Tree OK requireExplicit True: OK and continue */
    762     case 5:
    763         *pexplicit_policy = 1;
    764         break;
    765 
    766         /* Tree OK: continue */
    767 
    768     case 1:
    769         if (!tree)
    770             /*
    771              * tree_init() returns success and a null tree
    772              * if it's just looking at a trust anchor.
    773              * I'm not sure that returning success here is
    774              * correct, but I'm sure that reporting this
    775              * as an internal error which our caller
    776              * interprets as a malloc failure is wrong.
    777              */
    778             return 1;
    779         break;
    780     }
    781 
    782     if (!tree)
    783         goto error;
    784     ret = tree_evaluate(tree);
    785 
    786     tree_print("tree_evaluate()", tree, NULL);
    787 
    788     if (ret <= 0)
    789         goto error;
    790 
    791     /* Return value 2 means tree empty */
    792     if (ret == 2) {
    793         X509_policy_tree_free(tree);
    794         if (*pexplicit_policy)
    795             return -2;
    796         else
    797             return 1;
    798     }
    799 
    800     /* Tree is not empty: continue */
    801 
    802     ret = tree_calculate_authority_set(tree, &auth_nodes);
    803 
    804     if (!ret)
    805         goto error;
    806 
    807     if (!tree_calculate_user_set(tree, policy_oids, auth_nodes))
    808         goto error;
    809 
    810     if (ret == 2)
    811         sk_X509_POLICY_NODE_free(auth_nodes);
    812 
    813     if (tree)
    814         *ptree = tree;
    815 
    816     if (*pexplicit_policy) {
    817         nodes = X509_policy_tree_get0_user_policies(tree);
    818         if (sk_X509_POLICY_NODE_num(nodes) <= 0)
    819             return -2;
    820     }
    821 
    822     return 1;
    823 
    824  error:
    825 
    826     X509_policy_tree_free(tree);
    827 
    828     return 0;
    829 
    830 }
    831