GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/x509/x509_vpm.c Lines: 73 236 30.9 %
Date: 2017-11-13 Branches: 45 194 23.2 %

Line Branch Exec Source
1
/* $OpenBSD: x509_vpm.c,v 1.15 2016/12/21 15:15:45 jsing 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/lhash.h>
65
#include <openssl/stack.h>
66
#include <openssl/x509.h>
67
#include <openssl/x509v3.h>
68
69
#include "vpm_int.h"
70
71
/* X509_VERIFY_PARAM functions */
72
73
int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email,
74
    size_t emaillen);
75
int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip,
76
    size_t iplen);
77
78
#define SET_HOST 0
79
#define ADD_HOST 1
80
81
static void
82
str_free(char *s)
83
{
84
    free(s);
85
}
86
87
#define string_stack_free(sk) sk_OPENSSL_STRING_pop_free(sk, str_free)
88
89
90
/*
91
 * Post 1.0.1 sk function "deep_copy".  For the moment we simply make
92
 * these take void * and use them directly without a glorious blob of
93
 * obfuscating macros of dubious value in front of them. All this in
94
 * preparation for a rototilling of safestack.h (likely inspired by
95
 * this).
96
 */
97
static void *
98
sk_deep_copy(void *sk_void, void *copy_func_void, void *free_func_void)
99
{
100
	_STACK *sk = sk_void;
101
	void *(*copy_func)(void *) = copy_func_void;
102
	void (*free_func)(void *) = free_func_void;
103
	_STACK *ret = sk_dup(sk);
104
105
	if (ret == NULL)
106
		return NULL;
107
108
	size_t i;
109
	for (i = 0; i < ret->num; i++) {
110
		if (ret->data[i] == NULL)
111
			continue;
112
		ret->data[i] = copy_func(ret->data[i]);
113
		if (ret->data[i] == NULL) {
114
			size_t j;
115
			for (j = 0; j < i; j++) {
116
				if (ret->data[j] != NULL)
117
					free_func(ret->data[j]);
118
			}
119
			sk_free(ret);
120
			return NULL;
121
		}
122
	}
123
124
	return ret;
125
}
126
127
static int
128
int_x509_param_set_hosts(X509_VERIFY_PARAM_ID *id, int mode,
129
    const char *name, size_t namelen)
130
{
131
	char *copy;
132
133
	/*
134
	 * Refuse names with embedded NUL bytes.
135
	 * XXX: Do we need to push an error onto the error stack?
136
	 */
137
	if (name && memchr(name, '\0', namelen))
138
		return 0;
139
140
	if (mode == SET_HOST && id->hosts) {
141
		string_stack_free(id->hosts);
142
		id->hosts = NULL;
143
	}
144
	if (name == NULL || namelen == 0)
145
		return 1;
146
	copy = strndup(name, namelen);
147
	if (copy == NULL)
148
		return 0;
149
150
	if (id->hosts == NULL &&
151
	    (id->hosts = sk_OPENSSL_STRING_new_null()) == NULL) {
152
		free(copy);
153
		return 0;
154
	}
155
156
	if (!sk_OPENSSL_STRING_push(id->hosts, copy)) {
157
		free(copy);
158
		if (sk_OPENSSL_STRING_num(id->hosts) == 0) {
159
			sk_OPENSSL_STRING_free(id->hosts);
160
			id->hosts = NULL;
161
		}
162
		return 0;
163
	}
164
165
	return 1;
166
}
167
168
static void
169
x509_verify_param_zero(X509_VERIFY_PARAM *param)
170
{
171
	X509_VERIFY_PARAM_ID *paramid;
172
18988
	if (!param)
173
		return;
174
9494
	param->name = NULL;
175
9494
	param->purpose = 0;
176
9494
	param->trust = 0;
177
	/*param->inh_flags = X509_VP_FLAG_DEFAULT;*/
178
9494
	param->inh_flags = 0;
179
9494
	param->flags = 0;
180
9494
	param->depth = -1;
181
9494
	if (param->policies) {
182
		sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
183
		param->policies = NULL;
184
	}
185
9494
	paramid = param->id;
186
9494
	if (paramid->hosts) {
187
		string_stack_free(paramid->hosts);
188
		paramid->hosts = NULL;
189
	}
190
9494
	free(paramid->peername);
191
9494
	paramid->peername = NULL;
192
9494
	free(paramid->email);
193
9494
	paramid->email = NULL;
194
9494
	paramid->emaillen = 0;
195
9494
	free(paramid->ip);
196
9494
	paramid->ip = NULL;
197
9494
	paramid->iplen = 0;
198
18988
}
199
200
X509_VERIFY_PARAM *
201
X509_VERIFY_PARAM_new(void)
202
{
203
	X509_VERIFY_PARAM *param;
204
	X509_VERIFY_PARAM_ID *paramid;
205
9560
	param = calloc(1, sizeof(X509_VERIFY_PARAM));
206
4780
	if (param == NULL)
207
		return NULL;
208
4780
	paramid = calloc (1, sizeof(X509_VERIFY_PARAM_ID));
209
4780
	if (paramid == NULL) {
210
		free(param);
211
		return NULL;
212
	}
213
4780
	param->id = paramid;
214
4780
	x509_verify_param_zero(param);
215
4780
	return param;
216
4780
}
217
218
void
219
X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param)
220
{
221
9428
	if (param == NULL)
222
		return;
223
4714
	x509_verify_param_zero(param);
224
4714
	free(param->id);
225
4714
	free(param);
226
9428
}
227
228
/* This function determines how parameters are "inherited" from one structure
229
 * to another. There are several different ways this can happen.
230
 *
231
 * 1. If a child structure needs to have its values initialized from a parent
232
 *    they are simply copied across. For example SSL_CTX copied to SSL.
233
 * 2. If the structure should take on values only if they are currently unset.
234
 *    For example the values in an SSL structure will take appropriate value
235
 *    for SSL servers or clients but only if the application has not set new
236
 *    ones.
237
 *
238
 * The "inh_flags" field determines how this function behaves.
239
 *
240
 * Normally any values which are set in the default are not copied from the
241
 * destination and verify flags are ORed together.
242
 *
243
 * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied
244
 * to the destination. Effectively the values in "to" become default values
245
 * which will be used only if nothing new is set in "from".
246
 *
247
 * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether
248
 * they are set or not. Flags is still Ored though.
249
 *
250
 * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead
251
 * of ORed.
252
 *
253
 * If X509_VP_FLAG_LOCKED is set then no values are copied.
254
 *
255
 * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed
256
 * after the next call.
257
 */
258
259
/* Macro to test if a field should be copied from src to dest */
260
261
#define test_x509_verify_param_copy(field, def) \
262
	(to_overwrite || \
263
		((src->field != def) && (to_default || (dest->field == def))))
264
265
/* As above but for ID fields */
266
267
#define test_x509_verify_param_copy_id(idf, def) \
268
	test_x509_verify_param_copy(id->idf, def)
269
270
/* Macro to test and copy a field if necessary */
271
272
#define x509_verify_param_copy(field, def) \
273
	if (test_x509_verify_param_copy(field, def)) \
274
		dest->field = src->field
275
276
int
277
X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, const X509_VERIFY_PARAM *src)
278
{
279
	unsigned long inh_flags;
280
	int to_default, to_overwrite;
281
	X509_VERIFY_PARAM_ID *id;
282
283
14616
	if (!src)
284
		return 1;
285
7308
	id = src->id;
286
7308
	inh_flags = dest->inh_flags | src->inh_flags;
287
288
7308
	if (inh_flags & X509_VP_FLAG_ONCE)
289
		dest->inh_flags = 0;
290
291
7308
	if (inh_flags & X509_VP_FLAG_LOCKED)
292
		return 1;
293
294
7308
	if (inh_flags & X509_VP_FLAG_DEFAULT)
295
1293
		to_default = 1;
296
	else
297
		to_default = 0;
298
299
7308
	if (inh_flags & X509_VP_FLAG_OVERWRITE)
300
		to_overwrite = 1;
301
	else
302
		to_overwrite = 0;
303
304


18513
	x509_verify_param_copy(purpose, 0);
305


18513
	x509_verify_param_copy(trust, 0);
306


19176
	x509_verify_param_copy(depth, -1);
307
308
	/* If overwrite or check time not set, copy across */
309
310

14616
	if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) {
311
7308
		dest->check_time = src->check_time;
312
7308
		dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME;
313
		/* Don't need to copy flag: that is done below */
314
7308
	}
315
316
7308
	if (inh_flags & X509_VP_FLAG_RESET_FLAGS)
317
		dest->flags = 0;
318
319
7308
	dest->flags |= src->flags;
320
321


14616
	if (test_x509_verify_param_copy(policies, NULL)) {
322
		if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies))
323
			return 0;
324
	}
325
326
	/* Copy the host flags if and only if we're copying the host list */
327


14616
	if (test_x509_verify_param_copy_id(hosts, NULL)) {
328
		if (dest->id->hosts) {
329
			string_stack_free(dest->id->hosts);
330
			dest->id->hosts = NULL;
331
		}
332
		if (id->hosts) {
333
			dest->id->hosts =
334
			    sk_deep_copy(id->hosts, strdup, str_free);
335
			if (dest->id->hosts == NULL)
336
				return 0;
337
			dest->id->hostflags = id->hostflags;
338
		}
339
	}
340
341


14616
	if (test_x509_verify_param_copy_id(email, NULL)) {
342
		if (!X509_VERIFY_PARAM_set1_email(dest, id->email,
343
		    id->emaillen))
344
			return 0;
345
	}
346
347


14616
	if (test_x509_verify_param_copy_id(ip, NULL)) {
348
		if (!X509_VERIFY_PARAM_set1_ip(dest, id->ip, id->iplen))
349
			return 0;
350
	}
351
352
7308
	return 1;
353
7308
}
354
355
int
356
X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, const X509_VERIFY_PARAM *from)
357
{
358
2586
	unsigned long save_flags = to->inh_flags;
359
	int ret;
360
361
1293
	to->inh_flags |= X509_VP_FLAG_DEFAULT;
362
1293
	ret = X509_VERIFY_PARAM_inherit(to, from);
363
1293
	to->inh_flags = save_flags;
364
1293
	return ret;
365
}
366
367
static int
368
int_x509_param_set1(char **pdest, size_t *pdestlen,  const char *src,
369
    size_t srclen)
370
{
371
	char *tmp;
372
	if (src) {
373
		if (srclen == 0) {
374
			if ((tmp = strdup(src)) == NULL)
375
				return 0;
376
			srclen = strlen(src);
377
		} else {
378
			if ((tmp = malloc(srclen)) == NULL)
379
				return 0;
380
			memcpy(tmp, src, srclen);
381
		}
382
	} else {
383
		tmp = NULL;
384
		srclen = 0;
385
	}
386
	if (*pdest)
387
		free(*pdest);
388
	*pdest = tmp;
389
	if (pdestlen)
390
		*pdestlen = srclen;
391
	return 1;
392
}
393
394
int
395
X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name)
396
{
397
	free(param->name);
398
	param->name = NULL;
399
	if (name == NULL)
400
		return 1;
401
	param->name = strdup(name);
402
	if (param->name)
403
		return 1;
404
	return 0;
405
}
406
407
int
408
X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags)
409
{
410
224
	param->flags |= flags;
411
112
	if (flags & X509_V_FLAG_POLICY_MASK)
412
2
		param->flags |= X509_V_FLAG_POLICY_CHECK;
413
112
	return 1;
414
}
415
416
int
417
X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, unsigned long flags)
418
{
419
	param->flags &= ~flags;
420
	return 1;
421
}
422
423
unsigned long
424
X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param)
425
{
426
	return param->flags;
427
}
428
429
int
430
X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose)
431
{
432
	return X509_PURPOSE_set(&param->purpose, purpose);
433
}
434
435
int
436
X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust)
437
{
438
	return X509_TRUST_set(&param->trust, trust);
439
}
440
441
void
442
X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth)
443
{
444
24
	param->depth = depth;
445
12
}
446
447
void
448
X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t)
449
{
450
	param->check_time = t;
451
	param->flags |= X509_V_FLAG_USE_CHECK_TIME;
452
}
453
454
int
455
X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, ASN1_OBJECT *policy)
456
{
457
	if (!param->policies) {
458
		param->policies = sk_ASN1_OBJECT_new_null();
459
		if (!param->policies)
460
			return 0;
461
	}
462
	if (!sk_ASN1_OBJECT_push(param->policies, policy))
463
		return 0;
464
	return 1;
465
}
466
467
int
468
X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
469
    STACK_OF(ASN1_OBJECT) *policies)
470
{
471
	int i;
472
	ASN1_OBJECT *oid, *doid;
473
474
	if (!param)
475
		return 0;
476
	if (param->policies)
477
		sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
478
479
	if (!policies) {
480
		param->policies = NULL;
481
		return 1;
482
	}
483
484
	param->policies = sk_ASN1_OBJECT_new_null();
485
	if (!param->policies)
486
		return 0;
487
488
	for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++) {
489
		oid = sk_ASN1_OBJECT_value(policies, i);
490
		doid = OBJ_dup(oid);
491
		if (!doid)
492
			return 0;
493
		if (!sk_ASN1_OBJECT_push(param->policies, doid)) {
494
			ASN1_OBJECT_free(doid);
495
			return 0;
496
		}
497
	}
498
	param->flags |= X509_V_FLAG_POLICY_CHECK;
499
	return 1;
500
}
501
502
int
503
X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
504
    const char *name, size_t namelen)
505
{
506
	return int_x509_param_set_hosts(param->id, SET_HOST, name, namelen);
507
}
508
509
int
510
X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
511
    const char *name, size_t namelen)
512
{
513
	return int_x509_param_set_hosts(param->id, ADD_HOST, name, namelen);
514
}
515
516
void
517
X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, unsigned int flags)
518
{
519
	param->id->hostflags = flags;
520
}
521
522
char *
523
X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param)
524
{
525
	return param->id->peername;
526
}
527
528
int
529
X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,  const char *email,
530
    size_t emaillen)
531
{
532
	return int_x509_param_set1(&param->id->email, &param->id->emaillen,
533
	    email, emaillen);
534
}
535
536
int
537
X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip,
538
    size_t iplen)
539
{
540
	if (iplen != 0 && iplen != 4 && iplen != 16)
541
		return 0;
542
	return int_x509_param_set1((char **)&param->id->ip, &param->id->iplen,
543
	    (char *)ip, iplen);
544
}
545
546
int
547
X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc)
548
{
549
	unsigned char ipout[16];
550
	size_t iplen;
551
552
	iplen = (size_t)a2i_ipadd(ipout, ipasc);
553
	if (iplen == 0)
554
		return 0;
555
	return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen);
556
}
557
558
int
559
X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param)
560
{
561
	return param->depth;
562
}
563
564
const char *
565
X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param)
566
{
567
	return param->name;
568
}
569
570
static const X509_VERIFY_PARAM_ID _empty_id = { NULL };
571
572
#define vpm_empty_id (X509_VERIFY_PARAM_ID *)&_empty_id
573
574
/*
575
 * Default verify parameters: these are used for various applications and can
576
 * be overridden by the user specified table.
577
 */
578
579
static const X509_VERIFY_PARAM default_table[] = {
580
	{
581
		.name = "default",
582
		.depth = 100,
583
		.trust = 0,  /* XXX This is not the default trust value */
584
		.id = vpm_empty_id
585
	},
586
	{
587
		.name = "pkcs7",
588
		.purpose = X509_PURPOSE_SMIME_SIGN,
589
		.trust = X509_TRUST_EMAIL,
590
		.depth = -1,
591
		.id = vpm_empty_id
592
	},
593
	{
594
		.name = "smime_sign",
595
		.purpose = X509_PURPOSE_SMIME_SIGN,
596
		.trust = X509_TRUST_EMAIL,
597
		.depth =  -1,
598
		.id = vpm_empty_id
599
	},
600
	{
601
		.name = "ssl_client",
602
		.purpose = X509_PURPOSE_SSL_CLIENT,
603
		.trust = X509_TRUST_SSL_CLIENT,
604
		.depth = -1,
605
		.id = vpm_empty_id
606
	},
607
	{
608
		.name = "ssl_server",
609
		.purpose = X509_PURPOSE_SSL_SERVER,
610
		.trust = X509_TRUST_SSL_SERVER,
611
		.depth = -1,
612
		.id = vpm_empty_id
613
	}
614
};
615
616
static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL;
617
618
static int
619
param_cmp(const X509_VERIFY_PARAM * const *a,
620
    const X509_VERIFY_PARAM * const *b)
621
{
622
	return strcmp((*a)->name, (*b)->name);
623
}
624
625
int
626
X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param)
627
{
628
	X509_VERIFY_PARAM *ptmp;
629
	if (!param_table) {
630
		param_table = sk_X509_VERIFY_PARAM_new(param_cmp);
631
		if (!param_table)
632
			return 0;
633
	} else {
634
		size_t idx;
635
636
		if ((idx = sk_X509_VERIFY_PARAM_find(param_table, param))
637
		    != -1) {
638
			ptmp = sk_X509_VERIFY_PARAM_value(param_table,
639
			    idx);
640
			X509_VERIFY_PARAM_free(ptmp);
641
			(void)sk_X509_VERIFY_PARAM_delete(param_table,
642
			    idx);
643
		}
644
	}
645
	if (!sk_X509_VERIFY_PARAM_push(param_table, param))
646
		return 0;
647
	return 1;
648
}
649
650
int
651
X509_VERIFY_PARAM_get_count(void)
652
{
653
	int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM);
654
	if (param_table)
655
		num += sk_X509_VERIFY_PARAM_num(param_table);
656
	return num;
657
}
658
659
const
660
X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id)
661
{
662
	int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM);
663
	if (id < num)
664
		return default_table + id;
665
	return sk_X509_VERIFY_PARAM_value(param_table, id - num);
666
}
667
668
const
669
X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name)
670
{
671
5598
	X509_VERIFY_PARAM pm;
672
	unsigned int i, limit;
673
674
2799
	pm.name = (char *)name;
675
2799
	if (param_table) {
676
		size_t idx;
677
		if ((idx = sk_X509_VERIFY_PARAM_find(param_table, &pm)) != -1)
678
			return sk_X509_VERIFY_PARAM_value(param_table, idx);
679
	}
680
681
	limit = sizeof(default_table) / sizeof(X509_VERIFY_PARAM);
682
15916
	for (i = 0; i < limit; i++) {
683
7958
		if (strcmp(default_table[i].name, name) == 0) {
684
2799
			return &default_table[i];
685
		}
686
	}
687
	return NULL;
688
2799
}
689
690
void
691
X509_VERIFY_PARAM_table_cleanup(void)
692
{
693
	if (param_table)
694
		sk_X509_VERIFY_PARAM_pop_free(param_table,
695
		    X509_VERIFY_PARAM_free);
696
	param_table = NULL;
697
}