1c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* pcy_tree.c */ 2c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * project 2004. 4c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 5c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* ==================================================================== 6c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Copyright (c) 2004 The OpenSSL Project. All rights reserved. 7c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 8c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Redistribution and use in source and binary forms, with or without 9c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * modification, are permitted provided that the following conditions 10c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * are met: 11c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 12c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 1. Redistributions of source code must retain the above copyright 13c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * notice, this list of conditions and the following disclaimer. 14c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 15c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 2. Redistributions in binary form must reproduce the above copyright 16c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * notice, this list of conditions and the following disclaimer in 17c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * the documentation and/or other materials provided with the 18c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * distribution. 19c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 20c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 3. All advertising materials mentioning features or use of this 21c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * software must display the following acknowledgment: 22c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * "This product includes software developed by the OpenSSL Project 23c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 25c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * endorse or promote products derived from this software without 27c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * prior written permission. For written permission, please contact 28c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * licensing@OpenSSL.org. 29c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 30c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 5. Products derived from this software may not be called "OpenSSL" 31c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * nor may "OpenSSL" appear in their names without prior written 32c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * permission of the OpenSSL Project. 33c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 34c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 6. Redistributions of any form whatsoever must retain the following 35c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * acknowledgment: 36c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * "This product includes software developed by the OpenSSL Project 37c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 39c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * OF THE POSSIBILITY OF SUCH DAMAGE. 51c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ==================================================================== 52c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 53c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This product includes cryptographic software written by Eric Young 54c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * (eay@cryptsoft.com). This product includes software written by Tim 55c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Hudson (tjh@cryptsoft.com). 56c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 57c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 58c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 59c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include "cryptlib.h" 60c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/x509.h> 61c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/x509v3.h> 62c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 63c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include "pcy_int.h" 64c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 65480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* Enable this to print out the complete policy tree at various point during 66480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * evaluation. 67480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org */ 68480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 69480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/*#define OPENSSL_POLICY_DEBUG*/ 70480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 71480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#ifdef OPENSSL_POLICY_DEBUG 72480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 73480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic void expected_print(BIO *err, X509_POLICY_LEVEL *lev, 74480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org X509_POLICY_NODE *node, int indent) 75480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 76480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if ( (lev->flags & X509_V_FLAG_INHIBIT_MAP) 77480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org || !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK)) 78480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org BIO_puts(err, " Not Mapped\n"); 79480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org else 80480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 81480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org int i; 82480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set; 83480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ASN1_OBJECT *oid; 84480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org BIO_puts(err, " Expected: "); 85480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++) 86480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 87480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org oid = sk_ASN1_OBJECT_value(pset, i); 88480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (i) 89480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org BIO_puts(err, ", "); 90480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org i2a_ASN1_OBJECT(err, oid); 91480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 92480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org BIO_puts(err, "\n"); 93480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 94480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 95480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 96480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic void tree_print(char *str, X509_POLICY_TREE *tree, 97480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org X509_POLICY_LEVEL *curr) 98480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 99480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org X509_POLICY_LEVEL *plev; 100480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org X509_POLICY_NODE *node; 101480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org int i; 102480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org BIO *err; 103480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org err = BIO_new_fp(stderr, BIO_NOCLOSE); 104480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!curr) 105480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org curr = tree->levels + tree->nlevel; 106480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org else 107480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org curr++; 108480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org BIO_printf(err, "Level print after %s\n", str); 109480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels); 110480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org for (plev = tree->levels; plev != curr; plev++) 111480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 112480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org BIO_printf(err, "Level %ld, flags = %x\n", 113480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org plev - tree->levels, plev->flags); 114480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++) 115480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 116480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org node = sk_X509_POLICY_NODE_value(plev->nodes, i); 117480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org X509_POLICY_NODE_print(err, node, 2); 118480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org expected_print(err, plev, node, 2); 119480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org BIO_printf(err, " Flags: %x\n", node->data->flags); 120480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 121480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (plev->anyPolicy) 122480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org X509_POLICY_NODE_print(err, plev->anyPolicy, 2); 123480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 124480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 125480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org BIO_free(err); 126480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 127480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 128480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#else 129480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 130480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#define tree_print(a,b,c) /* */ 131480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 132480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#endif 133480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 134c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Initialize policy tree. Return values: 135c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 0 Some internal error occured. 136c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * -1 Inconsistent or invalid extensions in certificates. 137c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 1 Tree initialized OK. 138c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 2 Policy tree is empty. 139c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 5 Tree OK and requireExplicitPolicy true. 140c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 6 Tree empty and requireExplicitPolicy true. 141c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 142c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 143c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, 144c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned int flags) 145c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 146c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_POLICY_TREE *tree; 147c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_POLICY_LEVEL *level; 148c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org const X509_POLICY_CACHE *cache; 149c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_POLICY_DATA *data = NULL; 150c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509 *x; 151c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int ret = 1; 152c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int i, n; 153c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int explicit_policy; 154c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int any_skip; 155c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int map_skip; 156c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *ptree = NULL; 157c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org n = sk_X509_num(certs); 158c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 159480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#if 0 160c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Disable policy mapping for now... */ 161c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org flags |= X509_V_FLAG_INHIBIT_MAP; 162480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#endif 163c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 164c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (flags & X509_V_FLAG_EXPLICIT_POLICY) 165c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org explicit_policy = 0; 166c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 167c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org explicit_policy = n + 1; 168c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 169c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (flags & X509_V_FLAG_INHIBIT_ANY) 170c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org any_skip = 0; 171c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 172c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org any_skip = n + 1; 173c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 174c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (flags & X509_V_FLAG_INHIBIT_MAP) 175c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org map_skip = 0; 176c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 177c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org map_skip = n + 1; 178c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 179c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Can't do anything with just a trust anchor */ 180c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (n == 1) 181c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 1; 182c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* First setup policy cache in all certificates apart from the 183c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * trust anchor. Note any bad cache results on the way. Also can 184c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * calculate explicit_policy value at this point. 185c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 186c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (i = n - 2; i >= 0; i--) 187c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 188c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org x = sk_X509_value(certs, i); 189c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_check_purpose(x, -1, -1); 190c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org cache = policy_cache_set(x); 191c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* If cache NULL something bad happened: return immediately */ 192c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (cache == NULL) 193c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 194c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* If inconsistent extensions keep a note of it but continue */ 195c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (x->ex_flags & EXFLAG_INVALID_POLICY) 196c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = -1; 197c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Otherwise if we have no data (hence no CertificatePolicies) 198c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * and haven't already set an inconsistent code note it. 199c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 200c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else if ((ret == 1) && !cache->data) 201c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = 2; 202c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (explicit_policy > 0) 203c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 204c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!(x->ex_flags & EXFLAG_SI)) 205c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org explicit_policy--; 206c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((cache->explicit_skip != -1) 207c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org && (cache->explicit_skip < explicit_policy)) 208c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org explicit_policy = cache->explicit_skip; 209c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 210c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 211c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 212c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ret != 1) 213c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 214c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ret == 2 && !explicit_policy) 215c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 6; 216c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return ret; 217c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 218c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 219c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 220c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* If we get this far initialize the tree */ 221c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 222c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org tree = OPENSSL_malloc(sizeof(X509_POLICY_TREE)); 223c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 224c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!tree) 225c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 226c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 227c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org tree->flags = 0; 228c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org tree->levels = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL) * n); 229c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org tree->nlevel = 0; 230c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org tree->extra_data = NULL; 231c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org tree->auth_policies = NULL; 232c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org tree->user_policies = NULL; 233c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 234c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!tree->levels) 235c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 236c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org OPENSSL_free(tree); 237c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 238c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 239c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 240c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL)); 241c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 242c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org tree->nlevel = n; 243c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 244c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org level = tree->levels; 245c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 246c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Root data: initialize to anyPolicy */ 247c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 248c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0); 249c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 250c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!data || !level_add_node(level, data, NULL, tree)) 251c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto bad_tree; 252c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 253c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (i = n - 2; i >= 0; i--) 254c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 255c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org level++; 256c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org x = sk_X509_value(certs, i); 257c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org cache = policy_cache_set(x); 258c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); 259c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org level->cert = x; 260c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 261c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!cache->anyPolicy) 262c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org level->flags |= X509_V_FLAG_INHIBIT_ANY; 263c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 264c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Determine inhibit any and inhibit map flags */ 265c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (any_skip == 0) 266c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 267c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Any matching allowed if certificate is self 268c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * issued and not the last in the chain. 269c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 270c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!(x->ex_flags & EXFLAG_SI) || (i == 0)) 271c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org level->flags |= X509_V_FLAG_INHIBIT_ANY; 272c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 273c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 274c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 275c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!(x->ex_flags & EXFLAG_SI)) 276c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org any_skip--; 277c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((cache->any_skip >= 0) 278c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org && (cache->any_skip < any_skip)) 279c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org any_skip = cache->any_skip; 280c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 281c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 282c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (map_skip == 0) 283c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org level->flags |= X509_V_FLAG_INHIBIT_MAP; 284c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 285c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 286480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!(x->ex_flags & EXFLAG_SI)) 287480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org map_skip--; 288c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((cache->map_skip >= 0) 289c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org && (cache->map_skip < map_skip)) 290c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org map_skip = cache->map_skip; 291c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 292c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 293c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 294c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 295c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *ptree = tree; 296c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 297c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (explicit_policy) 298c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 1; 299c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 300c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 5; 301c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 302c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bad_tree: 303c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 304c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_policy_tree_free(tree); 305c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 306c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 307c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 308c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 309c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 310480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int tree_link_matching_nodes(X509_POLICY_LEVEL *curr, 311480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org const X509_POLICY_DATA *data) 312480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 313480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org X509_POLICY_LEVEL *last = curr - 1; 314480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org X509_POLICY_NODE *node; 315480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org int i, matched = 0; 316480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* Iterate through all in nodes linking matches */ 317480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) 318480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 319480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org node = sk_X509_POLICY_NODE_value(last->nodes, i); 320480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (policy_node_match(last, node, data->valid_policy)) 321480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 322480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!level_add_node(curr, data, node, NULL)) 323480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 324480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org matched = 1; 325480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 326480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 327480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!matched && last->anyPolicy) 328480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 329480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!level_add_node(curr, data, last->anyPolicy, NULL)) 330480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 331480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 332480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 1; 333480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 334480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 335480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* This corresponds to RFC3280 6.1.3(d)(1): 336c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * link any data from CertificatePolicies onto matching parent 337c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * or anyPolicy if no match. 338c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 339c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 340c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int tree_link_nodes(X509_POLICY_LEVEL *curr, 341c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org const X509_POLICY_CACHE *cache) 342c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 343c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int i; 344c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_POLICY_DATA *data; 345480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 346c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) 347c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 348c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data = sk_X509_POLICY_DATA_value(cache->data, i); 349c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* If a node is mapped any it doesn't have a corresponding 350c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * CertificatePolicies entry. 351c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * However such an identical node would be created 352c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * if anyPolicy matching is enabled because there would be 353c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * no match with the parent valid_policy_set. So we create 354c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * link because then it will have the mapping flags 355c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * right and we can prune it later. 356c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 357480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#if 0 358c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY) 359c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org && !(curr->flags & X509_V_FLAG_INHIBIT_ANY)) 360c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org continue; 361480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#endif 362480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* Look for matching nodes in previous level */ 363480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!tree_link_matching_nodes(curr, data)) 364c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 365c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 366c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 1; 367c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 368c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 369480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* This corresponds to RFC3280 6.1.3(d)(2): 370c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Create new data for any unmatched policies in the parent and link 371c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * to anyPolicy. 372c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 373c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 374480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int tree_add_unmatched(X509_POLICY_LEVEL *curr, 375480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org const X509_POLICY_CACHE *cache, 376480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org const ASN1_OBJECT *id, 377480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org X509_POLICY_NODE *node, 378480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org X509_POLICY_TREE *tree) 379480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 380480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org X509_POLICY_DATA *data; 381480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (id == NULL) 382480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org id = node->data->valid_policy; 383480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* Create a new node with qualifiers from anyPolicy and 384480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * id from unmatched node. 385480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org */ 386480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org data = policy_data_new(NULL, id, node_critical(node)); 387480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 388480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (data == NULL) 389480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 390480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* Curr may not have anyPolicy */ 391480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org data->qualifier_set = cache->anyPolicy->qualifier_set; 392480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; 393480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!level_add_node(curr, data, node, tree)) 394480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 395480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org policy_data_free(data); 396480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 397480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 398480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 399480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 1; 400480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 401480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 402480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int tree_link_unmatched(X509_POLICY_LEVEL *curr, 403480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org const X509_POLICY_CACHE *cache, 404480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org X509_POLICY_NODE *node, 405480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org X509_POLICY_TREE *tree) 406480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 407480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org const X509_POLICY_LEVEL *last = curr - 1; 408480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org int i; 409480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 410480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if ( (last->flags & X509_V_FLAG_INHIBIT_MAP) 411480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org || !(node->data->flags & POLICY_DATA_FLAG_MAPPED)) 412480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 413480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* If no policy mapping: matched if one child present */ 414480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (node->nchild) 415480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 1; 416480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!tree_add_unmatched(curr, cache, NULL, node, tree)) 417480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 418480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* Add it */ 419480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 420480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org else 421480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 422480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* If mapping: matched if one child per expected policy set */ 423480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set; 424480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (node->nchild == sk_ASN1_OBJECT_num(expset)) 425480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 1; 426480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* Locate unmatched nodes */ 427480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++) 428480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 429480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i); 430480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (level_find_node(curr, node, oid)) 431480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org continue; 432480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!tree_add_unmatched(curr, cache, oid, node, tree)) 433480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 434480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 435480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 436480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 437480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 438480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 1; 439480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 440480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 441480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 442c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int tree_link_any(X509_POLICY_LEVEL *curr, 443c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org const X509_POLICY_CACHE *cache, 444c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_POLICY_TREE *tree) 445c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 446c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int i; 447480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /*X509_POLICY_DATA *data;*/ 448c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_POLICY_NODE *node; 449480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org X509_POLICY_LEVEL *last = curr - 1; 450c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 451c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) 452c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 453c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org node = sk_X509_POLICY_NODE_value(last->nodes, i); 454c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 455480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!tree_link_unmatched(curr, cache, node, tree)) 456480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 457480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 458480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#if 0 459480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 460c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Skip any node with any children: we only want unmathced 461c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * nodes. 462c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 463c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Note: need something better for policy mapping 464c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * because each node may have multiple children 465c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 466c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (node->nchild) 467c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org continue; 468480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 469c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Create a new node with qualifiers from anyPolicy and 470c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * id from unmatched node. 471c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 472c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data = policy_data_new(NULL, node->data->valid_policy, 473c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org node_critical(node)); 474c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 475c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (data == NULL) 476c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 477c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Curr may not have anyPolicy */ 478c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data->qualifier_set = cache->anyPolicy->qualifier_set; 479c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; 480c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!level_add_node(curr, data, node, tree)) 481c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 482c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org policy_data_free(data); 483c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 484c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 485480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 486480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#endif 487480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 488c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 489c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Finally add link to anyPolicy */ 490c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (last->anyPolicy) 491c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 492c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!level_add_node(curr, cache->anyPolicy, 493c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org last->anyPolicy, NULL)) 494c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 495c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 496c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 1; 497c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 498c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 499c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Prune the tree: delete any child mapped child data on the current level 500c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * then proceed up the tree deleting any data with no children. If we ever 501c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * have no data on a level we can halt because the tree will be empty. 502c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 503c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 504c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr) 505c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 506480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org STACK_OF(X509_POLICY_NODE) *nodes; 507c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_POLICY_NODE *node; 508c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int i; 509480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org nodes = curr->nodes; 510480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (curr->flags & X509_V_FLAG_INHIBIT_MAP) 511c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 512480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) 513c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 514480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org node = sk_X509_POLICY_NODE_value(nodes, i); 515480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* Delete any mapped data: see RFC3280 XXXX */ 516480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) 517480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 518480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org node->parent->nchild--; 519480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org OPENSSL_free(node); 520480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org (void)sk_X509_POLICY_NODE_delete(nodes,i); 521480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 522c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 523c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 524c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 525c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for(;;) { 526c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org --curr; 527480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org nodes = curr->nodes; 528480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) 529c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 530480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org node = sk_X509_POLICY_NODE_value(nodes, i); 531c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (node->nchild == 0) 532c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 533c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org node->parent->nchild--; 534c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org OPENSSL_free(node); 535480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org (void)sk_X509_POLICY_NODE_delete(nodes, i); 536c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 537c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 538c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (curr->anyPolicy && !curr->anyPolicy->nchild) 539c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 540c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (curr->anyPolicy->parent) 541c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org curr->anyPolicy->parent->nchild--; 542c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org OPENSSL_free(curr->anyPolicy); 543c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org curr->anyPolicy = NULL; 544c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 545c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (curr == tree->levels) 546c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 547c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* If we zapped anyPolicy at top then tree is empty */ 548c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!curr->anyPolicy) 549c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 2; 550c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 1; 551c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 552c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 553c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 554c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 1; 555c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 556c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 557c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 558c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes, 559c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_POLICY_NODE *pcy) 560c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 561c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!*pnodes) 562c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 563c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *pnodes = policy_node_cmp_new(); 564c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!*pnodes) 565c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 566c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 567c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else if (sk_X509_POLICY_NODE_find(*pnodes, pcy) != -1) 568c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 1; 569c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 570c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!sk_X509_POLICY_NODE_push(*pnodes, pcy)) 571c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 572c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 573c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 1; 574c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 575c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 576c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 577c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Calculate the authority set based on policy tree. 578c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * The 'pnodes' parameter is used as a store for the set of policy nodes 579c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * used to calculate the user set. If the authority set is not anyPolicy 580c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * then pnodes will just point to the authority set. If however the authority 581c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * set is anyPolicy then the set of valid policies (other than anyPolicy) 582c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * is store in pnodes. The return value of '2' is used in this case to indicate 583c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * that pnodes should be freed. 584c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 585c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 586c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int tree_calculate_authority_set(X509_POLICY_TREE *tree, 587c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org STACK_OF(X509_POLICY_NODE) **pnodes) 588c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 589c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_POLICY_LEVEL *curr; 590c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_POLICY_NODE *node, *anyptr; 591c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org STACK_OF(X509_POLICY_NODE) **addnodes; 592c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int i, j; 593c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org curr = tree->levels + tree->nlevel - 1; 594c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 595c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* If last level contains anyPolicy set is anyPolicy */ 596c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (curr->anyPolicy) 597c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 598c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy)) 599c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 600c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org addnodes = pnodes; 601c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 602c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 603c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Add policies to authority set */ 604c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org addnodes = &tree->auth_policies; 605c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 606c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org curr = tree->levels; 607c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (i = 1; i < tree->nlevel; i++) 608c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 609c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* If no anyPolicy node on this this level it can't 610c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * appear on lower levels so end search. 611c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 612c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!(anyptr = curr->anyPolicy)) 613c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 614c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org curr++; 615c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++) 616c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 617c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org node = sk_X509_POLICY_NODE_value(curr->nodes, j); 618c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((node->parent == anyptr) 619c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org && !tree_add_auth_node(addnodes, node)) 620c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 621c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 622c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 623c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 624c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (addnodes == pnodes) 625c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 2; 626c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 627c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *pnodes = tree->auth_policies; 628c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 629c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 1; 630c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 631c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 632c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int tree_calculate_user_set(X509_POLICY_TREE *tree, 633c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org STACK_OF(ASN1_OBJECT) *policy_oids, 634c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org STACK_OF(X509_POLICY_NODE) *auth_nodes) 635c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 636c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int i; 637c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_POLICY_NODE *node; 638c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ASN1_OBJECT *oid; 639c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 640c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_POLICY_NODE *anyPolicy; 641c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_POLICY_DATA *extra; 642c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 643c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Check if anyPolicy present in authority constrained policy set: 644c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * this will happen if it is a leaf node. 645c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 646c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 647c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (sk_ASN1_OBJECT_num(policy_oids) <= 0) 648c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 1; 649c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 650c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy; 651c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 652c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) 653c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 654c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org oid = sk_ASN1_OBJECT_value(policy_oids, i); 655c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (OBJ_obj2nid(oid) == NID_any_policy) 656c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 657c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org tree->flags |= POLICY_FLAG_ANY_POLICY; 658c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 1; 659c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 660c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 661c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 662c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) 663c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 664c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org oid = sk_ASN1_OBJECT_value(policy_oids, i); 665c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org node = tree_find_sk(auth_nodes, oid); 666c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!node) 667c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 668c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!anyPolicy) 669c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org continue; 670c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Create a new node with policy ID from user set 671c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * and qualifiers from anyPolicy. 672c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 673c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org extra = policy_data_new(NULL, oid, 674c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org node_critical(anyPolicy)); 675c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!extra) 676c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 677c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org extra->qualifier_set = anyPolicy->data->qualifier_set; 678c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS 679c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org | POLICY_DATA_FLAG_EXTRA_NODE; 680c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org node = level_add_node(NULL, extra, anyPolicy->parent, 681c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org tree); 682c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 683c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!tree->user_policies) 684c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 685c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org tree->user_policies = sk_X509_POLICY_NODE_new_null(); 686c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!tree->user_policies) 687c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 1; 688c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 689c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!sk_X509_POLICY_NODE_push(tree->user_policies, node)) 690c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 691c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 692c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 1; 693c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 694c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 695c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 696c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int tree_evaluate(X509_POLICY_TREE *tree) 697c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 698c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int ret, i; 699c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_POLICY_LEVEL *curr = tree->levels + 1; 700c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org const X509_POLICY_CACHE *cache; 701c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 702c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for(i = 1; i < tree->nlevel; i++, curr++) 703c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 704c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org cache = policy_cache_set(curr->cert); 705c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!tree_link_nodes(curr, cache)) 706c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 707c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 708c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) 709c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org && !tree_link_any(curr, cache, tree)) 710c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 711480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org tree_print("before tree_prune()", tree, curr); 712c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = tree_prune(tree, curr); 713c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ret != 1) 714c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return ret; 715c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 716c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 717c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 1; 718c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 719c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 720c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 721c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic void exnode_free(X509_POLICY_NODE *node) 722c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 723c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE)) 724c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org OPENSSL_free(node); 725c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 726c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 727c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 728c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgvoid X509_policy_tree_free(X509_POLICY_TREE *tree) 729c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 730c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_POLICY_LEVEL *curr; 731c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int i; 732c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 733c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!tree) 734c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return; 735c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 736c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org sk_X509_POLICY_NODE_free(tree->auth_policies); 737c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free); 738c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 739c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for(i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++) 740c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 741c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (curr->cert) 742c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_free(curr->cert); 743c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (curr->nodes) 744c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org sk_X509_POLICY_NODE_pop_free(curr->nodes, 745c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org policy_node_free); 746c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (curr->anyPolicy) 747c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org policy_node_free(curr->anyPolicy); 748c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 749c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 750c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (tree->extra_data) 751c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org sk_X509_POLICY_DATA_pop_free(tree->extra_data, 752c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org policy_data_free); 753c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 754c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org OPENSSL_free(tree->levels); 755c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org OPENSSL_free(tree); 756c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 757c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 758c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 759c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Application policy checking function. 760c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Return codes: 761c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 0 Internal Error. 762c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 1 Successful. 763c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * -1 One or more certificates contain invalid or inconsistent extensions 764c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * -2 User constrained policy set empty and requireExplicit true. 765c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 766c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 767c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, 768c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org STACK_OF(X509) *certs, 769c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org STACK_OF(ASN1_OBJECT) *policy_oids, 770c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned int flags) 771c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 772c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int ret; 773c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_POLICY_TREE *tree = NULL; 774c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL; 775c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *ptree = NULL; 776c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 777c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *pexplicit_policy = 0; 778c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = tree_init(&tree, certs, flags); 779c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 780c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org switch (ret) 781c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 782c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 783c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Tree empty requireExplicit False: OK */ 784c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case 2: 785c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 1; 786c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 787c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Some internal error */ 788480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org case -1: 789480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return -1; 790480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 791480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* Some internal error */ 792c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case 0: 793c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 794c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 795c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Tree empty requireExplicit True: Error */ 796c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 797c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case 6: 798c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *pexplicit_policy = 1; 799c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return -2; 800c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 801c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Tree OK requireExplicit True: OK and continue */ 802c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case 5: 803c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *pexplicit_policy = 1; 804c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 805c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 806c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Tree OK: continue */ 807c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 808c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case 1: 809c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!tree) 810c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* 811c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * tree_init() returns success and a null tree 812c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * if it's just looking at a trust anchor. 813c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * I'm not sure that returning success here is 814c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * correct, but I'm sure that reporting this 815c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * as an internal error which our caller 816c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * interprets as a malloc failure is wrong. 817c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 818c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 1; 819c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 820c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 821c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 822c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!tree) goto error; 823c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = tree_evaluate(tree); 824c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 825480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org tree_print("tree_evaluate()", tree, NULL); 826480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 827c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ret <= 0) 828c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto error; 829c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 830c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Return value 2 means tree empty */ 831c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ret == 2) 832c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 833c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_policy_tree_free(tree); 834c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (*pexplicit_policy) 835c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return -2; 836c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 837c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 1; 838c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 839c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 840c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Tree is not empty: continue */ 841c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 842c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = tree_calculate_authority_set(tree, &auth_nodes); 843c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 844c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!ret) 845c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto error; 846c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 847c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!tree_calculate_user_set(tree, policy_oids, auth_nodes)) 848c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto error; 849c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 850c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ret == 2) 851c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org sk_X509_POLICY_NODE_free(auth_nodes); 852c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 853c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (tree) 854c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *ptree = tree; 855c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 856c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (*pexplicit_policy) 857c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 858c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org nodes = X509_policy_tree_get0_user_policies(tree); 859c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (sk_X509_POLICY_NODE_num(nodes) <= 0) 860c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return -2; 861c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 862c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 863c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 1; 864c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 865c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org error: 866c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 867c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_policy_tree_free(tree); 868c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 869c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 870c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 871c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 872c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 873