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