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