1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* pcy_tree.c */
2e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * project 2004.
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ====================================================================
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the documentation and/or other materials provided with the
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    distribution.
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    software must display the following acknowledgment:
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    endorse or promote products derived from this software without
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    prior written permission. For written permission, please contact
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    licensing@OpenSSL.org.
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL"
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    nor may "OpenSSL" appear in their names without prior written
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    permission of the OpenSSL Project.
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    acknowledgment:
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE.
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ====================================================================
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This product includes cryptographic software written by Eric Young
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (eay@cryptsoft.com).  This product includes software written by Tim
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Hudson (tjh@cryptsoft.com).
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "cryptlib.h"
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/x509.h>
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/x509v3.h>
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "pcy_int.h"
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
65221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* Enable this to print out the complete policy tree at various point during
66221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * evaluation.
67221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom */
68221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
69221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/*#define OPENSSL_POLICY_DEBUG*/
70221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
71221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifdef OPENSSL_POLICY_DEBUG
72221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
73221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void expected_print(BIO *err, X509_POLICY_LEVEL *lev,
74221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				X509_POLICY_NODE *node, int indent)
75221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
76221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (	    (lev->flags & X509_V_FLAG_INHIBIT_MAP)
77221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		|| !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK))
78221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		BIO_puts(err, "  Not Mapped\n");
79221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else
80221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
81221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		int i;
82221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set;
83221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ASN1_OBJECT *oid;
84221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		BIO_puts(err, "  Expected: ");
85221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++)
86221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
87221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			oid = sk_ASN1_OBJECT_value(pset, i);
88221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (i)
89221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				BIO_puts(err, ", ");
90221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			i2a_ASN1_OBJECT(err, oid);
91221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
92221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		BIO_puts(err, "\n");
93221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
94221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
95221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
96221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void tree_print(char *str, X509_POLICY_TREE *tree,
97221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			X509_POLICY_LEVEL *curr)
98221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
99221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	X509_POLICY_LEVEL *plev;
100221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	X509_POLICY_NODE *node;
101221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int i;
102221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	BIO *err;
103221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err = BIO_new_fp(stderr, BIO_NOCLOSE);
104221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!curr)
105221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		curr = tree->levels + tree->nlevel;
106221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else
107221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		curr++;
108221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	BIO_printf(err, "Level print after %s\n", str);
109221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels);
110221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	for (plev = tree->levels; plev != curr; plev++)
111221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
112221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		BIO_printf(err, "Level %ld, flags = %x\n",
113221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				plev - tree->levels, plev->flags);
114221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++)
115221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
116221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			node = sk_X509_POLICY_NODE_value(plev->nodes, i);
117221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			X509_POLICY_NODE_print(err, node, 2);
118221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			expected_print(err, plev, node, 2);
119221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			BIO_printf(err, "  Flags: %x\n", node->data->flags);
120221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
121221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (plev->anyPolicy)
122221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			X509_POLICY_NODE_print(err, plev->anyPolicy, 2);
123221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
124221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
125221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	BIO_free(err);
126221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
127221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
128221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#else
129221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
130221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#define tree_print(a,b,c) /* */
131221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
132221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
133221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Initialize policy tree. Return values:
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *  0 Some internal error occured.
136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * -1 Inconsistent or invalid extensions in certificates.
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *  1 Tree initialized OK.
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *  2 Policy tree is empty.
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *  5 Tree OK and requireExplicitPolicy true.
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *  6 Tree empty and requireExplicitPolicy true.
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			unsigned int flags)
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509_POLICY_TREE *tree;
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509_POLICY_LEVEL *level;
148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const X509_POLICY_CACHE *cache;
149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509_POLICY_DATA *data = NULL;
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509 *x;
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret = 1;
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i, n;
153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int explicit_policy;
154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int any_skip;
155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int map_skip;
156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	*ptree = NULL;
157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	n = sk_X509_num(certs);
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
159221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#if 0
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Disable policy mapping for now... */
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	flags |= X509_V_FLAG_INHIBIT_MAP;
162221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (flags & X509_V_FLAG_EXPLICIT_POLICY)
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		explicit_policy = 0;
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		explicit_policy = n + 1;
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (flags & X509_V_FLAG_INHIBIT_ANY)
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		any_skip = 0;
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		any_skip = n + 1;
173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (flags & X509_V_FLAG_INHIBIT_MAP)
175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		map_skip = 0;
176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		map_skip = n + 1;
178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Can't do anything with just a trust anchor */
180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (n == 1)
181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 1;
182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* First setup policy cache in all certificates apart from the
183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * trust anchor. Note any bad cache results on the way. Also can
184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * calculate explicit_policy value at this point.
185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 */
186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for (i = n - 2; i >= 0; i--)
187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		x = sk_X509_value(certs, i);
189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		X509_check_purpose(x, -1, -1);
190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		cache = policy_cache_set(x);
191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* If cache NULL something bad happened: return immediately */
192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (cache == NULL)
193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* If inconsistent extensions keep a note of it but continue */
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (x->ex_flags & EXFLAG_INVALID_POLICY)
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret = -1;
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Otherwise if we have no data (hence no CertificatePolicies)
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * and haven't already set an inconsistent code note it.
199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 */
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if ((ret == 1) && !cache->data)
201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret = 2;
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (explicit_policy > 0)
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
204e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu			if (!(x->ex_flags & EXFLAG_SI))
205e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu				explicit_policy--;
206e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu			if ((cache->explicit_skip != -1)
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				&& (cache->explicit_skip < explicit_policy))
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				explicit_policy = cache->explicit_skip;
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ret != 1)
213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ret == 2 && !explicit_policy)
215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 6;
216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return ret;
217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* If we get this far initialize the tree */
221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	tree = OPENSSL_malloc(sizeof(X509_POLICY_TREE));
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!tree)
225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	tree->flags = 0;
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	tree->levels = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL) * n);
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	tree->nlevel = 0;
230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	tree->extra_data = NULL;
231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	tree->auth_policies = NULL;
232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	tree->user_policies = NULL;
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
23498d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom	if (!tree->levels)
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		OPENSSL_free(tree);
237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL));
241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	tree->nlevel = n;
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	level = tree->levels;
245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Root data: initialize to anyPolicy */
247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0);
249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!data || !level_add_node(level, data, NULL, tree))
251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto bad_tree;
252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for (i = n - 2; i >= 0; i--)
254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		level++;
256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		x = sk_X509_value(certs, i);
257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		cache = policy_cache_set(x);
258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		level->cert = x;
260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!cache->anyPolicy)
262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				level->flags |= X509_V_FLAG_INHIBIT_ANY;
263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Determine inhibit any and inhibit map flags */
265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (any_skip == 0)
266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* Any matching allowed if certificate is self
268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * issued and not the last in the chain.
269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 */
270e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu			if (!(x->ex_flags & EXFLAG_SI) || (i == 0))
271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				level->flags |= X509_V_FLAG_INHIBIT_ANY;
272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
275e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu			if (!(x->ex_flags & EXFLAG_SI))
276e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu				any_skip--;
277e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu			if ((cache->any_skip >= 0)
278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				&& (cache->any_skip < any_skip))
279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				any_skip = cache->any_skip;
280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (map_skip == 0)
283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			level->flags |= X509_V_FLAG_INHIBIT_MAP;
284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
286221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (!(x->ex_flags & EXFLAG_SI))
287221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				map_skip--;
288e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu			if ((cache->map_skip >= 0)
289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				&& (cache->map_skip < map_skip))
290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				map_skip = cache->map_skip;
291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	*ptree = tree;
296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (explicit_policy)
298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 1;
299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 5;
301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bad_tree:
303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509_policy_tree_free(tree);
305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 0;
307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
310221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
311221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				const X509_POLICY_DATA *data)
312221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
313221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	X509_POLICY_LEVEL *last = curr - 1;
314221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	X509_POLICY_NODE *node;
315221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int i, matched = 0;
316221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* Iterate through all in nodes linking matches */
317221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
318221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
319221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		node = sk_X509_POLICY_NODE_value(last->nodes, i);
320221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (policy_node_match(last, node, data->valid_policy))
321221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
322221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (!level_add_node(curr, data, node, NULL))
323221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				return 0;
324221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			matched = 1;
325221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
326221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
327221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!matched && last->anyPolicy)
328221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
329221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (!level_add_node(curr, data, last->anyPolicy, NULL))
330221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return 0;
331221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
332221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 1;
333221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
334221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
335221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* This corresponds to RFC3280 6.1.3(d)(1):
336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * link any data from CertificatePolicies onto matching parent
337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * or anyPolicy if no match.
338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int tree_link_nodes(X509_POLICY_LEVEL *curr,
341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				const X509_POLICY_CACHE *cache)
342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i;
344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509_POLICY_DATA *data;
34543c12e3d4f9bbbbd4a8ba7b149686437514bc6b6Brian Carlstrom
346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++)
347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		data = sk_X509_POLICY_DATA_value(cache->data, i);
349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* If a node is mapped any it doesn't have a corresponding
350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * CertificatePolicies entry.
351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * However such an identical node would be created
352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * if anyPolicy matching is enabled because there would be
353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * no match with the parent valid_policy_set. So we create
354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * link because then it will have the mapping flags
355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * right and we can prune it later.
356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 */
357221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#if 0
358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY)
359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			&& !(curr->flags & X509_V_FLAG_INHIBIT_ANY))
360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			continue;
361221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
362221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		/* Look for matching nodes in previous level */
363221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (!tree_link_matching_nodes(curr, data))
364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				return 0;
365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
369221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* This corresponds to RFC3280 6.1.3(d)(2):
370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Create new data for any unmatched policies in the parent and link
371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * to anyPolicy.
372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
374221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int tree_add_unmatched(X509_POLICY_LEVEL *curr,
375221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			const X509_POLICY_CACHE *cache,
376221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			const ASN1_OBJECT *id,
377221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			X509_POLICY_NODE *node,
378221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			X509_POLICY_TREE *tree)
379221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
380221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	X509_POLICY_DATA *data;
381221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (id == NULL)
382221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		id = node->data->valid_policy;
383221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* Create a new node with qualifiers from anyPolicy and
384221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	 * id from unmatched node.
385221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	 */
386221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	data = policy_data_new(NULL, id, node_critical(node));
387221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
388221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (data == NULL)
389221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
390221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* Curr may not have anyPolicy */
391221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	data->qualifier_set = cache->anyPolicy->qualifier_set;
392221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
393221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!level_add_node(curr, data, node, tree))
394221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
395221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		policy_data_free(data);
396221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
397221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
398221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
399221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 1;
400221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
401221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
402221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int tree_link_unmatched(X509_POLICY_LEVEL *curr,
403221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			const X509_POLICY_CACHE *cache,
404221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			X509_POLICY_NODE *node,
405221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			X509_POLICY_TREE *tree)
406221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
407221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	const X509_POLICY_LEVEL *last = curr - 1;
408221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int i;
409221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
410221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (	    (last->flags & X509_V_FLAG_INHIBIT_MAP)
411221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		|| !(node->data->flags & POLICY_DATA_FLAG_MAPPED))
412221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
413221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		/* If no policy mapping: matched if one child present */
414221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (node->nchild)
415221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return 1;
416221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (!tree_add_unmatched(curr, cache, NULL, node, tree))
417221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return 0;
418221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		/* Add it */
419221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
420221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else
421221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
422221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		/* If mapping: matched if one child per expected policy set */
423221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set;
424221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (node->nchild == sk_ASN1_OBJECT_num(expset))
425221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return 1;
426221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		/* Locate unmatched nodes */
427221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++)
428221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
429221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i);
430221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (level_find_node(curr, node, oid))
431221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				continue;
432221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (!tree_add_unmatched(curr, cache, oid, node, tree))
433221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				return 0;
434221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
435221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
436221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
437221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
438221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 1;
439221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
440221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
441221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
442656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int tree_link_any(X509_POLICY_LEVEL *curr,
443656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			const X509_POLICY_CACHE *cache,
444656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			X509_POLICY_TREE *tree)
445656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
446656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i;
447221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/*X509_POLICY_DATA *data;*/
448656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509_POLICY_NODE *node;
449221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	X509_POLICY_LEVEL *last = curr - 1;
450656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
451656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
452656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
453656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		node = sk_X509_POLICY_NODE_value(last->nodes, i);
454656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
455221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (!tree_link_unmatched(curr, cache, node, tree))
456221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return 0;
457221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
458221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#if 0
459221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
460656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Skip any node with any children: we only want unmathced
461656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * nodes.
462656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 *
463656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * Note: need something better for policy mapping
464656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * because each node may have multiple children
465656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 */
466656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (node->nchild)
467656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			continue;
468221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
469656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Create a new node with qualifiers from anyPolicy and
470656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * id from unmatched node.
471656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 */
472656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		data = policy_data_new(NULL, node->data->valid_policy,
473656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						node_critical(node));
474656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
475656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (data == NULL)
476656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
477e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		/* Curr may not have anyPolicy */
478e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		data->qualifier_set = cache->anyPolicy->qualifier_set;
479656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
480656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!level_add_node(curr, data, node, tree))
481656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
482656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			policy_data_free(data);
483656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
484656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
485221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
486221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
487221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
488656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
489656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Finally add link to anyPolicy */
490656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (last->anyPolicy)
491656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
492656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!level_add_node(curr, cache->anyPolicy,
493656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						last->anyPolicy, NULL))
494656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
495656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
496656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
497656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
498656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
499656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Prune the tree: delete any child mapped child data on the current level
500656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * then proceed up the tree deleting any data with no children. If we ever
501656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * have no data on a level we can halt because the tree will be empty.
502656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
503656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
504656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
505656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
506221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	STACK_OF(X509_POLICY_NODE) *nodes;
507656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509_POLICY_NODE *node;
508656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i;
509221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	nodes = curr->nodes;
510221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (curr->flags & X509_V_FLAG_INHIBIT_MAP)
511656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
512221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--)
513656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
514221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			node = sk_X509_POLICY_NODE_value(nodes, i);
515221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			/* Delete any mapped data: see RFC3280 XXXX */
516221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK)
517221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
518221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				node->parent->nchild--;
519221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				OPENSSL_free(node);
520221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				(void)sk_X509_POLICY_NODE_delete(nodes,i);
521221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
522656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
523656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
524656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
525656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for(;;)	{
526656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		--curr;
527221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		nodes = curr->nodes;
528221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--)
529656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
530221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			node = sk_X509_POLICY_NODE_value(nodes, i);
531656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (node->nchild == 0)
532656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
533656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				node->parent->nchild--;
534656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				OPENSSL_free(node);
535221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				(void)sk_X509_POLICY_NODE_delete(nodes, i);
536656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
537656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
538656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (curr->anyPolicy && !curr->anyPolicy->nchild)
539656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
540656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (curr->anyPolicy->parent)
541656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				curr->anyPolicy->parent->nchild--;
542656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			OPENSSL_free(curr->anyPolicy);
543656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			curr->anyPolicy = NULL;
544656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
545656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (curr == tree->levels)
546656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
547656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* If we zapped anyPolicy at top then tree is empty */
548656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!curr->anyPolicy)
549656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					return 2;
550656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 1;
551656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
552656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
553656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
554656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
555656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
556656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
557656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
558656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes,
559656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						 X509_POLICY_NODE *pcy)
560656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
561656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!*pnodes)
562656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
563656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*pnodes = policy_node_cmp_new();
564656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!*pnodes)
565656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
566656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
567656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else if (sk_X509_POLICY_NODE_find(*pnodes, pcy) != -1)
568656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 1;
569656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
570656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!sk_X509_POLICY_NODE_push(*pnodes, pcy))
571656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
572656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
573656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
574656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
575656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
576656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
577656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Calculate the authority set based on policy tree.
578656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The 'pnodes' parameter is used as a store for the set of policy nodes
579656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * used to calculate the user set. If the authority set is not anyPolicy
580656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * then pnodes will just point to the authority set. If however the authority
581656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * set is anyPolicy then the set of valid policies (other than anyPolicy)
582656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * is store in pnodes. The return value of '2' is used in this case to indicate
583656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * that pnodes should be freed.
584656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
585656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
586656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int tree_calculate_authority_set(X509_POLICY_TREE *tree,
587656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					STACK_OF(X509_POLICY_NODE) **pnodes)
588656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
589656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509_POLICY_LEVEL *curr;
590656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509_POLICY_NODE *node, *anyptr;
591656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	STACK_OF(X509_POLICY_NODE) **addnodes;
592656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i, j;
593656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	curr = tree->levels + tree->nlevel - 1;
594656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
595656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* If last level contains anyPolicy set is anyPolicy */
596656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (curr->anyPolicy)
597656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
598656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy))
599656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
600656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		addnodes = pnodes;
601656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
602656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
603656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Add policies to authority set */
604656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		addnodes = &tree->auth_policies;
605656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
606656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	curr = tree->levels;
607656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for (i = 1; i < tree->nlevel; i++)
608656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
609656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* If no anyPolicy node on this this level it can't
610656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * appear on lower levels so end search.
611656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 */
612656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!(anyptr = curr->anyPolicy))
613656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			break;
614656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		curr++;
615656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++)
616656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
617656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			node = sk_X509_POLICY_NODE_value(curr->nodes, j);
618656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if ((node->parent == anyptr)
619656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				&& !tree_add_auth_node(addnodes, node))
620656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					return 0;
621656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
622656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
623656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
624656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (addnodes == pnodes)
625656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 2;
626656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
627656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	*pnodes = tree->auth_policies;
628656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
629656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
630656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
631656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
632656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int tree_calculate_user_set(X509_POLICY_TREE *tree,
633656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				STACK_OF(ASN1_OBJECT) *policy_oids,
634656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				STACK_OF(X509_POLICY_NODE) *auth_nodes)
635656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
636656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i;
637656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509_POLICY_NODE *node;
638656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_OBJECT *oid;
639656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
640656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509_POLICY_NODE *anyPolicy;
641656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509_POLICY_DATA *extra;
642656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
643656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Check if anyPolicy present in authority constrained policy set:
644656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * this will happen if it is a leaf node.
645656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 */
646656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
647656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (sk_ASN1_OBJECT_num(policy_oids) <= 0)
648656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 1;
649656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
650656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy;
651656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
652656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++)
653656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
654656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		oid = sk_ASN1_OBJECT_value(policy_oids, i);
655656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (OBJ_obj2nid(oid) == NID_any_policy)
656656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
657656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			tree->flags |= POLICY_FLAG_ANY_POLICY;
658656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 1;
659656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
660656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
661656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
662656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++)
663656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
664656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		oid = sk_ASN1_OBJECT_value(policy_oids, i);
665656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		node = tree_find_sk(auth_nodes, oid);
666656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!node)
667656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
668656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!anyPolicy)
669656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				continue;
670656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* Create a new node with policy ID from user set
671656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * and qualifiers from anyPolicy.
672656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 */
673656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			extra = policy_data_new(NULL, oid,
674656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						node_critical(anyPolicy));
675656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!extra)
676656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				return 0;
677656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			extra->qualifier_set = anyPolicy->data->qualifier_set;
678656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS
679656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						| POLICY_DATA_FLAG_EXTRA_NODE;
680656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			node = level_add_node(NULL, extra, anyPolicy->parent,
681656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						tree);
682656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
683656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!tree->user_policies)
684656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
685656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			tree->user_policies = sk_X509_POLICY_NODE_new_null();
686656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!tree->user_policies)
687656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				return 1;
688656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
689656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!sk_X509_POLICY_NODE_push(tree->user_policies, node))
690656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
691656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
692656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
693656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
694656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
695656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
696656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int tree_evaluate(X509_POLICY_TREE *tree)
697656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
698656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret, i;
699656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509_POLICY_LEVEL *curr = tree->levels + 1;
700656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const X509_POLICY_CACHE *cache;
701656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
702656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for(i = 1; i < tree->nlevel; i++, curr++)
703656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
704656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		cache = policy_cache_set(curr->cert);
705656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!tree_link_nodes(curr, cache))
706656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
707656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
708656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)
709656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			&& !tree_link_any(curr, cache, tree))
710656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
711221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	tree_print("before tree_prune()", tree, curr);
712656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = tree_prune(tree, curr);
713656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ret != 1)
714656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return ret;
715656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
716656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
717656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
718656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
719656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
720656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
721656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void exnode_free(X509_POLICY_NODE *node)
722656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
723656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE))
724656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		OPENSSL_free(node);
725656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
726656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
727656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
728656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid X509_policy_tree_free(X509_POLICY_TREE *tree)
729656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
730656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509_POLICY_LEVEL *curr;
731656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i;
732656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
733656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!tree)
734656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return;
735656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
736656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	sk_X509_POLICY_NODE_free(tree->auth_policies);
737656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free);
738656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
739656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for(i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++)
740656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
741656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (curr->cert)
742656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			X509_free(curr->cert);
743656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (curr->nodes)
744656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			sk_X509_POLICY_NODE_pop_free(curr->nodes,
745656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						policy_node_free);
746656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (curr->anyPolicy)
747656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			policy_node_free(curr->anyPolicy);
748656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
749656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
750656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (tree->extra_data)
751656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		sk_X509_POLICY_DATA_pop_free(tree->extra_data,
752656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						policy_data_free);
753656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
754656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	OPENSSL_free(tree->levels);
755656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	OPENSSL_free(tree);
756656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
757656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
758656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
759656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Application policy checking function.
760656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Return codes:
761656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *  0 	Internal Error.
762656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *  1   Successful.
763656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * -1   One or more certificates contain invalid or inconsistent extensions
764656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * -2	User constrained policy set empty and requireExplicit true.
765656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
766656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
767656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
768656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			STACK_OF(X509) *certs,
769656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			STACK_OF(ASN1_OBJECT) *policy_oids,
770656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			unsigned int flags)
771656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
772656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret;
773656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509_POLICY_TREE *tree = NULL;
774656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL;
775656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	*ptree = NULL;
776656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
777656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	*pexplicit_policy = 0;
778656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret = tree_init(&tree, certs, flags);
779656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
780656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	switch (ret)
781656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
782656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
783656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Tree empty requireExplicit False: OK */
784656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case 2:
785656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 1;
786656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
787656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Some internal error */
788221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		case -1:
789221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -1;
790221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
791221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		/* Some internal error */
792656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case 0:
793656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
794656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
795656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Tree empty requireExplicit True: Error */
796656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
797656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case 6:
798656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*pexplicit_policy = 1;
799656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return -2;
800656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
801656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Tree OK requireExplicit True: OK and continue */
802656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case 5:
803656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*pexplicit_policy = 1;
804656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
805656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
806656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Tree OK: continue */
807656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
808656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case 1:
809656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!tree)
810656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/*
811656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * tree_init() returns success and a null tree
812656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * if it's just looking at a trust anchor.
813656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * I'm not sure that returning success here is
814656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * correct, but I'm sure that reporting this
815656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * as an internal error which our caller
816656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * interprets as a malloc failure is wrong.
817656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 */
818656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 1;
819656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
820656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
821656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
822656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!tree) goto error;
823656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret = tree_evaluate(tree);
824656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
825221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	tree_print("tree_evaluate()", tree, NULL);
826221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
827656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ret <= 0)
828656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto error;
829656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
830656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Return value 2 means tree empty */
831656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ret == 2)
832656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
833656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		X509_policy_tree_free(tree);
834656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (*pexplicit_policy)
835656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return -2;
836656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
837656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 1;
838656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
839656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
840656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Tree is not empty: continue */
841656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
842656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret = tree_calculate_authority_set(tree, &auth_nodes);
843656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
844656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!ret)
845656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto error;
846656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
847656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!tree_calculate_user_set(tree, policy_oids, auth_nodes))
848656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto error;
849656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
850656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ret == 2)
851656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		sk_X509_POLICY_NODE_free(auth_nodes);
852656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
853656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (tree)
854656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*ptree = tree;
855656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
856656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (*pexplicit_policy)
857656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
858656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		nodes = X509_policy_tree_get0_user_policies(tree);
859656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (sk_X509_POLICY_NODE_num(nodes) <= 0)
860656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return -2;
861656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
862656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
863656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
864656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
865656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	error:
866656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
867656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509_policy_tree_free(tree);
868656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
869656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 0;
870656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
871656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
872656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
873