xref: /openbsd/lib/libcrypto/x509/x509_vpm.c (revision a16560b1)
1*a16560b1Stb /* $OpenBSD: x509_vpm.c,v 1.45 2024/03/29 04:50:11 tb Exp $ */
282a8dcafSdjm /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
35650a0e1Sdjm  * project 2004.
45650a0e1Sdjm  */
55650a0e1Sdjm /* ====================================================================
65650a0e1Sdjm  * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
75650a0e1Sdjm  *
85650a0e1Sdjm  * Redistribution and use in source and binary forms, with or without
95650a0e1Sdjm  * modification, are permitted provided that the following conditions
105650a0e1Sdjm  * are met:
115650a0e1Sdjm  *
125650a0e1Sdjm  * 1. Redistributions of source code must retain the above copyright
135650a0e1Sdjm  *    notice, this list of conditions and the following disclaimer.
145650a0e1Sdjm  *
155650a0e1Sdjm  * 2. Redistributions in binary form must reproduce the above copyright
165650a0e1Sdjm  *    notice, this list of conditions and the following disclaimer in
175650a0e1Sdjm  *    the documentation and/or other materials provided with the
185650a0e1Sdjm  *    distribution.
195650a0e1Sdjm  *
205650a0e1Sdjm  * 3. All advertising materials mentioning features or use of this
215650a0e1Sdjm  *    software must display the following acknowledgment:
225650a0e1Sdjm  *    "This product includes software developed by the OpenSSL Project
235650a0e1Sdjm  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
245650a0e1Sdjm  *
255650a0e1Sdjm  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
265650a0e1Sdjm  *    endorse or promote products derived from this software without
275650a0e1Sdjm  *    prior written permission. For written permission, please contact
285650a0e1Sdjm  *    licensing@OpenSSL.org.
295650a0e1Sdjm  *
305650a0e1Sdjm  * 5. Products derived from this software may not be called "OpenSSL"
315650a0e1Sdjm  *    nor may "OpenSSL" appear in their names without prior written
325650a0e1Sdjm  *    permission of the OpenSSL Project.
335650a0e1Sdjm  *
345650a0e1Sdjm  * 6. Redistributions of any form whatsoever must retain the following
355650a0e1Sdjm  *    acknowledgment:
365650a0e1Sdjm  *    "This product includes software developed by the OpenSSL Project
375650a0e1Sdjm  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
385650a0e1Sdjm  *
395650a0e1Sdjm  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
405650a0e1Sdjm  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
415650a0e1Sdjm  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
425650a0e1Sdjm  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
435650a0e1Sdjm  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
445650a0e1Sdjm  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
455650a0e1Sdjm  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
465650a0e1Sdjm  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
475650a0e1Sdjm  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
485650a0e1Sdjm  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
495650a0e1Sdjm  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
505650a0e1Sdjm  * OF THE POSSIBILITY OF SUCH DAMAGE.
515650a0e1Sdjm  * ====================================================================
525650a0e1Sdjm  *
535650a0e1Sdjm  * This product includes cryptographic software written by Eric Young
545650a0e1Sdjm  * (eay@cryptsoft.com).  This product includes software written by Tim
555650a0e1Sdjm  * Hudson (tjh@cryptsoft.com).
565650a0e1Sdjm  *
575650a0e1Sdjm  */
585650a0e1Sdjm 
595650a0e1Sdjm #include <stdio.h>
60a8913c44Sjsing #include <string.h>
615650a0e1Sdjm 
62b6ab114eSjsing #include <openssl/buffer.h>
635650a0e1Sdjm #include <openssl/crypto.h>
64e932005dStb #include <openssl/err.h>
655650a0e1Sdjm #include <openssl/lhash.h>
66deda88cbSbeck #include <openssl/stack.h>
675650a0e1Sdjm #include <openssl/x509.h>
685650a0e1Sdjm #include <openssl/x509v3.h>
695650a0e1Sdjm 
70c9675a23Stb #include "x509_local.h"
71deda88cbSbeck 
725650a0e1Sdjm /* X509_VERIFY_PARAM functions */
735650a0e1Sdjm 
7447398500Sjsing int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email,
7547398500Sjsing     size_t emaillen);
7647398500Sjsing int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip,
7747398500Sjsing     size_t iplen);
7847398500Sjsing 
79deda88cbSbeck #define SET_HOST 0
80deda88cbSbeck #define ADD_HOST 1
81deda88cbSbeck 
82deda88cbSbeck static void
str_free(char * s)83deda88cbSbeck str_free(char *s)
84deda88cbSbeck {
85deda88cbSbeck 	free(s);
86deda88cbSbeck }
87deda88cbSbeck 
STACK_OF(OPENSSL_STRING)8835600121Stb static STACK_OF(OPENSSL_STRING) *
8935600121Stb sk_OPENSSL_STRING_deep_copy(const STACK_OF(OPENSSL_STRING) *sk)
90deda88cbSbeck {
9135600121Stb 	STACK_OF(OPENSSL_STRING) *new;
9235600121Stb 	char *copy = NULL;
9335600121Stb 	int i;
94deda88cbSbeck 
9535600121Stb 	if ((new = sk_OPENSSL_STRING_new_null()) == NULL)
9635600121Stb 		goto err;
9735600121Stb 
9835600121Stb 	for (i = 0; i < sk_OPENSSL_STRING_num(sk); i++) {
9935600121Stb 		if ((copy = strdup(sk_OPENSSL_STRING_value(sk, i))) == NULL)
10035600121Stb 			goto err;
10135600121Stb 		if (sk_OPENSSL_STRING_push(new, copy) <= 0)
10235600121Stb 			goto err;
10335600121Stb 		copy = NULL;
10435600121Stb 	}
10535600121Stb 
10635600121Stb 	return new;
10735600121Stb 
10835600121Stb  err:
10935600121Stb 	sk_OPENSSL_STRING_pop_free(new, str_free);
11035600121Stb 	free(copy);
11135600121Stb 
112deda88cbSbeck 	return NULL;
113deda88cbSbeck }
114deda88cbSbeck 
115deda88cbSbeck static int
x509_param_set_hosts_internal(X509_VERIFY_PARAM * vpm,int mode,const char * name,size_t namelen)116b6c35519Stb x509_param_set_hosts_internal(X509_VERIFY_PARAM *vpm, int mode,
117deda88cbSbeck     const char *name, size_t namelen)
118deda88cbSbeck {
119deda88cbSbeck 	char *copy;
120deda88cbSbeck 
121e9803435Sbeck 	if (name != NULL && namelen == 0)
122e9803435Sbeck 		namelen = strlen(name);
123deda88cbSbeck 	/*
124deda88cbSbeck 	 * Refuse names with embedded NUL bytes.
125deda88cbSbeck 	 */
126deda88cbSbeck 	if (name && memchr(name, '\0', namelen))
127deda88cbSbeck 		return 0;
128deda88cbSbeck 
129b6c35519Stb 	if (mode == SET_HOST && vpm->hosts) {
130b6c35519Stb 		sk_OPENSSL_STRING_pop_free(vpm->hosts, str_free);
131b6c35519Stb 		vpm->hosts = NULL;
132deda88cbSbeck 	}
133deda88cbSbeck 	if (name == NULL || namelen == 0)
134deda88cbSbeck 		return 1;
135deda88cbSbeck 	copy = strndup(name, namelen);
136deda88cbSbeck 	if (copy == NULL)
137deda88cbSbeck 		return 0;
138deda88cbSbeck 
139b6c35519Stb 	if (vpm->hosts == NULL &&
140b6c35519Stb 	    (vpm->hosts = sk_OPENSSL_STRING_new_null()) == NULL) {
141deda88cbSbeck 		free(copy);
142deda88cbSbeck 		return 0;
143deda88cbSbeck 	}
144deda88cbSbeck 
145b6c35519Stb 	if (!sk_OPENSSL_STRING_push(vpm->hosts, copy)) {
146deda88cbSbeck 		free(copy);
147b6c35519Stb 		if (sk_OPENSSL_STRING_num(vpm->hosts) == 0) {
148b6c35519Stb 			sk_OPENSSL_STRING_free(vpm->hosts);
149b6c35519Stb 			vpm->hosts = NULL;
150deda88cbSbeck 		}
151deda88cbSbeck 		return 0;
152deda88cbSbeck 	}
153deda88cbSbeck 
154deda88cbSbeck 	return 1;
155deda88cbSbeck }
156deda88cbSbeck 
15715238b08Sjsing static void
x509_verify_param_zero(X509_VERIFY_PARAM * param)15815238b08Sjsing x509_verify_param_zero(X509_VERIFY_PARAM *param)
1595650a0e1Sdjm {
1605650a0e1Sdjm 	if (!param)
1615650a0e1Sdjm 		return;
162b6c35519Stb 
1634c6be9d1Stb 	free(param->name);
1645650a0e1Sdjm 	param->name = NULL;
1655650a0e1Sdjm 	param->purpose = 0;
1665650a0e1Sdjm 	param->trust = 0;
167f1535dc8Sdjm 	/*param->inh_flags = X509_VP_FLAG_DEFAULT;*/
168e2ee43e0Sdjm 	param->inh_flags = 0;
169d4b1ba33Stb 	param->flags = 0;
1705650a0e1Sdjm 	param->depth = -1;
1715650a0e1Sdjm 	sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
1725650a0e1Sdjm 	param->policies = NULL;
173b6c35519Stb 	sk_OPENSSL_STRING_pop_free(param->hosts, str_free);
174b6c35519Stb 	param->hosts = NULL;
175b6c35519Stb 	free(param->peername);
176b6c35519Stb 	param->peername = NULL;
177b6c35519Stb 	free(param->email);
178b6c35519Stb 	param->email = NULL;
179b6c35519Stb 	param->emaillen = 0;
180b6c35519Stb 	free(param->ip);
181b6c35519Stb 	param->ip = NULL;
182b6c35519Stb 	param->iplen = 0;
183b6c35519Stb 	param->poisoned = 0;
1845650a0e1Sdjm }
1855650a0e1Sdjm 
18615238b08Sjsing X509_VERIFY_PARAM *
X509_VERIFY_PARAM_new(void)18715238b08Sjsing X509_VERIFY_PARAM_new(void)
1885650a0e1Sdjm {
1895650a0e1Sdjm 	X509_VERIFY_PARAM *param;
190b6c35519Stb 
19166415b63Stedu 	param = calloc(1, sizeof(X509_VERIFY_PARAM));
192deda88cbSbeck 	if (param == NULL)
193deda88cbSbeck 		return NULL;
1945650a0e1Sdjm 	x509_verify_param_zero(param);
1955650a0e1Sdjm 	return param;
1965650a0e1Sdjm }
197cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_new);
1985650a0e1Sdjm 
19915238b08Sjsing void
X509_VERIFY_PARAM_free(X509_VERIFY_PARAM * param)20015238b08Sjsing X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param)
2015650a0e1Sdjm {
202deda88cbSbeck 	if (param == NULL)
203deda88cbSbeck 		return;
2045650a0e1Sdjm 	x509_verify_param_zero(param);
2056f3a6cb1Sbeck 	free(param);
2065650a0e1Sdjm }
207cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_free);
2085650a0e1Sdjm 
20940007492Stb /*
21040007492Stb  * This function determines how parameters are "inherited" from one structure
2115650a0e1Sdjm  * to another. There are several different ways this can happen.
2125650a0e1Sdjm  *
2135650a0e1Sdjm  * 1. If a child structure needs to have its values initialized from a parent
2145650a0e1Sdjm  *    they are simply copied across. For example SSL_CTX copied to SSL.
2155650a0e1Sdjm  * 2. If the structure should take on values only if they are currently unset.
2165650a0e1Sdjm  *    For example the values in an SSL structure will take appropriate value
2175650a0e1Sdjm  *    for SSL servers or clients but only if the application has not set new
2185650a0e1Sdjm  *    ones.
2195650a0e1Sdjm  *
2205650a0e1Sdjm  * The "inh_flags" field determines how this function behaves.
2215650a0e1Sdjm  *
2225650a0e1Sdjm  * Normally any values which are set in the default are not copied from the
2235650a0e1Sdjm  * destination and verify flags are ORed together.
2245650a0e1Sdjm  *
2255650a0e1Sdjm  * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied
2265650a0e1Sdjm  * to the destination. Effectively the values in "to" become default values
2275650a0e1Sdjm  * which will be used only if nothing new is set in "from".
2285650a0e1Sdjm  *
2295650a0e1Sdjm  * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether
2305650a0e1Sdjm  * they are set or not. Flags is still Ored though.
2315650a0e1Sdjm  *
2325650a0e1Sdjm  * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead
2335650a0e1Sdjm  * of ORed.
2345650a0e1Sdjm  *
2355650a0e1Sdjm  * If X509_VP_FLAG_LOCKED is set then no values are copied.
2365650a0e1Sdjm  *
2375650a0e1Sdjm  * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed
2385650a0e1Sdjm  * after the next call.
2395650a0e1Sdjm  */
2405650a0e1Sdjm 
2415650a0e1Sdjm /* Macro to test if a field should be copied from src to dest */
2425650a0e1Sdjm #define test_x509_verify_param_copy(field, def) \
2435650a0e1Sdjm 	(to_overwrite || \
2445650a0e1Sdjm 		((src->field != def) && (to_default || (dest->field == def))))
2455650a0e1Sdjm 
2465650a0e1Sdjm /* Macro to test and copy a field if necessary */
2475650a0e1Sdjm #define x509_verify_param_copy(field, def) \
2485650a0e1Sdjm 	if (test_x509_verify_param_copy(field, def)) \
2495650a0e1Sdjm 		dest->field = src->field
2505650a0e1Sdjm 
25115238b08Sjsing int
X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM * dest,const X509_VERIFY_PARAM * src)25215238b08Sjsing X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, const X509_VERIFY_PARAM *src)
2535650a0e1Sdjm {
2545650a0e1Sdjm 	unsigned long inh_flags;
2555650a0e1Sdjm 	int to_default, to_overwrite;
25615238b08Sjsing 
2575650a0e1Sdjm 	if (!src)
2585650a0e1Sdjm 		return 1;
2595650a0e1Sdjm 	inh_flags = dest->inh_flags | src->inh_flags;
2605650a0e1Sdjm 
2615650a0e1Sdjm 	if (inh_flags & X509_VP_FLAG_ONCE)
2625650a0e1Sdjm 		dest->inh_flags = 0;
2635650a0e1Sdjm 
2645650a0e1Sdjm 	if (inh_flags & X509_VP_FLAG_LOCKED)
2655650a0e1Sdjm 		return 1;
2665650a0e1Sdjm 
2675650a0e1Sdjm 	if (inh_flags & X509_VP_FLAG_DEFAULT)
2685650a0e1Sdjm 		to_default = 1;
2695650a0e1Sdjm 	else
2705650a0e1Sdjm 		to_default = 0;
2715650a0e1Sdjm 
2725650a0e1Sdjm 	if (inh_flags & X509_VP_FLAG_OVERWRITE)
2735650a0e1Sdjm 		to_overwrite = 1;
2745650a0e1Sdjm 	else
2755650a0e1Sdjm 		to_overwrite = 0;
2765650a0e1Sdjm 
2775650a0e1Sdjm 	x509_verify_param_copy(purpose, 0);
2785650a0e1Sdjm 	x509_verify_param_copy(trust, 0);
2795650a0e1Sdjm 	x509_verify_param_copy(depth, -1);
2805650a0e1Sdjm 
2815650a0e1Sdjm 	/* If overwrite or check time not set, copy across */
2825650a0e1Sdjm 
2837609e5c6Stedu 	if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) {
2845650a0e1Sdjm 		dest->check_time = src->check_time;
2855650a0e1Sdjm 		dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME;
2865650a0e1Sdjm 		/* Don't need to copy flag: that is done below */
2875650a0e1Sdjm 	}
2885650a0e1Sdjm 
2895650a0e1Sdjm 	if (inh_flags & X509_VP_FLAG_RESET_FLAGS)
2905650a0e1Sdjm 		dest->flags = 0;
2915650a0e1Sdjm 
2925650a0e1Sdjm 	dest->flags |= src->flags;
2935650a0e1Sdjm 
2947609e5c6Stedu 	if (test_x509_verify_param_copy(policies, NULL)) {
2955650a0e1Sdjm 		if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies))
2965650a0e1Sdjm 			return 0;
2975650a0e1Sdjm 	}
2985650a0e1Sdjm 
299b6c35519Stb 	x509_verify_param_copy(hostflags, 0);
3005c7ffd32Stb 
301b6c35519Stb 	if (test_x509_verify_param_copy(hosts, NULL)) {
302b6c35519Stb 		if (dest->hosts) {
303b6c35519Stb 			sk_OPENSSL_STRING_pop_free(dest->hosts, str_free);
304b6c35519Stb 			dest->hosts = NULL;
305deda88cbSbeck 		}
306b6c35519Stb 		if (src->hosts) {
30735600121Stb 			dest->hosts = sk_OPENSSL_STRING_deep_copy(src->hosts);
308b6c35519Stb 			if (dest->hosts == NULL)
309deda88cbSbeck 				return 0;
310deda88cbSbeck 		}
311deda88cbSbeck 	}
312deda88cbSbeck 
313b6c35519Stb 	if (test_x509_verify_param_copy(email, NULL)) {
314b6c35519Stb 		if (!X509_VERIFY_PARAM_set1_email(dest, src->email,
315b6c35519Stb 		    src->emaillen))
316deda88cbSbeck 			return 0;
317deda88cbSbeck 	}
318deda88cbSbeck 
319b6c35519Stb 	if (test_x509_verify_param_copy(ip, NULL)) {
320b6c35519Stb 		if (!X509_VERIFY_PARAM_set1_ip(dest, src->ip, src->iplen))
321deda88cbSbeck 			return 0;
322deda88cbSbeck 	}
323deda88cbSbeck 
3245650a0e1Sdjm 	return 1;
3255650a0e1Sdjm }
326cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_inherit);
3275650a0e1Sdjm 
32815238b08Sjsing int
X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM * to,const X509_VERIFY_PARAM * from)32915238b08Sjsing X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, const X509_VERIFY_PARAM *from)
3305650a0e1Sdjm {
331f1535dc8Sdjm 	unsigned long save_flags = to->inh_flags;
332f1535dc8Sdjm 	int ret;
33315238b08Sjsing 
3345650a0e1Sdjm 	to->inh_flags |= X509_VP_FLAG_DEFAULT;
335f1535dc8Sdjm 	ret = X509_VERIFY_PARAM_inherit(to, from);
336f1535dc8Sdjm 	to->inh_flags = save_flags;
337f1535dc8Sdjm 	return ret;
3385650a0e1Sdjm }
339cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1);
3405650a0e1Sdjm 
341deda88cbSbeck static int
x509_param_set1_internal(char ** pdest,size_t * pdestlen,const char * src,size_t srclen,int nonul)3422a5239c0Sbeck x509_param_set1_internal(char **pdest, size_t *pdestlen,  const char *src,
3432a5239c0Sbeck     size_t srclen, int nonul)
344deda88cbSbeck {
345deda88cbSbeck 	char *tmp;
3462a5239c0Sbeck 
3472a5239c0Sbeck 	if (src == NULL)
3482a5239c0Sbeck 		return 0;
3492a5239c0Sbeck 
350deda88cbSbeck 	if (srclen == 0) {
3512a5239c0Sbeck 		srclen = strlen(src);
3522a5239c0Sbeck 		if (srclen == 0)
3532a5239c0Sbeck 			return 0;
354deda88cbSbeck 		if ((tmp = strdup(src)) == NULL)
355deda88cbSbeck 			return 0;
356deda88cbSbeck 	} else {
3572a5239c0Sbeck 		if (nonul && memchr(src, '\0', srclen))
3582a5239c0Sbeck 			return 0;
359deda88cbSbeck 		if ((tmp = malloc(srclen)) == NULL)
360deda88cbSbeck 			return 0;
361deda88cbSbeck 		memcpy(tmp, src, srclen);
362deda88cbSbeck 	}
3632a5239c0Sbeck 
364deda88cbSbeck 	if (*pdest)
365deda88cbSbeck 		free(*pdest);
366deda88cbSbeck 	*pdest = tmp;
367deda88cbSbeck 	if (pdestlen)
368deda88cbSbeck 		*pdestlen = srclen;
369deda88cbSbeck 	return 1;
370deda88cbSbeck }
371deda88cbSbeck 
37215238b08Sjsing int
X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM * param,const char * name)37315238b08Sjsing X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name)
3745650a0e1Sdjm {
3756f3a6cb1Sbeck 	free(param->name);
376cfa3bb9dSmiod 	param->name = NULL;
37769442892Sbeck 	if (name == NULL)
37869442892Sbeck 		return 1;
37969442892Sbeck 	param->name = strdup(name);
3805650a0e1Sdjm 	if (param->name)
3815650a0e1Sdjm 		return 1;
3825650a0e1Sdjm 	return 0;
3835650a0e1Sdjm }
384cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_name);
3855650a0e1Sdjm 
38615238b08Sjsing int
X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM * param,unsigned long flags)38715238b08Sjsing X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags)
3885650a0e1Sdjm {
3895650a0e1Sdjm 	param->flags |= flags;
3905650a0e1Sdjm 	return 1;
3915650a0e1Sdjm }
392cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_flags);
3935650a0e1Sdjm 
39415238b08Sjsing int
X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM * param,unsigned long flags)39515238b08Sjsing X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, unsigned long flags)
3965650a0e1Sdjm {
3975650a0e1Sdjm 	param->flags &= ~flags;
3985650a0e1Sdjm 	return 1;
3995650a0e1Sdjm }
400cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_clear_flags);
4015650a0e1Sdjm 
40215238b08Sjsing unsigned long
X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM * param)40315238b08Sjsing X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param)
4045650a0e1Sdjm {
4055650a0e1Sdjm 	return param->flags;
4065650a0e1Sdjm }
407cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_flags);
4085650a0e1Sdjm 
40915238b08Sjsing int
X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM * param,int purpose)41015238b08Sjsing X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose)
4115650a0e1Sdjm {
412e932005dStb 	if (purpose < X509_PURPOSE_MIN || purpose > X509_PURPOSE_MAX) {
413e932005dStb 		X509V3error(X509V3_R_INVALID_PURPOSE);
414e932005dStb 		return 0;
415e932005dStb 	}
416e932005dStb 
417e932005dStb 	param->purpose = purpose;
418e932005dStb 	return 1;
4195650a0e1Sdjm }
420cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_purpose);
4215650a0e1Sdjm 
42215238b08Sjsing int
X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM * param,int trust)42315238b08Sjsing X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust)
4245650a0e1Sdjm {
425e932005dStb 	if (trust < X509_TRUST_MIN || trust > X509_TRUST_MAX) {
426e932005dStb 		X509error(X509_R_INVALID_TRUST);
427e932005dStb 		return 0;
428e932005dStb 	}
429e932005dStb 
430e932005dStb 	param->trust = trust;
431e932005dStb 	return 1;
4325650a0e1Sdjm }
433cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_trust);
4345650a0e1Sdjm 
43515238b08Sjsing void
X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM * param,int depth)43615238b08Sjsing X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth)
4375650a0e1Sdjm {
4385650a0e1Sdjm 	param->depth = depth;
4395650a0e1Sdjm }
440cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_depth);
4415650a0e1Sdjm 
44215238b08Sjsing void
X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM * param,int auth_level)443e84fde04Stb X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM *param, int auth_level)
444e84fde04Stb {
445e84fde04Stb 	param->security_level = auth_level;
446e84fde04Stb }
447cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_auth_level);
448e84fde04Stb 
4496f34a740Stb time_t
X509_VERIFY_PARAM_get_time(const X509_VERIFY_PARAM * param)4506f34a740Stb X509_VERIFY_PARAM_get_time(const X509_VERIFY_PARAM *param)
4516f34a740Stb {
4526f34a740Stb 	return param->check_time;
4536f34a740Stb }
454cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_time);
4556f34a740Stb 
456e84fde04Stb void
X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM * param,time_t t)45715238b08Sjsing X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t)
4585650a0e1Sdjm {
4595650a0e1Sdjm 	param->check_time = t;
4605650a0e1Sdjm 	param->flags |= X509_V_FLAG_USE_CHECK_TIME;
4615650a0e1Sdjm }
462cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_time);
4635650a0e1Sdjm 
46415238b08Sjsing int
X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM * param,ASN1_OBJECT * policy)46515238b08Sjsing X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, ASN1_OBJECT *policy)
4665650a0e1Sdjm {
4676602a299Stb 	if (param->policies == NULL)
4685650a0e1Sdjm 		param->policies = sk_ASN1_OBJECT_new_null();
4696602a299Stb 	if (param->policies == NULL)
4705650a0e1Sdjm 		return 0;
4716602a299Stb 	if (sk_ASN1_OBJECT_push(param->policies, policy) <= 0)
4725650a0e1Sdjm 		return 0;
4735650a0e1Sdjm 	return 1;
4745650a0e1Sdjm }
475cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_add0_policy);
4765650a0e1Sdjm 
STACK_OF(ASN1_OBJECT)477*a16560b1Stb static STACK_OF(ASN1_OBJECT) *
478*a16560b1Stb sk_ASN1_OBJECT_deep_copy(const STACK_OF(ASN1_OBJECT) *sk)
479*a16560b1Stb {
480*a16560b1Stb 	STACK_OF(ASN1_OBJECT) *objs;
481*a16560b1Stb 	ASN1_OBJECT *obj = NULL;
482*a16560b1Stb 	int i;
483*a16560b1Stb 
484*a16560b1Stb 	if ((objs = sk_ASN1_OBJECT_new_null()) == NULL)
485*a16560b1Stb 		goto err;
486*a16560b1Stb 
487*a16560b1Stb 	for (i = 0; i < sk_ASN1_OBJECT_num(sk); i++) {
488*a16560b1Stb 		if ((obj = OBJ_dup(sk_ASN1_OBJECT_value(sk, i))) == NULL)
489*a16560b1Stb 			goto err;
490*a16560b1Stb 		if (sk_ASN1_OBJECT_push(objs, obj) <= 0)
491*a16560b1Stb 			goto err;
492*a16560b1Stb 		obj = NULL;
493*a16560b1Stb 	}
494*a16560b1Stb 
495*a16560b1Stb 	return objs;
496*a16560b1Stb 
497*a16560b1Stb  err:
498*a16560b1Stb 	sk_ASN1_OBJECT_pop_free(objs, ASN1_OBJECT_free);
499*a16560b1Stb 	ASN1_OBJECT_free(obj);
500*a16560b1Stb 
501*a16560b1Stb 	return NULL;
502*a16560b1Stb }
503*a16560b1Stb 
50415238b08Sjsing int
X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM * param,STACK_OF (ASN1_OBJECT)* policies)50515238b08Sjsing X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
5065650a0e1Sdjm     STACK_OF(ASN1_OBJECT) *policies)
5075650a0e1Sdjm {
508*a16560b1Stb 	if (param == NULL)
5095650a0e1Sdjm 		return 0;
510*a16560b1Stb 
5115650a0e1Sdjm 	sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
5125650a0e1Sdjm 	param->policies = NULL;
513*a16560b1Stb 
514*a16560b1Stb 	if (policies == NULL)
5155650a0e1Sdjm 		return 1;
5165650a0e1Sdjm 
517*a16560b1Stb 	if ((param->policies = sk_ASN1_OBJECT_deep_copy(policies)) == NULL)
5185650a0e1Sdjm 		return 0;
5195650a0e1Sdjm 
5205650a0e1Sdjm 	return 1;
5215650a0e1Sdjm }
522cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_policies);
5235650a0e1Sdjm 
52415238b08Sjsing int
X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM * param,const char * name,size_t namelen)525deda88cbSbeck X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
526deda88cbSbeck     const char *name, size_t namelen)
527deda88cbSbeck {
528b6c35519Stb 	if (x509_param_set_hosts_internal(param, SET_HOST, name, namelen))
5292a5239c0Sbeck 		return 1;
530b6c35519Stb 	param->poisoned = 1;
5312a5239c0Sbeck 	return 0;
532deda88cbSbeck }
533cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_host);
534deda88cbSbeck 
535deda88cbSbeck int
X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM * param,const char * name,size_t namelen)536deda88cbSbeck X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
537deda88cbSbeck     const char *name, size_t namelen)
538deda88cbSbeck {
539b6c35519Stb 	if (x509_param_set_hosts_internal(param, ADD_HOST, name, namelen))
5402a5239c0Sbeck 		return 1;
541b6c35519Stb 	param->poisoned = 1;
5422a5239c0Sbeck 	return 0;
543deda88cbSbeck }
544cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_add1_host);
545deda88cbSbeck 
546e51d4db3Stb /* Public API in OpenSSL - nothing seems to use this. */
547e51d4db3Stb unsigned int
X509_VERIFY_PARAM_get_hostflags(X509_VERIFY_PARAM * param)548e51d4db3Stb X509_VERIFY_PARAM_get_hostflags(X509_VERIFY_PARAM *param)
549e51d4db3Stb {
550b6c35519Stb 	return param->hostflags;
551e51d4db3Stb }
552e51d4db3Stb 
553deda88cbSbeck void
X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM * param,unsigned int flags)554deda88cbSbeck X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, unsigned int flags)
555deda88cbSbeck {
556b6c35519Stb 	param->hostflags = flags;
557deda88cbSbeck }
558cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_hostflags);
559deda88cbSbeck 
560deda88cbSbeck char *
X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM * param)561deda88cbSbeck X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param)
562deda88cbSbeck {
563b6c35519Stb 	return param->peername;
564deda88cbSbeck }
565cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_get0_peername);
566deda88cbSbeck 
567deda88cbSbeck int
X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM * param,const char * email,size_t emaillen)568deda88cbSbeck X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,  const char *email,
569deda88cbSbeck     size_t emaillen)
570deda88cbSbeck {
571b6c35519Stb 	if (x509_param_set1_internal(&param->email, &param->emaillen,
5722a5239c0Sbeck 	    email, emaillen, 1))
5732a5239c0Sbeck 		return 1;
574b6c35519Stb 	param->poisoned = 1;
5752a5239c0Sbeck 	return 0;
576deda88cbSbeck }
577cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_email);
578deda88cbSbeck 
579deda88cbSbeck int
X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM * param,const unsigned char * ip,size_t iplen)580deda88cbSbeck X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip,
581deda88cbSbeck     size_t iplen)
582deda88cbSbeck {
5832a5239c0Sbeck 	if (iplen != 4 && iplen != 16)
5842a5239c0Sbeck 		goto err;
585b6c35519Stb 	if (x509_param_set1_internal((char **)&param->ip, &param->iplen,
5862a5239c0Sbeck 		(char *)ip, iplen, 0))
5872a5239c0Sbeck 		return 1;
5882a5239c0Sbeck  err:
589b6c35519Stb 	param->poisoned = 1;
590deda88cbSbeck 	return 0;
591deda88cbSbeck }
592cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_ip);
593deda88cbSbeck 
594deda88cbSbeck int
X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM * param,const char * ipasc)595deda88cbSbeck X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc)
596deda88cbSbeck {
597deda88cbSbeck 	unsigned char ipout[16];
598deda88cbSbeck 	size_t iplen;
599deda88cbSbeck 
600deda88cbSbeck 	iplen = (size_t)a2i_ipadd(ipout, ipasc);
601deda88cbSbeck 	return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen);
602deda88cbSbeck }
603cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_ip_asc);
604deda88cbSbeck 
605deda88cbSbeck int
X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM * param)60615238b08Sjsing X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param)
6075650a0e1Sdjm {
6085650a0e1Sdjm 	return param->depth;
6095650a0e1Sdjm }
610cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_depth);
6115650a0e1Sdjm 
612deda88cbSbeck const char *
X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM * param)613deda88cbSbeck X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param)
614deda88cbSbeck {
615deda88cbSbeck 	return param->name;
616deda88cbSbeck }
617cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_get0_name);
618deda88cbSbeck 
619deda88cbSbeck /*
620deda88cbSbeck  * Default verify parameters: these are used for various applications and can
621deda88cbSbeck  * be overridden by the user specified table.
6225650a0e1Sdjm  */
6235650a0e1Sdjm 
6245650a0e1Sdjm static const X509_VERIFY_PARAM default_table[] = {
6255650a0e1Sdjm 	{
626deda88cbSbeck 		.name = "default",
627a37b3debSjsing 		.flags = X509_V_FLAG_TRUSTED_FIRST,
628deda88cbSbeck 		.depth = 100,
629f69362f8Sbeck 		.trust = 0,  /* XXX This is not the default trust value */
6305650a0e1Sdjm 	},
6315650a0e1Sdjm 	{
632deda88cbSbeck 		.name = "pkcs7",
633deda88cbSbeck 		.purpose = X509_PURPOSE_SMIME_SIGN,
634deda88cbSbeck 		.trust = X509_TRUST_EMAIL,
635deda88cbSbeck 		.depth = -1,
636e2ee43e0Sdjm 	},
637e2ee43e0Sdjm 	{
638deda88cbSbeck 		.name = "smime_sign",
639deda88cbSbeck 		.purpose = X509_PURPOSE_SMIME_SIGN,
640deda88cbSbeck 		.trust = X509_TRUST_EMAIL,
641deda88cbSbeck 		.depth =  -1,
6425650a0e1Sdjm 	},
6435650a0e1Sdjm 	{
644deda88cbSbeck 		.name = "ssl_client",
645deda88cbSbeck 		.purpose = X509_PURPOSE_SSL_CLIENT,
646deda88cbSbeck 		.trust = X509_TRUST_SSL_CLIENT,
647deda88cbSbeck 		.depth = -1,
6485650a0e1Sdjm 	},
6495650a0e1Sdjm 	{
650deda88cbSbeck 		.name = "ssl_server",
651deda88cbSbeck 		.purpose = X509_PURPOSE_SSL_SERVER,
652deda88cbSbeck 		.trust = X509_TRUST_SSL_SERVER,
653deda88cbSbeck 		.depth = -1,
6547609e5c6Stedu 	}
6557609e5c6Stedu };
6565650a0e1Sdjm 
6575650a0e1Sdjm static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL;
6585650a0e1Sdjm 
65915238b08Sjsing static int
param_cmp(const X509_VERIFY_PARAM * const * a,const X509_VERIFY_PARAM * const * b)66015238b08Sjsing param_cmp(const X509_VERIFY_PARAM * const *a,
6615650a0e1Sdjm     const X509_VERIFY_PARAM * const *b)
6625650a0e1Sdjm {
6635650a0e1Sdjm 	return strcmp((*a)->name, (*b)->name);
6645650a0e1Sdjm }
6655650a0e1Sdjm 
66615238b08Sjsing int
X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM * param)66715238b08Sjsing X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param)
6685650a0e1Sdjm {
6695650a0e1Sdjm 	X509_VERIFY_PARAM *ptmp;
6707609e5c6Stedu 	if (!param_table) {
6715650a0e1Sdjm 		param_table = sk_X509_VERIFY_PARAM_new(param_cmp);
6725650a0e1Sdjm 		if (!param_table)
6735650a0e1Sdjm 			return 0;
6747609e5c6Stedu 	} else {
675deda88cbSbeck 		size_t idx;
676deda88cbSbeck 
677deda88cbSbeck 		if ((idx = sk_X509_VERIFY_PARAM_find(param_table, param))
678deda88cbSbeck 		    != -1) {
679deda88cbSbeck 			ptmp = sk_X509_VERIFY_PARAM_value(param_table,
680deda88cbSbeck 			    idx);
6815650a0e1Sdjm 			X509_VERIFY_PARAM_free(ptmp);
682deda88cbSbeck 			(void)sk_X509_VERIFY_PARAM_delete(param_table,
683deda88cbSbeck 			    idx);
6845650a0e1Sdjm 		}
6855650a0e1Sdjm 	}
6865650a0e1Sdjm 	if (!sk_X509_VERIFY_PARAM_push(param_table, param))
6875650a0e1Sdjm 		return 0;
6885650a0e1Sdjm 	return 1;
6895650a0e1Sdjm }
690cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_add0_table);
6915650a0e1Sdjm 
692deda88cbSbeck int
X509_VERIFY_PARAM_get_count(void)693deda88cbSbeck X509_VERIFY_PARAM_get_count(void)
6945650a0e1Sdjm {
695deda88cbSbeck 	int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM);
696deda88cbSbeck 	if (param_table)
697deda88cbSbeck 		num += sk_X509_VERIFY_PARAM_num(param_table);
698deda88cbSbeck 	return num;
699deda88cbSbeck }
700cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_count);
701deda88cbSbeck 
70240007492Stb const X509_VERIFY_PARAM *
X509_VERIFY_PARAM_get0(int id)70340007492Stb X509_VERIFY_PARAM_get0(int id)
704deda88cbSbeck {
705deda88cbSbeck 	int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM);
706deda88cbSbeck 	if (id < num)
707deda88cbSbeck 		return default_table + id;
708deda88cbSbeck 	return sk_X509_VERIFY_PARAM_value(param_table, id - num);
709deda88cbSbeck }
710cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_get0);
711deda88cbSbeck 
71240007492Stb const X509_VERIFY_PARAM *
X509_VERIFY_PARAM_lookup(const char * name)71340007492Stb X509_VERIFY_PARAM_lookup(const char *name)
714deda88cbSbeck {
7155650a0e1Sdjm 	X509_VERIFY_PARAM pm;
716deda88cbSbeck 	unsigned int i, limit;
717f1535dc8Sdjm 
7185650a0e1Sdjm 	pm.name = (char *)name;
7197609e5c6Stedu 	if (param_table) {
720deda88cbSbeck 		size_t idx;
721deda88cbSbeck 		if ((idx = sk_X509_VERIFY_PARAM_find(param_table, &pm)) != -1)
7225650a0e1Sdjm 			return sk_X509_VERIFY_PARAM_value(param_table, idx);
7235650a0e1Sdjm 	}
724deda88cbSbeck 
725deda88cbSbeck 	limit = sizeof(default_table) / sizeof(X509_VERIFY_PARAM);
726deda88cbSbeck 	for (i = 0; i < limit; i++) {
727deda88cbSbeck 		if (strcmp(default_table[i].name, name) == 0) {
728deda88cbSbeck 			return &default_table[i];
729deda88cbSbeck 		}
730deda88cbSbeck 	}
731deda88cbSbeck 	return NULL;
7325650a0e1Sdjm }
733cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_lookup);
7345650a0e1Sdjm 
73515238b08Sjsing void
X509_VERIFY_PARAM_table_cleanup(void)73615238b08Sjsing X509_VERIFY_PARAM_table_cleanup(void)
7375650a0e1Sdjm {
7385650a0e1Sdjm 	if (param_table)
7395650a0e1Sdjm 		sk_X509_VERIFY_PARAM_pop_free(param_table,
7405650a0e1Sdjm 		    X509_VERIFY_PARAM_free);
7415650a0e1Sdjm 	param_table = NULL;
7425650a0e1Sdjm }
743cedac418Stb LCRYPTO_ALIAS(X509_VERIFY_PARAM_table_cleanup);
744