195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * project 2004. 395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* ==================================================================== 595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Copyright (c) 2004 The OpenSSL Project. All rights reserved. 695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Redistribution and use in source and binary forms, with or without 895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * modification, are permitted provided that the following conditions 995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * are met: 1095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1. Redistributions of source code must retain the above copyright 1295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * notice, this list of conditions and the following disclaimer. 1395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2. Redistributions in binary form must reproduce the above copyright 1595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * notice, this list of conditions and the following disclaimer in 1695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the documentation and/or other materials provided with the 1795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * distribution. 1895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3. All advertising materials mentioning features or use of this 2095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * software must display the following acknowledgment: 2195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * "This product includes software developed by the OpenSSL Project 2295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 2395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 2595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * endorse or promote products derived from this software without 2695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * prior written permission. For written permission, please contact 2795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * licensing@OpenSSL.org. 2895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 5. Products derived from this software may not be called "OpenSSL" 3095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * nor may "OpenSSL" appear in their names without prior written 3195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * permission of the OpenSSL Project. 3295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 6. Redistributions of any form whatsoever must retain the following 3495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * acknowledgment: 3595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * "This product includes software developed by the OpenSSL Project 3695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 3795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 3995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 4195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 4295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 4595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 4895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 4995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OF THE POSSIBILITY OF SUCH DAMAGE. 5095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ==================================================================== 5195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 5295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This product includes cryptographic software written by Eric Young 5395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * (eay@cryptsoft.com). This product includes software written by Tim 5495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Hudson (tjh@cryptsoft.com). 5595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 5695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 5795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/mem.h> 5995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/obj.h> 6095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/stack.h> 6195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/thread.h> 6295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/x509.h> 6395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/x509v3.h> 6495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "pcy_int.h" 6695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Enable this to print out the complete policy tree at various point during 6995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * evaluation. 7095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 7195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 7295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/*#define OPENSSL_POLICY_DEBUG*/ 7395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 7495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#ifdef OPENSSL_POLICY_DEBUG 7595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 7695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic void expected_print(BIO *err, X509_POLICY_LEVEL *lev, 7795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_NODE *node, int indent) 7895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 7995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ( (lev->flags & X509_V_FLAG_INHIBIT_MAP) 8095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley || !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK)) 8195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BIO_puts(err, " Not Mapped\n"); 8295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 8395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 8495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int i; 8595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set; 8695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_OBJECT *oid; 8795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BIO_puts(err, " Expected: "); 8895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++) 8995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 9095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley oid = sk_ASN1_OBJECT_value(pset, i); 9195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (i) 9295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BIO_puts(err, ", "); 9395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley i2a_ASN1_OBJECT(err, oid); 9495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 9595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BIO_puts(err, "\n"); 9695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 9795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 9895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 9995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic void tree_print(char *str, X509_POLICY_TREE *tree, 10095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_LEVEL *curr) 10195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 10295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_LEVEL *plev; 10395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_NODE *node; 10495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int i; 10595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BIO *err; 10695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley err = BIO_new_fp(stderr, BIO_NOCLOSE); 10795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!curr) 10895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley curr = tree->levels + tree->nlevel; 10995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 11095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley curr++; 11195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BIO_printf(err, "Level print after %s\n", str); 11295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels); 11395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (plev = tree->levels; plev != curr; plev++) 11495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 11595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BIO_printf(err, "Level %ld, flags = %x\n", 11695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley plev - tree->levels, plev->flags); 11795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++) 11895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 11995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley node = sk_X509_POLICY_NODE_value(plev->nodes, i); 12095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_NODE_print(err, node, 2); 12195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley expected_print(err, plev, node, 2); 12295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BIO_printf(err, " Flags: %x\n", node->data->flags); 12395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 12495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (plev->anyPolicy) 12595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_NODE_print(err, plev->anyPolicy, 2); 12695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 12795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BIO_free(err); 12995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 13195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#else 13295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#define tree_print(a,b,c) /* */ 13495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#endif 13695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Initialize policy tree. Return values: 13895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 0 Some internal error occured. 13995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * -1 Inconsistent or invalid extensions in certificates. 14095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1 Tree initialized OK. 14195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2 Policy tree is empty. 14295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 5 Tree OK and requireExplicitPolicy true. 14395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 6 Tree empty and requireExplicitPolicy true. 14495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 14595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 14695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, 14795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned int flags) 14895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 14995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_TREE *tree; 15095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_LEVEL *level; 15195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const X509_POLICY_CACHE *cache; 15295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_DATA *data = NULL; 15395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509 *x; 15495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int ret = 1; 15595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int i, n; 15695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int explicit_policy; 15795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int any_skip; 15895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int map_skip; 15995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *ptree = NULL; 16095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley n = sk_X509_num(certs); 16195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 16295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#if 0 16395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Disable policy mapping for now... */ 16495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley flags |= X509_V_FLAG_INHIBIT_MAP; 16595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#endif 16695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 16795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (flags & X509_V_FLAG_EXPLICIT_POLICY) 16895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley explicit_policy = 0; 16995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 17095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley explicit_policy = n + 1; 17195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 17295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (flags & X509_V_FLAG_INHIBIT_ANY) 17395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley any_skip = 0; 17495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 17595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley any_skip = n + 1; 17695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 17795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (flags & X509_V_FLAG_INHIBIT_MAP) 17895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley map_skip = 0; 17995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 18095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley map_skip = n + 1; 18195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 18295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Can't do anything with just a trust anchor */ 18395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (n == 1) 18495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 18595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* First setup policy cache in all certificates apart from the 18695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * trust anchor. Note any bad cache results on the way. Also can 18795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * calculate explicit_policy value at this point. 18895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 18995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = n - 2; i >= 0; i--) 19095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 19195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley x = sk_X509_value(certs, i); 19295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_check_purpose(x, -1, -1); 19395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley cache = policy_cache_set(x); 19495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If cache NULL something bad happened: return immediately */ 19595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (cache == NULL) 19695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 19795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If inconsistent extensions keep a note of it but continue */ 19895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (x->ex_flags & EXFLAG_INVALID_POLICY) 19995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = -1; 20095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Otherwise if we have no data (hence no CertificatePolicies) 20195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * and haven't already set an inconsistent code note it. 20295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 20395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else if ((ret == 1) && !cache->data) 20495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = 2; 20595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (explicit_policy > 0) 20695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 20795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!(x->ex_flags & EXFLAG_SI)) 20895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley explicit_policy--; 20995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ((cache->explicit_skip != -1) 21095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley && (cache->explicit_skip < explicit_policy)) 21195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley explicit_policy = cache->explicit_skip; 21295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 21395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 21495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 21595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ret != 1) 21695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 21795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ret == 2 && !explicit_policy) 21895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 6; 21995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ret; 22095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 22195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 22295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 22395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If we get this far initialize the tree */ 22495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 22595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tree = OPENSSL_malloc(sizeof(X509_POLICY_TREE)); 22695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 22795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!tree) 22895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 22995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 23095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tree->flags = 0; 23195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tree->levels = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL) * n); 23295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tree->nlevel = 0; 23395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tree->extra_data = NULL; 23495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tree->auth_policies = NULL; 23595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tree->user_policies = NULL; 23695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 23795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!tree->levels) 23895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 23995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(tree); 24095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 24195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 24295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 24395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL)); 24495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 24595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tree->nlevel = n; 24695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 24795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley level = tree->levels; 24895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 24995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Root data: initialize to anyPolicy */ 25095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 25195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0); 25295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 25395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!data || !level_add_node(level, data, NULL, tree)) 25495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto bad_tree; 25595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 25695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = n - 2; i >= 0; i--) 25795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 25895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley level++; 25995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley x = sk_X509_value(certs, i); 26095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley cache = policy_cache_set(x); 261150c617cfce408faf1274a60e5db194595cb4473David Benjamin level->cert = X509_up_ref(x); 26295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 26395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!cache->anyPolicy) 26495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley level->flags |= X509_V_FLAG_INHIBIT_ANY; 26595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 26695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Determine inhibit any and inhibit map flags */ 26795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (any_skip == 0) 26895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 26995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Any matching allowed if certificate is self 27095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * issued and not the last in the chain. 27195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 27295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!(x->ex_flags & EXFLAG_SI) || (i == 0)) 27395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley level->flags |= X509_V_FLAG_INHIBIT_ANY; 27495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 27595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 27695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 27795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!(x->ex_flags & EXFLAG_SI)) 27895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley any_skip--; 27995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ((cache->any_skip >= 0) 28095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley && (cache->any_skip < any_skip)) 28195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley any_skip = cache->any_skip; 28295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 28395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 28495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (map_skip == 0) 28595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley level->flags |= X509_V_FLAG_INHIBIT_MAP; 28695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 28795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 28895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!(x->ex_flags & EXFLAG_SI)) 28995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley map_skip--; 29095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ((cache->map_skip >= 0) 29195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley && (cache->map_skip < map_skip)) 29295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley map_skip = cache->map_skip; 29395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 29495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 29595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 29695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 29795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *ptree = tree; 29895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 29995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (explicit_policy) 30095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 30195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 30295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 5; 30395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 30495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley bad_tree: 30595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 30695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_policy_tree_free(tree); 30795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 30895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 30995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 31095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 31195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 31295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int tree_link_matching_nodes(X509_POLICY_LEVEL *curr, 31395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const X509_POLICY_DATA *data) 31495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 31595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_LEVEL *last = curr - 1; 31695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_NODE *node; 31795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int matched = 0; 31895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t i; 31995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Iterate through all in nodes linking matches */ 32095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) 32195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 32295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley node = sk_X509_POLICY_NODE_value(last->nodes, i); 32395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (policy_node_match(last, node, data->valid_policy)) 32495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 32595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!level_add_node(curr, data, node, NULL)) 32695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 32795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley matched = 1; 32895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 32995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 33095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!matched && last->anyPolicy) 33195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 33295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!level_add_node(curr, data, last->anyPolicy, NULL)) 33395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 33495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 33595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 33695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 33795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 33895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* This corresponds to RFC3280 6.1.3(d)(1): 33995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * link any data from CertificatePolicies onto matching parent 34095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * or anyPolicy if no match. 34195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 34295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 34395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int tree_link_nodes(X509_POLICY_LEVEL *curr, 34495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const X509_POLICY_CACHE *cache) 34595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 34695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t i; 34795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_DATA *data; 34895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 34995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) 35095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 35195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley data = sk_X509_POLICY_DATA_value(cache->data, i); 35295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If a node is mapped any it doesn't have a corresponding 35395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * CertificatePolicies entry. 35495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * However such an identical node would be created 35595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * if anyPolicy matching is enabled because there would be 35695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * no match with the parent valid_policy_set. So we create 35795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * link because then it will have the mapping flags 35895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * right and we can prune it later. 35995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 36095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#if 0 36195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY) 36295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley && !(curr->flags & X509_V_FLAG_INHIBIT_ANY)) 36395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley continue; 36495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#endif 36595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Look for matching nodes in previous level */ 36695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!tree_link_matching_nodes(curr, data)) 36795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 36895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 36995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 37095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 37195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 37295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* This corresponds to RFC3280 6.1.3(d)(2): 37395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Create new data for any unmatched policies in the parent and link 37495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * to anyPolicy. 37595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 37695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 37795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int tree_add_unmatched(X509_POLICY_LEVEL *curr, 37895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const X509_POLICY_CACHE *cache, 37995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_OBJECT *id, 38095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_NODE *node, 38195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_TREE *tree) 38295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 38395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_DATA *data; 38495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (id == NULL) 38595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley id = node->data->valid_policy; 38695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Create a new node with qualifiers from anyPolicy and 38795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * id from unmatched node. 38895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 38995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley data = policy_data_new(NULL, id, node_critical(node)); 39095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 39195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (data == NULL) 39295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 39395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Curr may not have anyPolicy */ 39495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley data->qualifier_set = cache->anyPolicy->qualifier_set; 39595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; 39695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!level_add_node(curr, data, node, tree)) 39795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 39895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley policy_data_free(data); 39995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 40095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 40195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 40295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 40395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 40495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 40595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int tree_link_unmatched(X509_POLICY_LEVEL *curr, 40695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const X509_POLICY_CACHE *cache, 40795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_NODE *node, 40895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_TREE *tree) 40995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 41095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const X509_POLICY_LEVEL *last = curr - 1; 41195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t i; 41295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 41395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ( (last->flags & X509_V_FLAG_INHIBIT_MAP) 41495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley || !(node->data->flags & POLICY_DATA_FLAG_MAPPED)) 41595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 41695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If no policy mapping: matched if one child present */ 41795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (node->nchild) 41895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 41995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!tree_add_unmatched(curr, cache, NULL, node, tree)) 42095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 42195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Add it */ 42295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 42395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 42495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 42595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If mapping: matched if one child per expected policy set */ 42695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set; 42795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (node->nchild == sk_ASN1_OBJECT_num(expset)) 42895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 42995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Locate unmatched nodes */ 43095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++) 43195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 43295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i); 43395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (level_find_node(curr, node, oid)) 43495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley continue; 43595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!tree_add_unmatched(curr, cache, oid, node, tree)) 43695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 43795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 43895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 43995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 44095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 44195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 44295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 44395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 44495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 44595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int tree_link_any(X509_POLICY_LEVEL *curr, 44695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const X509_POLICY_CACHE *cache, 44795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_TREE *tree) 44895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 44995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t i; 45095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /*X509_POLICY_DATA *data;*/ 45195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_NODE *node; 45295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_LEVEL *last = curr - 1; 45395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 45495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) 45595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 45695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley node = sk_X509_POLICY_NODE_value(last->nodes, i); 45795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 45895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!tree_link_unmatched(curr, cache, node, tree)) 45995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 46095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 46195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#if 0 46295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 46395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Skip any node with any children: we only want unmathced 46495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * nodes. 46595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 46695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Note: need something better for policy mapping 46795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * because each node may have multiple children 46895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 46995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (node->nchild) 47095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley continue; 47195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 47295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Create a new node with qualifiers from anyPolicy and 47395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * id from unmatched node. 47495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 47595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley data = policy_data_new(NULL, node->data->valid_policy, 47695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley node_critical(node)); 47795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 47895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (data == NULL) 47995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 48095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Curr may not have anyPolicy */ 48195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley data->qualifier_set = cache->anyPolicy->qualifier_set; 48295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; 48395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!level_add_node(curr, data, node, tree)) 48495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 48595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley policy_data_free(data); 48695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 48795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 48895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 48995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#endif 49095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 49195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 49295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Finally add link to anyPolicy */ 49395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (last->anyPolicy) 49495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 49595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!level_add_node(curr, cache->anyPolicy, 49695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley last->anyPolicy, NULL)) 49795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 49895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 49995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 50095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 50195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 50295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Prune the tree: delete any child mapped child data on the current level 50395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * then proceed up the tree deleting any data with no children. If we ever 50495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * have no data on a level we can halt because the tree will be empty. 50595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 50695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 50795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr) 50895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 50995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley STACK_OF(X509_POLICY_NODE) *nodes; 51095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_NODE *node; 51195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int i; 51295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley nodes = curr->nodes; 51395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (curr->flags & X509_V_FLAG_INHIBIT_MAP) 51495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 51595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) 51695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 51795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley node = sk_X509_POLICY_NODE_value(nodes, i); 51895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Delete any mapped data: see RFC3280 XXXX */ 51995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) 52095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 52195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley node->parent->nchild--; 52295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(node); 52395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley (void)sk_X509_POLICY_NODE_delete(nodes,i); 52495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 52595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 52695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 52795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 52895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for(;;) { 52995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley --curr; 53095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley nodes = curr->nodes; 53195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) 53295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 53395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley node = sk_X509_POLICY_NODE_value(nodes, i); 53495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (node->nchild == 0) 53595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 53695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley node->parent->nchild--; 53795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(node); 53895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley (void)sk_X509_POLICY_NODE_delete(nodes, i); 53995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 54095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 54195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (curr->anyPolicy && !curr->anyPolicy->nchild) 54295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 54395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (curr->anyPolicy->parent) 54495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley curr->anyPolicy->parent->nchild--; 54595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(curr->anyPolicy); 54695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley curr->anyPolicy = NULL; 54795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 54895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (curr == tree->levels) 54995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 55095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If we zapped anyPolicy at top then tree is empty */ 55195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!curr->anyPolicy) 55295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 2; 55395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 55495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 55595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 55695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 55795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 55895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 55995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 56095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 56195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes, 56295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_NODE *pcy) 56395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 56495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!*pnodes) 56595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 56695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *pnodes = policy_node_cmp_new(); 56795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!*pnodes) 56895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 56995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 57095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else if (sk_X509_POLICY_NODE_find(*pnodes, NULL, pcy)) 57195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 57295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 57395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!sk_X509_POLICY_NODE_push(*pnodes, pcy)) 57495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 57595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 57695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 57795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 57895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 57995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 58095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Calculate the authority set based on policy tree. 58195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The 'pnodes' parameter is used as a store for the set of policy nodes 58295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * used to calculate the user set. If the authority set is not anyPolicy 58395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * then pnodes will just point to the authority set. If however the authority 58495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * set is anyPolicy then the set of valid policies (other than anyPolicy) 58595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * is store in pnodes. The return value of '2' is used in this case to indicate 58695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * that pnodes should be freed. 58795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 58895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 58995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int tree_calculate_authority_set(X509_POLICY_TREE *tree, 59095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley STACK_OF(X509_POLICY_NODE) **pnodes) 59195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 59295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_LEVEL *curr; 59395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_NODE *node, *anyptr; 59495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley STACK_OF(X509_POLICY_NODE) **addnodes; 59595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int i; 59695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t j; 59795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley curr = tree->levels + tree->nlevel - 1; 59895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 59995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If last level contains anyPolicy set is anyPolicy */ 60095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (curr->anyPolicy) 60195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 60295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy)) 60395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 60495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley addnodes = pnodes; 60595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 60695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 60795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Add policies to authority set */ 60895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley addnodes = &tree->auth_policies; 60995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 61095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley curr = tree->levels; 61195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = 1; i < tree->nlevel; i++) 61295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 61395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If no anyPolicy node on this this level it can't 61495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * appear on lower levels so end search. 61595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 61695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!(anyptr = curr->anyPolicy)) 61795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 61895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley curr++; 61995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++) 62095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 62195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley node = sk_X509_POLICY_NODE_value(curr->nodes, j); 62295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ((node->parent == anyptr) 62395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley && !tree_add_auth_node(addnodes, node)) 62495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 62595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 62695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 62795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 62895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (addnodes == pnodes) 62995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 2; 63095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 63195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *pnodes = tree->auth_policies; 63295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 63395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 63495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 63595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 63695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int tree_calculate_user_set(X509_POLICY_TREE *tree, 63795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley STACK_OF(ASN1_OBJECT) *policy_oids, 63895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley STACK_OF(X509_POLICY_NODE) *auth_nodes) 63995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 64095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t i; 64195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_NODE *node; 64295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_OBJECT *oid; 64395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 64495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_NODE *anyPolicy; 64595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_DATA *extra; 64695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 64795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Check if anyPolicy present in authority constrained policy set: 64895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * this will happen if it is a leaf node. 64995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 65095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 65195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (sk_ASN1_OBJECT_num(policy_oids) <= 0) 65295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 65395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 65495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy; 65595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 65695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) 65795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 65895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley oid = sk_ASN1_OBJECT_value(policy_oids, i); 65995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (OBJ_obj2nid(oid) == NID_any_policy) 66095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 66195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tree->flags |= POLICY_FLAG_ANY_POLICY; 66295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 66395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 66495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 66595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 66695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) 66795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 66895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley oid = sk_ASN1_OBJECT_value(policy_oids, i); 66995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley node = tree_find_sk(auth_nodes, oid); 67095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!node) 67195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 67295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!anyPolicy) 67395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley continue; 67495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Create a new node with policy ID from user set 67595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * and qualifiers from anyPolicy. 67695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 67795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley extra = policy_data_new(NULL, oid, 67895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley node_critical(anyPolicy)); 67995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!extra) 68095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 68195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley extra->qualifier_set = anyPolicy->data->qualifier_set; 68295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS 68395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley | POLICY_DATA_FLAG_EXTRA_NODE; 68495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley node = level_add_node(NULL, extra, anyPolicy->parent, 68595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tree); 68695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 68795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!tree->user_policies) 68895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 68995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tree->user_policies = sk_X509_POLICY_NODE_new_null(); 69095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!tree->user_policies) 69195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 69295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 69395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!sk_X509_POLICY_NODE_push(tree->user_policies, node)) 69495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 69595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 69695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 69795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 69895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 69995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 70095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int tree_evaluate(X509_POLICY_TREE *tree) 70195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 70295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int ret, i; 70395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_LEVEL *curr = tree->levels + 1; 70495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const X509_POLICY_CACHE *cache; 70595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 70695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for(i = 1; i < tree->nlevel; i++, curr++) 70795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 70895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley cache = policy_cache_set(curr->cert); 70995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!tree_link_nodes(curr, cache)) 71095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 71195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 71295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) 71395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley && !tree_link_any(curr, cache, tree)) 71495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 71595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tree_print("before tree_prune()", tree, curr); 71695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = tree_prune(tree, curr); 71795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ret != 1) 71895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ret; 71995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 72095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 72195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 72295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 72395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 72495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 72595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic void exnode_free(X509_POLICY_NODE *node) 72695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 72795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE)) 72895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(node); 72995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 73095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 73195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 73295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid X509_policy_tree_free(X509_POLICY_TREE *tree) 73395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 73495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_LEVEL *curr; 73595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int i; 73695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 73795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!tree) 73895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return; 73995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 74095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley sk_X509_POLICY_NODE_free(tree->auth_policies); 74195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free); 74295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 74395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for(i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++) 74495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 74595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (curr->cert) 74695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_free(curr->cert); 74795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (curr->nodes) 74895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley sk_X509_POLICY_NODE_pop_free(curr->nodes, 74995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley policy_node_free); 75095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (curr->anyPolicy) 75195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley policy_node_free(curr->anyPolicy); 75295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 75395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 75495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (tree->extra_data) 75595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley sk_X509_POLICY_DATA_pop_free(tree->extra_data, 75695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley policy_data_free); 75795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 75895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(tree->levels); 75995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(tree); 76095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 76195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 76295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 76395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Application policy checking function. 76495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Return codes: 76595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 0 Internal Error. 76695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1 Successful. 76795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * -1 One or more certificates contain invalid or inconsistent extensions 76895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * -2 User constrained policy set empty and requireExplicit true. 76995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 77095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 77195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, 77295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley STACK_OF(X509) *certs, 77395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley STACK_OF(ASN1_OBJECT) *policy_oids, 77495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned int flags) 77595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 77695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int ret; 77795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_POLICY_TREE *tree = NULL; 77895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL; 77995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *ptree = NULL; 78095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 78195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *pexplicit_policy = 0; 78295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = tree_init(&tree, certs, flags); 78395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 78495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley switch (ret) 78595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 78695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 78795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Tree empty requireExplicit False: OK */ 78895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case 2: 78995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 79095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 79195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Some internal error */ 79295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case -1: 79395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -1; 79495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 79595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Some internal error */ 79695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case 0: 79795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 79895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 79995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Tree empty requireExplicit True: Error */ 80095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 80195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case 6: 80295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *pexplicit_policy = 1; 80395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -2; 80495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 80595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Tree OK requireExplicit True: OK and continue */ 80695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case 5: 80795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *pexplicit_policy = 1; 80895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 80995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 81095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Tree OK: continue */ 81195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 81295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case 1: 81395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!tree) 81495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* 81595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * tree_init() returns success and a null tree 81695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * if it's just looking at a trust anchor. 81795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * I'm not sure that returning success here is 81895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * correct, but I'm sure that reporting this 81995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * as an internal error which our caller 82095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * interprets as a malloc failure is wrong. 82195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 82295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 82395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 82495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 82595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 82695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!tree) goto error; 82795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = tree_evaluate(tree); 82895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 82995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tree_print("tree_evaluate()", tree, NULL); 83095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 83195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ret <= 0) 83295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto error; 83395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 83495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Return value 2 means tree empty */ 83595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ret == 2) 83695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 83795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_policy_tree_free(tree); 83895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (*pexplicit_policy) 83995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -2; 84095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 84195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 84295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 84395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 84495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Tree is not empty: continue */ 84595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 84695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = tree_calculate_authority_set(tree, &auth_nodes); 84795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 84895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ret) 84995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto error; 85095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 85195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!tree_calculate_user_set(tree, policy_oids, auth_nodes)) 85295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto error; 85395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 85495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ret == 2) 85595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley sk_X509_POLICY_NODE_free(auth_nodes); 85695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 85795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (tree) 85895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *ptree = tree; 85995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 86095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (*pexplicit_policy) 86195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 86295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley nodes = X509_policy_tree_get0_user_policies(tree); 86395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (sk_X509_POLICY_NODE_num(nodes) <= 0) 86495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -2; 86595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 86695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 86795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 86895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 86995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley error: 87095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 87195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley X509_policy_tree_free(tree); 87295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 87395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 87495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 87595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 87695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 877