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