1d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * project 2004. */
3d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* ====================================================================
4d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
5d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
6d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Redistribution and use in source and binary forms, with or without
7d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * modification, are permitted provided that the following conditions
8d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * are met:
9d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
10d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 1. Redistributions of source code must retain the above copyright
11d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    notice, this list of conditions and the following disclaimer.
12d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
13d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 2. Redistributions in binary form must reproduce the above copyright
14d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    notice, this list of conditions and the following disclaimer in
15d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    the documentation and/or other materials provided with the
16d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    distribution.
17d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
18d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 3. All advertising materials mentioning features or use of this
19d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    software must display the following acknowledgment:
20d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    "This product includes software developed by the OpenSSL Project
21d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
22d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
23d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
24d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    endorse or promote products derived from this software without
25d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    prior written permission. For written permission, please contact
26d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    licensing@OpenSSL.org.
27d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
28d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 5. Products derived from this software may not be called "OpenSSL"
29d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    nor may "OpenSSL" appear in their names without prior written
30d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    permission of the OpenSSL Project.
31d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
32d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 6. Redistributions of any form whatsoever must retain the following
33d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    acknowledgment:
34d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    "This product includes software developed by the OpenSSL Project
35d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
36d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
37d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
38d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
40d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
41d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
46d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
47d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
48d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OF THE POSSIBILITY OF SUCH DAMAGE.
49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ====================================================================
50d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
51d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This product includes cryptographic software written by Eric Young
52d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * (eay@cryptsoft.com).  This product includes software written by Tim
53d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Hudson (tjh@cryptsoft.com). */
54d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
55d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <string.h>
56d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
57d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/buf.h>
58d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/lhash.h>
59d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/mem.h>
60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/obj.h>
61e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include <openssl/stack.h>
62d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/x509.h>
63d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/x509v3.h>
64d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
65d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include "vpm_int.h"
66d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
67d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
68d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* X509_VERIFY_PARAM functions */
69d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
70e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#define SET_HOST 0
71e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#define ADD_HOST 1
72e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
73e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic char *str_copy(char *s) { return OPENSSL_strdup(s); }
74e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic void str_free(char *s) { OPENSSL_free(s); }
75e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
76e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#define string_stack_free(sk) sk_OPENSSL_STRING_pop_free(sk, str_free)
77e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
78e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic int int_x509_param_set_hosts(X509_VERIFY_PARAM_ID *id, int mode,
79e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley				    const char *name, size_t namelen)
80e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	{
81e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	char *copy;
82e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
83e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	/*
84e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	 * Refuse names with embedded NUL bytes.
85e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	 * XXX: Do we need to push an error onto the error stack?
86e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	 */
87e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	if (name && memchr(name, '\0', namelen))
88e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		 return 0;
89e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
90e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	if (mode == SET_HOST && id->hosts)
91e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		{
92e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		string_stack_free(id->hosts);
93e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		id->hosts = NULL;
94e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		}
95e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	if (name == NULL || namelen == 0)
96e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		return 1;
97e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
98e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	copy = BUF_strndup(name, namelen);
99e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	if (copy == NULL)
100e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		return 0;
101e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
102e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	if (id->hosts == NULL &&
103e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	    (id->hosts = sk_OPENSSL_STRING_new_null()) == NULL)
104e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		{
105e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		OPENSSL_free(copy);
106e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		return 0;
107e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		}
108e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
109e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	if (!sk_OPENSSL_STRING_push(id->hosts, copy))
110e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		{
111e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		OPENSSL_free(copy);
112e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		if (sk_OPENSSL_STRING_num(id->hosts) == 0)
113e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley			{
114e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley			sk_OPENSSL_STRING_free(id->hosts);
115e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley			id->hosts = NULL;
116e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley			}
117e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		return 0;
118e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		}
119e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
120e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	return 1;
121e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	}
122e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
123d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic void x509_verify_param_zero(X509_VERIFY_PARAM *param)
124d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
125d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	X509_VERIFY_PARAM_ID *paramid;
126d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (!param)
127d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		return;
128d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	param->name = NULL;
129d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	param->purpose = 0;
130d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	param->trust = 0;
131d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	/*param->inh_flags = X509_VP_FLAG_DEFAULT;*/
132d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	param->inh_flags = 0;
133d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	param->flags = 0;
134d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	param->depth = -1;
135d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (param->policies)
136d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		{
137d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
138d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		param->policies = NULL;
139d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		}
140d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	paramid = param->id;
141e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	if (paramid->hosts)
142d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		{
143e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		string_stack_free(paramid->hosts);
144e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		paramid->hosts = NULL;
145e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		}
146e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	if (paramid->peername)
147e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		{
148e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		OPENSSL_free(paramid->peername);
149e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		paramid->peername = NULL;
150d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		}
151d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (paramid->email)
152d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		{
153d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		OPENSSL_free(paramid->email);
154d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		paramid->email = NULL;
155d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		paramid->emaillen = 0;
156d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		}
157d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (paramid->ip)
158d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		{
159d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		OPENSSL_free(paramid->ip);
160d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		paramid->ip = NULL;
161d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		paramid->iplen = 0;
162d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		}
163d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
164d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
165d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
166d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyX509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void)
167d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
168d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	X509_VERIFY_PARAM *param;
169d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	X509_VERIFY_PARAM_ID *paramid;
170d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	param = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM));
171d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (!param)
172d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		return NULL;
173d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	paramid = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM_ID));
174d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (!paramid)
175d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		{
176d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		OPENSSL_free(param);
177d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		return NULL;
178d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		}
179d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	memset(param, 0, sizeof(X509_VERIFY_PARAM));
180d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	memset(paramid, 0, sizeof(X509_VERIFY_PARAM_ID));
181d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	param->id = paramid;
182d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	x509_verify_param_zero(param);
183d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	return param;
184d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
185d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
186d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param)
187d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
188e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	if (param == NULL)
189e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		return;
190d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	x509_verify_param_zero(param);
191d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	OPENSSL_free(param->id);
192d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	OPENSSL_free(param);
193d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
194d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
195d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* This function determines how parameters are "inherited" from one structure
196d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * to another. There are several different ways this can happen.
197d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
198d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 1. If a child structure needs to have its values initialized from a parent
199d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    they are simply copied across. For example SSL_CTX copied to SSL.
200d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 2. If the structure should take on values only if they are currently unset.
201d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    For example the values in an SSL structure will take appropriate value
202d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    for SSL servers or clients but only if the application has not set new
203d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    ones.
204d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
205d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The "inh_flags" field determines how this function behaves.
206d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
207d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Normally any values which are set in the default are not copied from the
208d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * destination and verify flags are ORed together.
209d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
210d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied
211d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * to the destination. Effectively the values in "to" become default values
212d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * which will be used only if nothing new is set in "from".
213d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
214d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether
215d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * they are set or not. Flags is still Ored though.
216d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
217d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead
218d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * of ORed.
219d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
220d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * If X509_VP_FLAG_LOCKED is set then no values are copied.
221d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
222d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed
223d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * after the next call.
224d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */
225d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
226d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Macro to test if a field should be copied from src to dest */
227d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
228d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#define test_x509_verify_param_copy(field, def) \
229d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	(to_overwrite || \
230d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		((src->field != def) && (to_default || (dest->field == def))))
231d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
232d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* As above but for ID fields */
233d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
234d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#define test_x509_verify_param_copy_id(idf, def) \
235d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	test_x509_verify_param_copy(id->idf, def)
236d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
237d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Macro to test and copy a field if necessary */
238d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
239d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#define x509_verify_param_copy(field, def) \
240d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (test_x509_verify_param_copy(field, def)) \
241d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		dest->field = src->field
242d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
243d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
244d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest,
245d9e397b599b13d642138480a28c14db7a136bf0Adam Langley						const X509_VERIFY_PARAM *src)
246d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
247d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	unsigned long inh_flags;
248d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	int to_default, to_overwrite;
249d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	X509_VERIFY_PARAM_ID *id;
250d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (!src)
251d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		return 1;
252d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	id = src->id;
253d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	inh_flags = dest->inh_flags | src->inh_flags;
254d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
255d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (inh_flags & X509_VP_FLAG_ONCE)
256d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		dest->inh_flags = 0;
257d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
258d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (inh_flags & X509_VP_FLAG_LOCKED)
259d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		return 1;
260d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
261d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (inh_flags & X509_VP_FLAG_DEFAULT)
262d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		to_default = 1;
263d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	else
264d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		to_default = 0;
265d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
266d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (inh_flags & X509_VP_FLAG_OVERWRITE)
267d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		to_overwrite = 1;
268d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	else
269d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		to_overwrite = 0;
270d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
271d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	x509_verify_param_copy(purpose, 0);
272d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	x509_verify_param_copy(trust, 0);
273d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	x509_verify_param_copy(depth, -1);
274d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
275d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	/* If overwrite or check time not set, copy across */
276d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
277d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME))
278d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		{
279d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		dest->check_time = src->check_time;
280d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME;
281d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		/* Don't need to copy flag: that is done below */
282d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		}
283d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
284d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (inh_flags & X509_VP_FLAG_RESET_FLAGS)
285d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		dest->flags = 0;
286d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
287d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	dest->flags |= src->flags;
288d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
289d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (test_x509_verify_param_copy(policies, NULL))
290d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		{
291d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies))
292d9e397b599b13d642138480a28c14db7a136bf0Adam Langley			return 0;
293d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		}
294d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
295e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	/* Copy the host flags if and only if we're copying the host list */
296e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	if (test_x509_verify_param_copy_id(hosts, NULL))
297d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		{
298e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		if (dest->id->hosts)
299e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley			{
300e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley			string_stack_free(dest->id->hosts);
301e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley			dest->id->hosts = NULL;
302e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley			}
303e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley		if (id->hosts)
304e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley			{
305e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley			dest->id->hosts =
306e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley			    sk_OPENSSL_STRING_deep_copy(id->hosts,
307e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley							str_copy, str_free);
308e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley			if (dest->id->hosts == NULL)
309e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley				return 0;
310e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley			dest->id->hostflags = id->hostflags;
311e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley			}
312d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		}
313d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
314d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (test_x509_verify_param_copy_id(email, NULL))
315d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		{
316d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		if (!X509_VERIFY_PARAM_set1_email(dest, id->email, id->emaillen))
317d9e397b599b13d642138480a28c14db7a136bf0Adam Langley			return 0;
318d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		}
319d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
320d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (test_x509_verify_param_copy_id(ip, NULL))
321d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		{
322d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		if (!X509_VERIFY_PARAM_set1_ip(dest, id->ip, id->iplen))
323d9e397b599b13d642138480a28c14db7a136bf0Adam Langley			return 0;
324d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		}
325d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
326d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	return 1;
327d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
328d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
329d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to,
330d9e397b599b13d642138480a28c14db7a136bf0Adam Langley						const X509_VERIFY_PARAM *from)
331d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
332d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	unsigned long save_flags = to->inh_flags;
333d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	int ret;
334d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	to->inh_flags |= X509_VP_FLAG_DEFAULT;
335d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	ret = X509_VERIFY_PARAM_inherit(to, from);
336d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	to->inh_flags = save_flags;
337d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	return ret;
338d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
339d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
340e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic int int_x509_param_set1(char **pdest, size_t *pdestlen,
341e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley				const char *src, size_t srclen)
342d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
343d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	void *tmp;
344d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (src)
345d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		{
346d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		if (srclen == 0)
347d9e397b599b13d642138480a28c14db7a136bf0Adam Langley			{
348e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley			tmp = BUF_strdup(src);
349e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley			srclen = strlen(src);
350d9e397b599b13d642138480a28c14db7a136bf0Adam Langley			}
351d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		else
352d9e397b599b13d642138480a28c14db7a136bf0Adam Langley			tmp = BUF_memdup(src, srclen);
353d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		if (!tmp)
354d9e397b599b13d642138480a28c14db7a136bf0Adam Langley			return 0;
355d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		}
356d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	else
357d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		{
358d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		tmp = NULL;
359d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		srclen = 0;
360d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		}
361d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (*pdest)
362d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		OPENSSL_free(*pdest);
363d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	*pdest = tmp;
364d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (pdestlen)
365d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		*pdestlen = srclen;
366d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	return 1;
367d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
368d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
369d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name)
370d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
371d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (param->name)
372d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		OPENSSL_free(param->name);
373d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	param->name = BUF_strdup(name);
374d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (param->name)
375d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		return 1;
376d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	return 0;
377d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
378d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
379d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags)
380d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
381d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	param->flags |= flags;
382d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (flags & X509_V_FLAG_POLICY_MASK)
383d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		param->flags |= X509_V_FLAG_POLICY_CHECK;
384d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	return 1;
385d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
386d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
387d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, unsigned long flags)
388d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
389d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	param->flags &= ~flags;
390d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	return 1;
391d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
392d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
393d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyunsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param)
394d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
395d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	return param->flags;
396d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
397d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
398d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose)
399d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
400d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	return X509_PURPOSE_set(&param->purpose, purpose);
401d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
402d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
403d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust)
404d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
405d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	return X509_TRUST_set(&param->trust, trust);
406d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
407d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
408d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth)
409d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
410d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	param->depth = depth;
411d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
412d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
413d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t)
414d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
415d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	param->check_time = t;
416d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	param->flags |= X509_V_FLAG_USE_CHECK_TIME;
417d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
418d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
419d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, ASN1_OBJECT *policy)
420d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
421d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (!param->policies)
422d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		{
423d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		param->policies = sk_ASN1_OBJECT_new_null();
424d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		if (!param->policies)
425d9e397b599b13d642138480a28c14db7a136bf0Adam Langley			return 0;
426d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		}
427d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (!sk_ASN1_OBJECT_push(param->policies, policy))
428d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		return 0;
429d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	return 1;
430d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
431d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
432d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
433d9e397b599b13d642138480a28c14db7a136bf0Adam Langley					STACK_OF(ASN1_OBJECT) *policies)
434d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
435d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	size_t i;
436d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	ASN1_OBJECT *oid, *doid;
437d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (!param)
438d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		return 0;
439d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (param->policies)
440d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
441d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
442d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (!policies)
443d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		{
444d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		param->policies = NULL;
445d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		return 1;
446d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		}
447d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
448d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	param->policies = sk_ASN1_OBJECT_new_null();
449d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (!param->policies)
450d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		return 0;
451d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
452d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++)
453d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		{
454d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		oid = sk_ASN1_OBJECT_value(policies, i);
455d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		doid = OBJ_dup(oid);
456d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		if (!doid)
457d9e397b599b13d642138480a28c14db7a136bf0Adam Langley			return 0;
458d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		if (!sk_ASN1_OBJECT_push(param->policies, doid))
459d9e397b599b13d642138480a28c14db7a136bf0Adam Langley			{
460d9e397b599b13d642138480a28c14db7a136bf0Adam Langley			ASN1_OBJECT_free(doid);
461d9e397b599b13d642138480a28c14db7a136bf0Adam Langley			return 0;
462d9e397b599b13d642138480a28c14db7a136bf0Adam Langley			}
463d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		}
464d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	param->flags |= X509_V_FLAG_POLICY_CHECK;
465d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	return 1;
466d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
467d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
468d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
469e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley				const char *name, size_t namelen)
470e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	{
471e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	return int_x509_param_set_hosts(param->id, SET_HOST, name, namelen);
472e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	}
473e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
474e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyint X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
475e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley				const char *name, size_t namelen)
476d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
477e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	return int_x509_param_set_hosts(param->id, ADD_HOST, name, namelen);
478d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
479d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
480d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
481d9e397b599b13d642138480a28c14db7a136bf0Adam Langley					unsigned int flags)
482d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
483d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	param->id->hostflags = flags;
484d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
485d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
486e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleychar *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param)
487e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	{
488e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	return param->id->peername;
489e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	}
490e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
491d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
492e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley				const char *email, size_t emaillen)
493d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
494d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	return int_x509_param_set1(&param->id->email, &param->id->emaillen,
495d9e397b599b13d642138480a28c14db7a136bf0Adam Langley					email, emaillen);
496d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
497d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
498d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
499d9e397b599b13d642138480a28c14db7a136bf0Adam Langley					const unsigned char *ip, size_t iplen)
500d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
501d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (iplen != 0 && iplen != 4 && iplen != 16)
502d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		return 0;
503e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	return int_x509_param_set1((char **)&param->id->ip, &param->id->iplen,
504e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley				   (char *)ip, iplen);
505d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
506d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
507d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc)
508d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
509d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	unsigned char ipout[16];
510e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	size_t iplen;
511e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
512e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	iplen = (size_t) a2i_ipadd(ipout, ipasc);
513d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (iplen == 0)
514d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		return 0;
515e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley	return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen);
516d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
517d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
518d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param)
519d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
520d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	return param->depth;
521d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
522d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
523d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyconst char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param)
524d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
525d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	return param->name;
526d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
527d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
528e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic const X509_VERIFY_PARAM_ID _empty_id = {NULL, 0U, NULL, NULL, 0, NULL, 0};
529d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
530d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#define vpm_empty_id (X509_VERIFY_PARAM_ID *)&_empty_id
531d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
532d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Default verify parameters: these are used for various
533d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * applications and can be overridden by the user specified table.
534d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * NB: the 'name' field *must* be in alphabetical order because it
535d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * will be searched using OBJ_search.
536d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */
537d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
538d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const X509_VERIFY_PARAM default_table[] = {
539d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
540d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	(char *) "default",	/* X509 default parameters */
541d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	0,		/* Check time */
542d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	0,		/* internal flags */
543d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	0,		/* flags */
544d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	0,		/* purpose */
545d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	0,		/* trust */
546d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	100,		/* depth */
547d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	NULL,		/* policies */
548d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	vpm_empty_id
549d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	},
550d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
551d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	(char *) "pkcs7",			/* S/MIME sign parameters */
552d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	0,				/* Check time */
553d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	0,				/* internal flags */
554d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	0,				/* flags */
555d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	X509_PURPOSE_SMIME_SIGN,	/* purpose */
556d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	X509_TRUST_EMAIL,		/* trust */
557d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	-1,				/* depth */
558d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	NULL,				/* policies */
559d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	vpm_empty_id
560d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	},
561d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
562d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	(char *) "smime_sign",			/* S/MIME sign parameters */
563d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	0,				/* Check time */
564d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	0,				/* internal flags */
565d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	0,				/* flags */
566d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	X509_PURPOSE_SMIME_SIGN,	/* purpose */
567d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	X509_TRUST_EMAIL,		/* trust */
568d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	-1,				/* depth */
569d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	NULL,				/* policies */
570d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	vpm_empty_id
571d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	},
572d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
573d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	(char *) "ssl_client",			/* SSL/TLS client parameters */
574d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	0,				/* Check time */
575d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	0,				/* internal flags */
576d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	0,				/* flags */
577d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	X509_PURPOSE_SSL_CLIENT,	/* purpose */
578d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	X509_TRUST_SSL_CLIENT,		/* trust */
579d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	-1,				/* depth */
580d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	NULL,				/* policies */
581d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	vpm_empty_id
582d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	},
583d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
584d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	(char *) "ssl_server",			/* SSL/TLS server parameters */
585d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	0,				/* Check time */
586d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	0,				/* internal flags */
587d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	0,				/* flags */
588d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	X509_PURPOSE_SSL_SERVER,	/* purpose */
589d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	X509_TRUST_SSL_SERVER,		/* trust */
590d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	-1,				/* depth */
591d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	NULL,				/* policies */
592d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	vpm_empty_id
593d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}};
594d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
595d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic STACK_OF(X509_VERIFY_PARAM) *param_table = NULL;
596d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
597d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int param_cmp(const X509_VERIFY_PARAM **a,
598d9e397b599b13d642138480a28c14db7a136bf0Adam Langley			const X509_VERIFY_PARAM **b)
599d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
600d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	return strcmp((*a)->name, (*b)->name);
601d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
602d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
603d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param)
604d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
605d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	X509_VERIFY_PARAM *ptmp;
606d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (!param_table)
607d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		{
608d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		param_table = sk_X509_VERIFY_PARAM_new(param_cmp);
609d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		if (!param_table)
610d9e397b599b13d642138480a28c14db7a136bf0Adam Langley			return 0;
611d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		}
612d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	else
613d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		{
614d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		size_t idx;
615d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
616d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		if (sk_X509_VERIFY_PARAM_find(param_table, &idx, param))
617d9e397b599b13d642138480a28c14db7a136bf0Adam Langley			{
618d9e397b599b13d642138480a28c14db7a136bf0Adam Langley			ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx);
619d9e397b599b13d642138480a28c14db7a136bf0Adam Langley			X509_VERIFY_PARAM_free(ptmp);
620d9e397b599b13d642138480a28c14db7a136bf0Adam Langley			(void)sk_X509_VERIFY_PARAM_delete(param_table, idx);
621d9e397b599b13d642138480a28c14db7a136bf0Adam Langley			}
622d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		}
623d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (!sk_X509_VERIFY_PARAM_push(param_table, param))
624d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		return 0;
625d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	return 1;
626d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
627d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
628d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint X509_VERIFY_PARAM_get_count(void)
629d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
630d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	int num = sizeof(default_table)/sizeof(X509_VERIFY_PARAM);
631d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (param_table)
632d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		num += sk_X509_VERIFY_PARAM_num(param_table);
633d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	return num;
634d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
635d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
636d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyconst X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id)
637d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
638d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	int num = sizeof(default_table)/sizeof(X509_VERIFY_PARAM);
639d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (id < num)
640d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		return default_table + id;
641d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	return sk_X509_VERIFY_PARAM_value(param_table, id - num);
642d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
643d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
644d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyconst X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name)
645d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
646d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	X509_VERIFY_PARAM pm;
647d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	unsigned i, limit;
648d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
649d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	pm.name = (char *)name;
650d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (param_table)
651d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		{
652d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		size_t idx;
653d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		if (sk_X509_VERIFY_PARAM_find(param_table, &idx, &pm))
654d9e397b599b13d642138480a28c14db7a136bf0Adam Langley			return sk_X509_VERIFY_PARAM_value(param_table, idx);
655d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		}
656d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
657d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	limit = sizeof(default_table)/sizeof(X509_VERIFY_PARAM);
658d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	for (i = 0; i < limit; i++) {
659d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		if (strcmp(default_table[i].name, name) == 0) {
660d9e397b599b13d642138480a28c14db7a136bf0Adam Langley			return &default_table[i];
661d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		}
662d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
663d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	return NULL;
664d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
665d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
666d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid X509_VERIFY_PARAM_table_cleanup(void)
667d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	{
668d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	if (param_table)
669d9e397b599b13d642138480a28c14db7a136bf0Adam Langley		sk_X509_VERIFY_PARAM_pop_free(param_table,
670d9e397b599b13d642138480a28c14db7a136bf0Adam Langley						X509_VERIFY_PARAM_free);
671d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	param_table = NULL;
672d9e397b599b13d642138480a28c14db7a136bf0Adam Langley	}
673