1 /* $OpenBSD: x509_vpm.c,v 1.40 2023/05/28 05:25:24 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/lhash.h> 65 #include <openssl/stack.h> 66 #include <openssl/x509.h> 67 #include <openssl/x509v3.h> 68 69 #include "x509_local.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 /* 88 * Post 1.0.1 sk function "deep_copy". For the moment we simply make 89 * these take void * and use them directly without a glorious blob of 90 * obfuscating macros of dubious value in front of them. All this in 91 * preparation for a rototilling of safestack.h (likely inspired by 92 * this). 93 */ 94 static void * 95 sk_deep_copy(void *sk_void, void *copy_func_void, void *free_func_void) 96 { 97 _STACK *sk = sk_void; 98 void *(*copy_func)(void *) = copy_func_void; 99 void (*free_func)(void *) = free_func_void; 100 _STACK *ret = sk_dup(sk); 101 size_t i; 102 103 if (ret == NULL) 104 return NULL; 105 106 for (i = 0; i < ret->num; i++) { 107 if (ret->data[i] == NULL) 108 continue; 109 ret->data[i] = copy_func(ret->data[i]); 110 if (ret->data[i] == NULL) { 111 size_t j; 112 for (j = 0; j < i; j++) { 113 if (ret->data[j] != NULL) 114 free_func(ret->data[j]); 115 } 116 sk_free(ret); 117 return NULL; 118 } 119 } 120 121 return ret; 122 } 123 124 static int 125 x509_param_set_hosts_internal(X509_VERIFY_PARAM *vpm, int mode, 126 const char *name, size_t namelen) 127 { 128 char *copy; 129 130 if (name != NULL && namelen == 0) 131 namelen = strlen(name); 132 /* 133 * Refuse names with embedded NUL bytes. 134 */ 135 if (name && memchr(name, '\0', namelen)) 136 return 0; 137 138 if (mode == SET_HOST && vpm->hosts) { 139 sk_OPENSSL_STRING_pop_free(vpm->hosts, str_free); 140 vpm->hosts = NULL; 141 } 142 if (name == NULL || namelen == 0) 143 return 1; 144 copy = strndup(name, namelen); 145 if (copy == NULL) 146 return 0; 147 148 if (vpm->hosts == NULL && 149 (vpm->hosts = sk_OPENSSL_STRING_new_null()) == NULL) { 150 free(copy); 151 return 0; 152 } 153 154 if (!sk_OPENSSL_STRING_push(vpm->hosts, copy)) { 155 free(copy); 156 if (sk_OPENSSL_STRING_num(vpm->hosts) == 0) { 157 sk_OPENSSL_STRING_free(vpm->hosts); 158 vpm->hosts = NULL; 159 } 160 return 0; 161 } 162 163 return 1; 164 } 165 166 static void 167 x509_verify_param_zero(X509_VERIFY_PARAM *param) 168 { 169 if (!param) 170 return; 171 172 free(param->name); 173 param->name = NULL; 174 param->purpose = 0; 175 param->trust = 0; 176 /*param->inh_flags = X509_VP_FLAG_DEFAULT;*/ 177 param->inh_flags = 0; 178 param->flags = 0; 179 param->depth = -1; 180 sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); 181 param->policies = NULL; 182 sk_OPENSSL_STRING_pop_free(param->hosts, str_free); 183 param->hosts = NULL; 184 free(param->peername); 185 param->peername = NULL; 186 free(param->email); 187 param->email = NULL; 188 param->emaillen = 0; 189 free(param->ip); 190 param->ip = NULL; 191 param->iplen = 0; 192 param->poisoned = 0; 193 } 194 195 X509_VERIFY_PARAM * 196 X509_VERIFY_PARAM_new(void) 197 { 198 X509_VERIFY_PARAM *param; 199 200 param = calloc(1, sizeof(X509_VERIFY_PARAM)); 201 if (param == NULL) 202 return NULL; 203 x509_verify_param_zero(param); 204 return param; 205 } 206 LCRYPTO_ALIAS(X509_VERIFY_PARAM_new); 207 208 void 209 X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param) 210 { 211 if (param == NULL) 212 return; 213 x509_verify_param_zero(param); 214 free(param); 215 } 216 LCRYPTO_ALIAS(X509_VERIFY_PARAM_free); 217 218 /* 219 * This function determines how parameters are "inherited" from one structure 220 * to another. There are several different ways this can happen. 221 * 222 * 1. If a child structure needs to have its values initialized from a parent 223 * they are simply copied across. For example SSL_CTX copied to SSL. 224 * 2. If the structure should take on values only if they are currently unset. 225 * For example the values in an SSL structure will take appropriate value 226 * for SSL servers or clients but only if the application has not set new 227 * ones. 228 * 229 * The "inh_flags" field determines how this function behaves. 230 * 231 * Normally any values which are set in the default are not copied from the 232 * destination and verify flags are ORed together. 233 * 234 * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied 235 * to the destination. Effectively the values in "to" become default values 236 * which will be used only if nothing new is set in "from". 237 * 238 * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether 239 * they are set or not. Flags is still Ored though. 240 * 241 * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead 242 * of ORed. 243 * 244 * If X509_VP_FLAG_LOCKED is set then no values are copied. 245 * 246 * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed 247 * after the next call. 248 */ 249 250 /* Macro to test if a field should be copied from src to dest */ 251 #define test_x509_verify_param_copy(field, def) \ 252 (to_overwrite || \ 253 ((src->field != def) && (to_default || (dest->field == def)))) 254 255 /* Macro to test and copy a field if necessary */ 256 #define x509_verify_param_copy(field, def) \ 257 if (test_x509_verify_param_copy(field, def)) \ 258 dest->field = src->field 259 260 int 261 X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, const X509_VERIFY_PARAM *src) 262 { 263 unsigned long inh_flags; 264 int to_default, to_overwrite; 265 266 if (!src) 267 return 1; 268 inh_flags = dest->inh_flags | src->inh_flags; 269 270 if (inh_flags & X509_VP_FLAG_ONCE) 271 dest->inh_flags = 0; 272 273 if (inh_flags & X509_VP_FLAG_LOCKED) 274 return 1; 275 276 if (inh_flags & X509_VP_FLAG_DEFAULT) 277 to_default = 1; 278 else 279 to_default = 0; 280 281 if (inh_flags & X509_VP_FLAG_OVERWRITE) 282 to_overwrite = 1; 283 else 284 to_overwrite = 0; 285 286 x509_verify_param_copy(purpose, 0); 287 x509_verify_param_copy(trust, 0); 288 x509_verify_param_copy(depth, -1); 289 290 /* If overwrite or check time not set, copy across */ 291 292 if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) { 293 dest->check_time = src->check_time; 294 dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME; 295 /* Don't need to copy flag: that is done below */ 296 } 297 298 if (inh_flags & X509_VP_FLAG_RESET_FLAGS) 299 dest->flags = 0; 300 301 dest->flags |= src->flags; 302 303 if (test_x509_verify_param_copy(policies, NULL)) { 304 if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies)) 305 return 0; 306 } 307 308 x509_verify_param_copy(hostflags, 0); 309 310 if (test_x509_verify_param_copy(hosts, NULL)) { 311 if (dest->hosts) { 312 sk_OPENSSL_STRING_pop_free(dest->hosts, str_free); 313 dest->hosts = NULL; 314 } 315 if (src->hosts) { 316 dest->hosts = sk_deep_copy(src->hosts, strdup, str_free); 317 if (dest->hosts == NULL) 318 return 0; 319 } 320 } 321 322 if (test_x509_verify_param_copy(email, NULL)) { 323 if (!X509_VERIFY_PARAM_set1_email(dest, src->email, 324 src->emaillen)) 325 return 0; 326 } 327 328 if (test_x509_verify_param_copy(ip, NULL)) { 329 if (!X509_VERIFY_PARAM_set1_ip(dest, src->ip, src->iplen)) 330 return 0; 331 } 332 333 return 1; 334 } 335 LCRYPTO_ALIAS(X509_VERIFY_PARAM_inherit); 336 337 int 338 X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, const X509_VERIFY_PARAM *from) 339 { 340 unsigned long save_flags = to->inh_flags; 341 int ret; 342 343 to->inh_flags |= X509_VP_FLAG_DEFAULT; 344 ret = X509_VERIFY_PARAM_inherit(to, from); 345 to->inh_flags = save_flags; 346 return ret; 347 } 348 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1); 349 350 static int 351 x509_param_set1_internal(char **pdest, size_t *pdestlen, const char *src, 352 size_t srclen, int nonul) 353 { 354 char *tmp; 355 356 if (src == NULL) 357 return 0; 358 359 if (srclen == 0) { 360 srclen = strlen(src); 361 if (srclen == 0) 362 return 0; 363 if ((tmp = strdup(src)) == NULL) 364 return 0; 365 } else { 366 if (nonul && memchr(src, '\0', srclen)) 367 return 0; 368 if ((tmp = malloc(srclen)) == NULL) 369 return 0; 370 memcpy(tmp, src, srclen); 371 } 372 373 if (*pdest) 374 free(*pdest); 375 *pdest = tmp; 376 if (pdestlen) 377 *pdestlen = srclen; 378 return 1; 379 } 380 381 int 382 X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name) 383 { 384 free(param->name); 385 param->name = NULL; 386 if (name == NULL) 387 return 1; 388 param->name = strdup(name); 389 if (param->name) 390 return 1; 391 return 0; 392 } 393 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_name); 394 395 int 396 X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags) 397 { 398 param->flags |= flags; 399 return 1; 400 } 401 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_flags); 402 403 int 404 X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, unsigned long flags) 405 { 406 param->flags &= ~flags; 407 return 1; 408 } 409 LCRYPTO_ALIAS(X509_VERIFY_PARAM_clear_flags); 410 411 unsigned long 412 X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param) 413 { 414 return param->flags; 415 } 416 LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_flags); 417 418 int 419 X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose) 420 { 421 return X509_PURPOSE_set(¶m->purpose, purpose); 422 } 423 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_purpose); 424 425 int 426 X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust) 427 { 428 return X509_TRUST_set(¶m->trust, trust); 429 } 430 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_trust); 431 432 void 433 X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth) 434 { 435 param->depth = depth; 436 } 437 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_depth); 438 439 void 440 X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM *param, int auth_level) 441 { 442 param->security_level = auth_level; 443 } 444 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_auth_level); 445 446 time_t 447 X509_VERIFY_PARAM_get_time(const X509_VERIFY_PARAM *param) 448 { 449 return param->check_time; 450 } 451 LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_time); 452 453 void 454 X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t) 455 { 456 param->check_time = t; 457 param->flags |= X509_V_FLAG_USE_CHECK_TIME; 458 } 459 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_time); 460 461 int 462 X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, ASN1_OBJECT *policy) 463 { 464 if (!param->policies) { 465 param->policies = sk_ASN1_OBJECT_new_null(); 466 if (!param->policies) 467 return 0; 468 } 469 if (!sk_ASN1_OBJECT_push(param->policies, policy)) 470 return 0; 471 return 1; 472 } 473 LCRYPTO_ALIAS(X509_VERIFY_PARAM_add0_policy); 474 475 int 476 X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, 477 STACK_OF(ASN1_OBJECT) *policies) 478 { 479 int i; 480 ASN1_OBJECT *oid, *doid; 481 482 if (!param) 483 return 0; 484 if (param->policies) 485 sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); 486 487 if (!policies) { 488 param->policies = NULL; 489 return 1; 490 } 491 492 param->policies = sk_ASN1_OBJECT_new_null(); 493 if (!param->policies) 494 return 0; 495 496 for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++) { 497 oid = sk_ASN1_OBJECT_value(policies, i); 498 doid = OBJ_dup(oid); 499 if (!doid) 500 return 0; 501 if (!sk_ASN1_OBJECT_push(param->policies, doid)) { 502 ASN1_OBJECT_free(doid); 503 return 0; 504 } 505 } 506 return 1; 507 } 508 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_policies); 509 510 int 511 X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, 512 const char *name, size_t namelen) 513 { 514 if (x509_param_set_hosts_internal(param, SET_HOST, name, namelen)) 515 return 1; 516 param->poisoned = 1; 517 return 0; 518 } 519 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_host); 520 521 int 522 X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, 523 const char *name, size_t namelen) 524 { 525 if (x509_param_set_hosts_internal(param, ADD_HOST, name, namelen)) 526 return 1; 527 param->poisoned = 1; 528 return 0; 529 } 530 LCRYPTO_ALIAS(X509_VERIFY_PARAM_add1_host); 531 532 /* Public API in OpenSSL - nothing seems to use this. */ 533 unsigned int 534 X509_VERIFY_PARAM_get_hostflags(X509_VERIFY_PARAM *param) 535 { 536 return param->hostflags; 537 } 538 539 void 540 X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, unsigned int flags) 541 { 542 param->hostflags = flags; 543 } 544 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_hostflags); 545 546 char * 547 X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param) 548 { 549 return param->peername; 550 } 551 LCRYPTO_ALIAS(X509_VERIFY_PARAM_get0_peername); 552 553 int 554 X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email, 555 size_t emaillen) 556 { 557 if (x509_param_set1_internal(¶m->email, ¶m->emaillen, 558 email, emaillen, 1)) 559 return 1; 560 param->poisoned = 1; 561 return 0; 562 } 563 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_email); 564 565 int 566 X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip, 567 size_t iplen) 568 { 569 if (iplen != 4 && iplen != 16) 570 goto err; 571 if (x509_param_set1_internal((char **)¶m->ip, ¶m->iplen, 572 (char *)ip, iplen, 0)) 573 return 1; 574 err: 575 param->poisoned = 1; 576 return 0; 577 } 578 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_ip); 579 580 int 581 X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc) 582 { 583 unsigned char ipout[16]; 584 size_t iplen; 585 586 iplen = (size_t)a2i_ipadd(ipout, ipasc); 587 return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen); 588 } 589 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_ip_asc); 590 591 int 592 X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param) 593 { 594 return param->depth; 595 } 596 LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_depth); 597 598 const char * 599 X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param) 600 { 601 return param->name; 602 } 603 LCRYPTO_ALIAS(X509_VERIFY_PARAM_get0_name); 604 605 /* 606 * Default verify parameters: these are used for various applications and can 607 * be overridden by the user specified table. 608 */ 609 610 static const X509_VERIFY_PARAM default_table[] = { 611 { 612 .name = "default", 613 .flags = X509_V_FLAG_TRUSTED_FIRST, 614 .depth = 100, 615 .trust = 0, /* XXX This is not the default trust value */ 616 }, 617 { 618 .name = "pkcs7", 619 .purpose = X509_PURPOSE_SMIME_SIGN, 620 .trust = X509_TRUST_EMAIL, 621 .depth = -1, 622 }, 623 { 624 .name = "smime_sign", 625 .purpose = X509_PURPOSE_SMIME_SIGN, 626 .trust = X509_TRUST_EMAIL, 627 .depth = -1, 628 }, 629 { 630 .name = "ssl_client", 631 .purpose = X509_PURPOSE_SSL_CLIENT, 632 .trust = X509_TRUST_SSL_CLIENT, 633 .depth = -1, 634 }, 635 { 636 .name = "ssl_server", 637 .purpose = X509_PURPOSE_SSL_SERVER, 638 .trust = X509_TRUST_SSL_SERVER, 639 .depth = -1, 640 } 641 }; 642 643 static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL; 644 645 static int 646 param_cmp(const X509_VERIFY_PARAM * const *a, 647 const X509_VERIFY_PARAM * const *b) 648 { 649 return strcmp((*a)->name, (*b)->name); 650 } 651 652 int 653 X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param) 654 { 655 X509_VERIFY_PARAM *ptmp; 656 if (!param_table) { 657 param_table = sk_X509_VERIFY_PARAM_new(param_cmp); 658 if (!param_table) 659 return 0; 660 } else { 661 size_t idx; 662 663 if ((idx = sk_X509_VERIFY_PARAM_find(param_table, param)) 664 != -1) { 665 ptmp = sk_X509_VERIFY_PARAM_value(param_table, 666 idx); 667 X509_VERIFY_PARAM_free(ptmp); 668 (void)sk_X509_VERIFY_PARAM_delete(param_table, 669 idx); 670 } 671 } 672 if (!sk_X509_VERIFY_PARAM_push(param_table, param)) 673 return 0; 674 return 1; 675 } 676 LCRYPTO_ALIAS(X509_VERIFY_PARAM_add0_table); 677 678 int 679 X509_VERIFY_PARAM_get_count(void) 680 { 681 int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM); 682 if (param_table) 683 num += sk_X509_VERIFY_PARAM_num(param_table); 684 return num; 685 } 686 LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_count); 687 688 const X509_VERIFY_PARAM * 689 X509_VERIFY_PARAM_get0(int id) 690 { 691 int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM); 692 if (id < num) 693 return default_table + id; 694 return sk_X509_VERIFY_PARAM_value(param_table, id - num); 695 } 696 LCRYPTO_ALIAS(X509_VERIFY_PARAM_get0); 697 698 const X509_VERIFY_PARAM * 699 X509_VERIFY_PARAM_lookup(const char *name) 700 { 701 X509_VERIFY_PARAM pm; 702 unsigned int i, limit; 703 704 pm.name = (char *)name; 705 if (param_table) { 706 size_t idx; 707 if ((idx = sk_X509_VERIFY_PARAM_find(param_table, &pm)) != -1) 708 return sk_X509_VERIFY_PARAM_value(param_table, idx); 709 } 710 711 limit = sizeof(default_table) / sizeof(X509_VERIFY_PARAM); 712 for (i = 0; i < limit; i++) { 713 if (strcmp(default_table[i].name, name) == 0) { 714 return &default_table[i]; 715 } 716 } 717 return NULL; 718 } 719 LCRYPTO_ALIAS(X509_VERIFY_PARAM_lookup); 720 721 void 722 X509_VERIFY_PARAM_table_cleanup(void) 723 { 724 if (param_table) 725 sk_X509_VERIFY_PARAM_pop_free(param_table, 726 X509_VERIFY_PARAM_free); 727 param_table = NULL; 728 } 729 LCRYPTO_ALIAS(X509_VERIFY_PARAM_table_cleanup); 730