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