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 83 str_free(char *s) 84 { 85 free(s); 86 } 87 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 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 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 * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 548 X509_VERIFY_PARAM_get_hostflags(X509_VERIFY_PARAM *param) 549 { 550 return param->hostflags; 551 } 552 553 void 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 * 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 568 X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email, 569 size_t emaillen) 570 { 571 if (x509_param_set1_internal(¶m->email, ¶m->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 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 **)¶m->ip, ¶m->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 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 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 * 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 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 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 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 * 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 * 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 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