1/* Written by Dr Stephen N Henson (steve@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@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@cryptsoft.com).  This product includes software written by Tim
54 * Hudson (tjh@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
78static 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
101static 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
148static 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
314static 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
345static 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
379static 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
407static 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 (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
447static 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
509static 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
561static 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
589static 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
636static 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
700static 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
725static 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
732void 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
771int 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