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