⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcy_tree.c

📁 开源的ssl算法openssl,版本0.9.8H
💻 C
📖 第 1 页 / 共 2 页
字号:
/* pcy_tree.c *//* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL * project 2004. *//* ==================================================================== * Copyright (c) 2004 The OpenSSL Project.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer.  * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * 3. All advertising materials mentioning features or use of this *    software must display the following acknowledgment: *    "This product includes software developed by the OpenSSL Project *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" * * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to *    endorse or promote products derived from this software without *    prior written permission. For written permission, please contact *    licensing@OpenSSL.org. * * 5. Products derived from this software may not be called "OpenSSL" *    nor may "OpenSSL" appear in their names without prior written *    permission of the OpenSSL Project. * * 6. Redistributions of any form whatsoever must retain the following *    acknowledgment: *    "This product includes software developed by the OpenSSL Project *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" * * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This product includes cryptographic software written by Eric Young * (eay@cryptsoft.com).  This product includes software written by Tim * Hudson (tjh@cryptsoft.com). * */#include "cryptlib.h"#include <openssl/x509.h>#include <openssl/x509v3.h>#include "pcy_int.h"/* Initialize policy tree. Return values: *  0 Some internal error occured. * -1 Inconsistent or invalid extensions in certificates. *  1 Tree initialized OK. *  2 Policy tree is empty. *  5 Tree OK and requireExplicitPolicy true. *  6 Tree empty and requireExplicitPolicy true. */static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,			unsigned int flags)	{	X509_POLICY_TREE *tree;	X509_POLICY_LEVEL *level;	const X509_POLICY_CACHE *cache;	X509_POLICY_DATA *data = NULL;	X509 *x;	int ret = 1;	int i, n;	int explicit_policy;	int any_skip;	int map_skip;	*ptree = NULL;	n = sk_X509_num(certs);	/* Disable policy mapping for now... */	flags |= X509_V_FLAG_INHIBIT_MAP;	if (flags & X509_V_FLAG_EXPLICIT_POLICY)		explicit_policy = 0;	else		explicit_policy = n + 1;	if (flags & X509_V_FLAG_INHIBIT_ANY)		any_skip = 0;	else		any_skip = n + 1;	if (flags & X509_V_FLAG_INHIBIT_MAP)		map_skip = 0;	else		map_skip = n + 1;	/* Can't do anything with just a trust anchor */	if (n == 1)		return 1;	/* First setup policy cache in all certificates apart from the	 * trust anchor. Note any bad cache results on the way. Also can	 * calculate explicit_policy value at this point.	 */	for (i = n - 2; i >= 0; i--)		{		x = sk_X509_value(certs, i);		X509_check_purpose(x, -1, -1);		cache = policy_cache_set(x);		/* If cache NULL something bad happened: return immediately */		if (cache == NULL)			return 0;		/* If inconsistent extensions keep a note of it but continue */		if (x->ex_flags & EXFLAG_INVALID_POLICY)			ret = -1;		/* Otherwise if we have no data (hence no CertificatePolicies)		 * and haven't already set an inconsistent code note it.		 */		else if ((ret == 1) && !cache->data)			ret = 2;		if (explicit_policy > 0)			{			explicit_policy--;			if (!(x->ex_flags & EXFLAG_SS)				&& (cache->explicit_skip != -1)				&& (cache->explicit_skip < explicit_policy))				explicit_policy = cache->explicit_skip;			}		}	if (ret != 1)		{		if (ret == 2 && !explicit_policy)			return 6;		return ret;		}	/* If we get this far initialize the tree */	tree = OPENSSL_malloc(sizeof(X509_POLICY_TREE));	if (!tree)		return 0;	tree->flags = 0;	tree->levels = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL) * n);	tree->nlevel = 0;	tree->extra_data = NULL;	tree->auth_policies = NULL;	tree->user_policies = NULL;	if (!tree)		{		OPENSSL_free(tree);		return 0;		}	memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL));	tree->nlevel = n;	level = tree->levels;	/* Root data: initialize to anyPolicy */	data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0);	if (!data || !level_add_node(level, data, NULL, tree))		goto bad_tree;	for (i = n - 2; i >= 0; i--)		{		level++;		x = sk_X509_value(certs, i);		cache = policy_cache_set(x);		CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);		level->cert = x;		if (!cache->anyPolicy)				level->flags |= X509_V_FLAG_INHIBIT_ANY;		/* Determine inhibit any and inhibit map flags */		if (any_skip == 0)			{			/* Any matching allowed if certificate is self			 * issued and not the last in the chain.			 */			if (!(x->ex_flags & EXFLAG_SS) || (i == 0))				level->flags |= X509_V_FLAG_INHIBIT_ANY;			}		else			{			any_skip--;			if ((cache->any_skip > 0)				&& (cache->any_skip < any_skip))				any_skip = cache->any_skip;			}		if (map_skip == 0)			level->flags |= X509_V_FLAG_INHIBIT_MAP;		else			{			map_skip--;			if ((cache->map_skip > 0)				&& (cache->map_skip < map_skip))				map_skip = cache->map_skip;			}		}	*ptree = tree;	if (explicit_policy)		return 1;	else		return 5;	bad_tree:	X509_policy_tree_free(tree);	return 0;	}/* This corresponds to RFC3280 XXXX XXXXX: * link any data from CertificatePolicies onto matching parent * or anyPolicy if no match. */static int tree_link_nodes(X509_POLICY_LEVEL *curr,				const X509_POLICY_CACHE *cache)	{	int i;	X509_POLICY_LEVEL *last;	X509_POLICY_DATA *data;	X509_POLICY_NODE *parent;	last = curr - 1;	for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++)		{		data = sk_X509_POLICY_DATA_value(cache->data, i);		/* If a node is mapped any it doesn't have a corresponding		 * CertificatePolicies entry. 		 * However such an identical node would be created		 * if anyPolicy matching is enabled because there would be		 * no match with the parent valid_policy_set. So we create		 * link because then it will have the mapping flags		 * right and we can prune it later.		 */		if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY)			&& !(curr->flags & X509_V_FLAG_INHIBIT_ANY))			continue;		/* Look for matching node in parent */		parent = level_find_node(last, data->valid_policy);		/* If no match link to anyPolicy */		if (!parent)			parent = last->anyPolicy;		if (parent && !level_add_node(curr, data, parent, NULL))				return 0;		}	return 1;	}/* This corresponds to RFC3280 XXXX XXXXX: * Create new data for any unmatched policies in the parent and link * to anyPolicy. */static int tree_link_any(X509_POLICY_LEVEL *curr,			const X509_POLICY_CACHE *cache,			X509_POLICY_TREE *tree)	{	int i;	X509_POLICY_DATA *data;	X509_POLICY_NODE *node;	X509_POLICY_LEVEL *last;	last = curr - 1;	for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)		{		node = sk_X509_POLICY_NODE_value(last->nodes, i);		/* Skip any node with any children: we only want unmathced		 * nodes.		 *		 * Note: need something better for policy mapping		 * because each node may have multiple children 		 */		if (node->nchild)			continue;		/* Create a new node with qualifiers from anyPolicy and		 * id from unmatched node.		 */		data = policy_data_new(NULL, node->data->valid_policy, 						node_critical(node));		if (data == NULL)			return 0;		data->qualifier_set = curr->anyPolicy->data->qualifier_set;		data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;		if (!level_add_node(curr, data, node, tree))			{			policy_data_free(data);			return 0;			}		}	/* Finally add link to anyPolicy */	if (last->anyPolicy)		{		if (!level_add_node(curr, cache->anyPolicy,						last->anyPolicy, NULL))			return 0;		}	return 1;	}/* Prune the tree: delete any child mapped child data on the current level * then proceed up the tree deleting any data with no children. If we ever * have no data on a level we can halt because the tree will be empty. */static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)	{	X509_POLICY_NODE *node;	int i;	for (i = sk_X509_POLICY_NODE_num(curr->nodes) - 1; i >= 0; i--)		{		node = sk_X509_POLICY_NODE_value(curr->nodes, i);		/* Delete any mapped data: see RFC3280 XXXX */		if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK)			{			node->parent->nchild--;			OPENSSL_free(node);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -