195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* pcy_node.c */
295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * project 2004.
495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */
595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* ====================================================================
695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Redistribution and use in source and binary forms, with or without
995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * modification, are permitted provided that the following conditions
1095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * are met:
1195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
1295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1. Redistributions of source code must retain the above copyright
1395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    notice, this list of conditions and the following disclaimer.
1495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
1595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2. Redistributions in binary form must reproduce the above copyright
1695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    notice, this list of conditions and the following disclaimer in
1795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    the documentation and/or other materials provided with the
1895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    distribution.
1995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
2095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3. All advertising materials mentioning features or use of this
2195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    software must display the following acknowledgment:
2295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    "This product includes software developed by the OpenSSL Project
2395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
2495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
2595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
2695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    endorse or promote products derived from this software without
2795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    prior written permission. For written permission, please contact
2895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    licensing@OpenSSL.org.
2995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
3095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 5. Products derived from this software may not be called "OpenSSL"
3195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    nor may "OpenSSL" appear in their names without prior written
3295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    permission of the OpenSSL Project.
3395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
3495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 6. Redistributions of any form whatsoever must retain the following
3595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    acknowledgment:
3695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    "This product includes software developed by the OpenSSL Project
3795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
3895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
3995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
4095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
4295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
4395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
4595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
4695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
4995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
5095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OF THE POSSIBILITY OF SUCH DAMAGE.
5195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ====================================================================
5295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
5395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This product includes cryptographic software written by Eric Young
5495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * (eay@cryptsoft.com).  This product includes software written by Tim
5595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Hudson (tjh@cryptsoft.com). */
5695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
5795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/asn1.h>
5895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/mem.h>
5995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/obj.h>
6095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/x509.h>
6195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/x509v3.h>
6295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
6395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "pcy_int.h"
6495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
6595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
6695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int node_cmp(const X509_POLICY_NODE **a,
6795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			const X509_POLICY_NODE **b)
6895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
6995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy);
7095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
7195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
7295c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleySTACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void)
7395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
7495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return sk_X509_POLICY_NODE_new(node_cmp);
7595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
7695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
7795c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyX509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes,
7895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley					const ASN1_OBJECT *id)
7995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
8095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_POLICY_DATA n;
8195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_POLICY_NODE l;
8295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	size_t idx;
8395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
8495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	n.valid_policy = (ASN1_OBJECT *)id;
8595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	l.data = &n;
8695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
8795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (!sk_X509_POLICY_NODE_find(nodes, &idx, &l))
8895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return NULL;
8995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
9095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return sk_X509_POLICY_NODE_value(nodes, idx);
9195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
9295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
9395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
9495c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyX509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
9595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley					const X509_POLICY_NODE *parent,
9695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley					const ASN1_OBJECT *id)
9795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
9895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_POLICY_NODE *node;
9995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	size_t i;
10095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++)
10195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
10295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		node = sk_X509_POLICY_NODE_value(level->nodes, i);
10395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (node->parent == parent)
10495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
10595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (!OBJ_cmp(node->data->valid_policy, id))
10695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				return node;
10795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
10895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
10995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return NULL;
11095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
11195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
11295c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyX509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
11395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			const X509_POLICY_DATA *data,
11495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			X509_POLICY_NODE *parent,
11595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			X509_POLICY_TREE *tree)
11695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
11795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_POLICY_NODE *node;
11895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	node = OPENSSL_malloc(sizeof(X509_POLICY_NODE));
11995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (!node)
12095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return NULL;
12195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	node->data = data;
12295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	node->parent = parent;
12395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	node->nchild = 0;
12495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (level)
12595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
12695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (OBJ_obj2nid(data->valid_policy) == NID_any_policy)
12795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
12895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (level->anyPolicy)
12995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				goto node_error;
13095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			level->anyPolicy = node;
13195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
13295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else
13395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
13495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
13595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (!level->nodes)
13695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				level->nodes = policy_node_cmp_new();
13795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (!level->nodes)
13895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				goto node_error;
13995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (!sk_X509_POLICY_NODE_push(level->nodes, node))
14095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				goto node_error;
14195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
14295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
14395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
14495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (tree)
14595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
14695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (!tree->extra_data)
14795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			 tree->extra_data = sk_X509_POLICY_DATA_new_null();
14895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (!tree->extra_data)
14995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			goto node_error;
15095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (!sk_X509_POLICY_DATA_push(tree->extra_data, data))
15195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			goto node_error;
15295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
15395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
15495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (parent)
15595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		parent->nchild++;
15695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
15795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return node;
15895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
15995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	node_error:
16095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	policy_node_free(node);
16195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return 0;
16295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
16395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
16495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
16595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid policy_node_free(X509_POLICY_NODE *node)
16695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
16795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	OPENSSL_free(node);
16895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
16995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
17095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* See if a policy node matches a policy OID. If mapping enabled look through
17195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * expected policy set otherwise just valid policy.
17295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */
17395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
17495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint policy_node_match(const X509_POLICY_LEVEL *lvl,
17595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		      const X509_POLICY_NODE *node, const ASN1_OBJECT *oid)
17695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
17795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	size_t i;
17895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ASN1_OBJECT *policy_oid;
17995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	const X509_POLICY_DATA *x = node->data;
18095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
18195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (	    (lvl->flags & X509_V_FLAG_INHIBIT_MAP)
18295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		|| !(x->flags & POLICY_DATA_FLAG_MAP_MASK))
18395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
18495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (!OBJ_cmp(x->valid_policy, oid))
18595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return 1;
18695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return 0;
18795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
18895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
18995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++)
19095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
19195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i);
19295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (!OBJ_cmp(policy_oid, oid))
19395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return 1;
19495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
19595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return 0;
19695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
19795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
198