1 /* crypto/x509/x509_lu.c */ 2 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay (at) cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh (at) cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay (at) cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "This product includes software written by Tim Hudson (tjh (at) cryptsoft.com)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] */ 57 58 #include <string.h> 59 60 #include <openssl/err.h> 61 #include <openssl/lhash.h> 62 #include <openssl/mem.h> 63 #include <openssl/thread.h> 64 #include <openssl/x509.h> 65 #include <openssl/x509v3.h> 66 67 #include "../internal.h" 68 69 X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method) 70 { 71 X509_LOOKUP *ret; 72 73 ret = (X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP)); 74 if (ret == NULL) 75 return NULL; 76 77 ret->init = 0; 78 ret->skip = 0; 79 ret->method = method; 80 ret->method_data = NULL; 81 ret->store_ctx = NULL; 82 if ((method->new_item != NULL) && !method->new_item(ret)) { 83 OPENSSL_free(ret); 84 return NULL; 85 } 86 return ret; 87 } 88 89 void X509_LOOKUP_free(X509_LOOKUP *ctx) 90 { 91 if (ctx == NULL) 92 return; 93 if ((ctx->method != NULL) && (ctx->method->free != NULL)) 94 (*ctx->method->free) (ctx); 95 OPENSSL_free(ctx); 96 } 97 98 int X509_LOOKUP_init(X509_LOOKUP *ctx) 99 { 100 if (ctx->method == NULL) 101 return 0; 102 if (ctx->method->init != NULL) 103 return ctx->method->init(ctx); 104 else 105 return 1; 106 } 107 108 int X509_LOOKUP_shutdown(X509_LOOKUP *ctx) 109 { 110 if (ctx->method == NULL) 111 return 0; 112 if (ctx->method->shutdown != NULL) 113 return ctx->method->shutdown(ctx); 114 else 115 return 1; 116 } 117 118 int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, 119 char **ret) 120 { 121 if (ctx->method == NULL) 122 return -1; 123 if (ctx->method->ctrl != NULL) 124 return ctx->method->ctrl(ctx, cmd, argc, argl, ret); 125 else 126 return 1; 127 } 128 129 int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, 130 X509_OBJECT *ret) 131 { 132 if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL)) 133 return 0; 134 if (ctx->skip) 135 return 0; 136 return ctx->method->get_by_subject(ctx, type, name, ret) > 0; 137 } 138 139 int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name, 140 ASN1_INTEGER *serial, X509_OBJECT *ret) 141 { 142 if ((ctx->method == NULL) || (ctx->method->get_by_issuer_serial == NULL)) 143 return 0; 144 return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret) > 0; 145 } 146 147 int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, 148 unsigned char *bytes, int len, 149 X509_OBJECT *ret) 150 { 151 if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL)) 152 return 0; 153 return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret) > 0; 154 } 155 156 int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len, 157 X509_OBJECT *ret) 158 { 159 if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL)) 160 return 0; 161 return ctx->method->get_by_alias(ctx, type, str, len, ret) > 0; 162 } 163 164 static int x509_object_cmp(const X509_OBJECT **a, const X509_OBJECT **b) 165 { 166 int ret; 167 168 ret = ((*a)->type - (*b)->type); 169 if (ret) 170 return ret; 171 switch ((*a)->type) { 172 case X509_LU_X509: 173 ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509); 174 break; 175 case X509_LU_CRL: 176 ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl); 177 break; 178 default: 179 /* abort(); */ 180 return 0; 181 } 182 return ret; 183 } 184 185 X509_STORE *X509_STORE_new(void) 186 { 187 X509_STORE *ret; 188 189 if ((ret = (X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL) 190 return NULL; 191 OPENSSL_memset(ret, 0, sizeof(*ret)); 192 CRYPTO_MUTEX_init(&ret->objs_lock); 193 ret->objs = sk_X509_OBJECT_new(x509_object_cmp); 194 if (ret->objs == NULL) 195 goto err; 196 ret->cache = 1; 197 ret->get_cert_methods = sk_X509_LOOKUP_new_null(); 198 if (ret->get_cert_methods == NULL) 199 goto err; 200 ret->param = X509_VERIFY_PARAM_new(); 201 if (ret->param == NULL) 202 goto err; 203 204 ret->references = 1; 205 return ret; 206 err: 207 if (ret) { 208 CRYPTO_MUTEX_cleanup(&ret->objs_lock); 209 if (ret->param) 210 X509_VERIFY_PARAM_free(ret->param); 211 if (ret->get_cert_methods) 212 sk_X509_LOOKUP_free(ret->get_cert_methods); 213 if (ret->objs) 214 sk_X509_OBJECT_free(ret->objs); 215 OPENSSL_free(ret); 216 } 217 return NULL; 218 } 219 220 int X509_STORE_up_ref(X509_STORE *store) 221 { 222 CRYPTO_refcount_inc(&store->references); 223 return 1; 224 } 225 226 static void cleanup(X509_OBJECT *a) 227 { 228 if (a == NULL) { 229 return; 230 } 231 if (a->type == X509_LU_X509) { 232 X509_free(a->data.x509); 233 } else if (a->type == X509_LU_CRL) { 234 X509_CRL_free(a->data.crl); 235 } else { 236 /* abort(); */ 237 } 238 239 OPENSSL_free(a); 240 } 241 242 void X509_STORE_free(X509_STORE *vfy) 243 { 244 size_t j; 245 STACK_OF(X509_LOOKUP) *sk; 246 X509_LOOKUP *lu; 247 248 if (vfy == NULL) 249 return; 250 251 if (!CRYPTO_refcount_dec_and_test_zero(&vfy->references)) { 252 return; 253 } 254 255 CRYPTO_MUTEX_cleanup(&vfy->objs_lock); 256 257 sk = vfy->get_cert_methods; 258 for (j = 0; j < sk_X509_LOOKUP_num(sk); j++) { 259 lu = sk_X509_LOOKUP_value(sk, j); 260 X509_LOOKUP_shutdown(lu); 261 X509_LOOKUP_free(lu); 262 } 263 sk_X509_LOOKUP_free(sk); 264 sk_X509_OBJECT_pop_free(vfy->objs, cleanup); 265 266 if (vfy->param) 267 X509_VERIFY_PARAM_free(vfy->param); 268 OPENSSL_free(vfy); 269 } 270 271 X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m) 272 { 273 size_t i; 274 STACK_OF(X509_LOOKUP) *sk; 275 X509_LOOKUP *lu; 276 277 sk = v->get_cert_methods; 278 for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) { 279 lu = sk_X509_LOOKUP_value(sk, i); 280 if (m == lu->method) { 281 return lu; 282 } 283 } 284 /* a new one */ 285 lu = X509_LOOKUP_new(m); 286 if (lu == NULL) 287 return NULL; 288 else { 289 lu->store_ctx = v; 290 if (sk_X509_LOOKUP_push(v->get_cert_methods, lu)) 291 return lu; 292 else { 293 X509_LOOKUP_free(lu); 294 return NULL; 295 } 296 } 297 } 298 299 int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name, 300 X509_OBJECT *ret) 301 { 302 X509_STORE *ctx = vs->ctx; 303 X509_LOOKUP *lu; 304 X509_OBJECT stmp, *tmp; 305 int i; 306 307 CRYPTO_MUTEX_lock_write(&ctx->objs_lock); 308 tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name); 309 CRYPTO_MUTEX_unlock_write(&ctx->objs_lock); 310 311 if (tmp == NULL || type == X509_LU_CRL) { 312 for (i = 0; i < (int)sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) { 313 lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i); 314 if (X509_LOOKUP_by_subject(lu, type, name, &stmp)) { 315 tmp = &stmp; 316 break; 317 } 318 } 319 if (tmp == NULL) 320 return 0; 321 } 322 323 /* 324 * if (ret->data.ptr != NULL) X509_OBJECT_free_contents(ret); 325 */ 326 327 ret->type = tmp->type; 328 ret->data.ptr = tmp->data.ptr; 329 330 X509_OBJECT_up_ref_count(ret); 331 332 return 1; 333 } 334 335 int X509_STORE_add_cert(X509_STORE *ctx, X509 *x) 336 { 337 X509_OBJECT *obj; 338 int ret = 1; 339 340 if (x == NULL) 341 return 0; 342 obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); 343 if (obj == NULL) { 344 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); 345 return 0; 346 } 347 obj->type = X509_LU_X509; 348 obj->data.x509 = x; 349 350 CRYPTO_MUTEX_lock_write(&ctx->objs_lock); 351 352 X509_OBJECT_up_ref_count(obj); 353 354 if (X509_OBJECT_retrieve_match(ctx->objs, obj)) { 355 X509_OBJECT_free_contents(obj); 356 OPENSSL_free(obj); 357 OPENSSL_PUT_ERROR(X509, X509_R_CERT_ALREADY_IN_HASH_TABLE); 358 ret = 0; 359 } else if (!sk_X509_OBJECT_push(ctx->objs, obj)) { 360 X509_OBJECT_free_contents(obj); 361 OPENSSL_free(obj); 362 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); 363 ret = 0; 364 } 365 366 CRYPTO_MUTEX_unlock_write(&ctx->objs_lock); 367 368 return ret; 369 } 370 371 int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x) 372 { 373 X509_OBJECT *obj; 374 int ret = 1; 375 376 if (x == NULL) 377 return 0; 378 obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); 379 if (obj == NULL) { 380 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); 381 return 0; 382 } 383 obj->type = X509_LU_CRL; 384 obj->data.crl = x; 385 386 CRYPTO_MUTEX_lock_write(&ctx->objs_lock); 387 388 X509_OBJECT_up_ref_count(obj); 389 390 if (X509_OBJECT_retrieve_match(ctx->objs, obj)) { 391 X509_OBJECT_free_contents(obj); 392 OPENSSL_free(obj); 393 OPENSSL_PUT_ERROR(X509, X509_R_CERT_ALREADY_IN_HASH_TABLE); 394 ret = 0; 395 } else if (!sk_X509_OBJECT_push(ctx->objs, obj)) { 396 X509_OBJECT_free_contents(obj); 397 OPENSSL_free(obj); 398 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); 399 ret = 0; 400 } 401 402 CRYPTO_MUTEX_unlock_write(&ctx->objs_lock); 403 404 return ret; 405 } 406 407 void X509_STORE_set0_additional_untrusted(X509_STORE *ctx, 408 STACK_OF(X509) *untrusted) { 409 ctx->additional_untrusted = untrusted; 410 } 411 412 int X509_OBJECT_up_ref_count(X509_OBJECT *a) 413 { 414 switch (a->type) { 415 case X509_LU_X509: 416 X509_up_ref(a->data.x509); 417 break; 418 case X509_LU_CRL: 419 X509_CRL_up_ref(a->data.crl); 420 break; 421 } 422 return 1; 423 } 424 425 void X509_OBJECT_free_contents(X509_OBJECT *a) 426 { 427 switch (a->type) { 428 case X509_LU_X509: 429 X509_free(a->data.x509); 430 break; 431 case X509_LU_CRL: 432 X509_CRL_free(a->data.crl); 433 break; 434 } 435 } 436 437 static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type, 438 X509_NAME *name, int *pnmatch) 439 { 440 X509_OBJECT stmp; 441 X509 x509_s; 442 X509_CINF cinf_s; 443 X509_CRL crl_s; 444 X509_CRL_INFO crl_info_s; 445 446 stmp.type = type; 447 switch (type) { 448 case X509_LU_X509: 449 stmp.data.x509 = &x509_s; 450 x509_s.cert_info = &cinf_s; 451 cinf_s.subject = name; 452 break; 453 case X509_LU_CRL: 454 stmp.data.crl = &crl_s; 455 crl_s.crl = &crl_info_s; 456 crl_info_s.issuer = name; 457 break; 458 default: 459 /* abort(); */ 460 return -1; 461 } 462 463 size_t idx; 464 if (!sk_X509_OBJECT_find(h, &idx, &stmp)) 465 return -1; 466 467 if (pnmatch != NULL) { 468 int tidx; 469 const X509_OBJECT *tobj, *pstmp; 470 *pnmatch = 1; 471 pstmp = &stmp; 472 for (tidx = idx + 1; tidx < (int)sk_X509_OBJECT_num(h); tidx++) { 473 tobj = sk_X509_OBJECT_value(h, tidx); 474 if (x509_object_cmp(&tobj, &pstmp)) 475 break; 476 (*pnmatch)++; 477 } 478 } 479 480 return idx; 481 } 482 483 int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, 484 X509_NAME *name) 485 { 486 return x509_object_idx_cnt(h, type, name, NULL); 487 } 488 489 X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, 490 int type, X509_NAME *name) 491 { 492 int idx; 493 idx = X509_OBJECT_idx_by_subject(h, type, name); 494 if (idx == -1) 495 return NULL; 496 return sk_X509_OBJECT_value(h, idx); 497 } 498 499 STACK_OF (X509) * X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm) 500 { 501 int i, idx, cnt; 502 STACK_OF(X509) *sk; 503 X509 *x; 504 X509_OBJECT *obj; 505 sk = sk_X509_new_null(); 506 if (sk == NULL) 507 return NULL; 508 CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); 509 idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); 510 if (idx < 0) { 511 /* 512 * Nothing found in cache: do lookup to possibly add new objects to 513 * cache 514 */ 515 X509_OBJECT xobj; 516 CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); 517 if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) { 518 sk_X509_free(sk); 519 return NULL; 520 } 521 X509_OBJECT_free_contents(&xobj); 522 CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); 523 idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); 524 if (idx < 0) { 525 CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); 526 sk_X509_free(sk); 527 return NULL; 528 } 529 } 530 for (i = 0; i < cnt; i++, idx++) { 531 obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); 532 x = obj->data.x509; 533 if (!sk_X509_push(sk, x)) { 534 CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); 535 sk_X509_pop_free(sk, X509_free); 536 return NULL; 537 } 538 X509_up_ref(x); 539 } 540 CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); 541 return sk; 542 543 } 544 545 STACK_OF (X509_CRL) * X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm) 546 { 547 int i, idx, cnt; 548 STACK_OF(X509_CRL) *sk; 549 X509_CRL *x; 550 X509_OBJECT *obj, xobj; 551 sk = sk_X509_CRL_new_null(); 552 if (sk == NULL) 553 return NULL; 554 555 /* Always do lookup to possibly add new CRLs to cache. */ 556 if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj)) { 557 sk_X509_CRL_free(sk); 558 return NULL; 559 } 560 X509_OBJECT_free_contents(&xobj); 561 CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); 562 idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt); 563 if (idx < 0) { 564 CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); 565 sk_X509_CRL_free(sk); 566 return NULL; 567 } 568 569 for (i = 0; i < cnt; i++, idx++) { 570 obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); 571 x = obj->data.crl; 572 X509_CRL_up_ref(x); 573 if (!sk_X509_CRL_push(sk, x)) { 574 CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); 575 X509_CRL_free(x); 576 sk_X509_CRL_pop_free(sk, X509_CRL_free); 577 return NULL; 578 } 579 } 580 CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); 581 return sk; 582 } 583 584 X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, 585 X509_OBJECT *x) 586 { 587 size_t idx, i; 588 X509_OBJECT *obj; 589 590 if (!sk_X509_OBJECT_find(h, &idx, x)) { 591 return NULL; 592 } 593 if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL)) 594 return sk_X509_OBJECT_value(h, idx); 595 for (i = idx; i < sk_X509_OBJECT_num(h); i++) { 596 obj = sk_X509_OBJECT_value(h, i); 597 if (x509_object_cmp 598 ((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x)) 599 return NULL; 600 if (x->type == X509_LU_X509) { 601 if (!X509_cmp(obj->data.x509, x->data.x509)) 602 return obj; 603 } else if (x->type == X509_LU_CRL) { 604 if (!X509_CRL_match(obj->data.crl, x->data.crl)) 605 return obj; 606 } else 607 return obj; 608 } 609 return NULL; 610 } 611 612 /* 613 * Try to get issuer certificate from store. Due to limitations of the API 614 * this can only retrieve a single certificate matching a given subject name. 615 * However it will fill the cache with all matching certificates, so we can 616 * examine the cache for all matches. Return values are: 1 lookup 617 * successful. 0 certificate not found. -1 some other error. 618 */ 619 int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) 620 { 621 X509_NAME *xn; 622 X509_OBJECT obj, *pobj; 623 int idx, ret; 624 size_t i; 625 xn = X509_get_issuer_name(x); 626 if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj)) 627 return 0; 628 /* If certificate matches all OK */ 629 if (ctx->check_issued(ctx, x, obj.data.x509)) { 630 *issuer = obj.data.x509; 631 return 1; 632 } 633 X509_OBJECT_free_contents(&obj); 634 635 /* Else find index of first cert accepted by 'check_issued' */ 636 ret = 0; 637 CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); 638 idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn); 639 if (idx != -1) { /* should be true as we've had at least one 640 * match */ 641 /* Look through all matching certs for suitable issuer */ 642 for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) { 643 pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i); 644 /* See if we've run past the matches */ 645 if (pobj->type != X509_LU_X509) 646 break; 647 if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509))) 648 break; 649 if (ctx->check_issued(ctx, x, pobj->data.x509)) { 650 *issuer = pobj->data.x509; 651 X509_OBJECT_up_ref_count(pobj); 652 ret = 1; 653 break; 654 } 655 } 656 } 657 CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); 658 return ret; 659 } 660 661 int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags) 662 { 663 return X509_VERIFY_PARAM_set_flags(ctx->param, flags); 664 } 665 666 int X509_STORE_set_depth(X509_STORE *ctx, int depth) 667 { 668 X509_VERIFY_PARAM_set_depth(ctx->param, depth); 669 return 1; 670 } 671 672 int X509_STORE_set_purpose(X509_STORE *ctx, int purpose) 673 { 674 return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose); 675 } 676 677 int X509_STORE_set_trust(X509_STORE *ctx, int trust) 678 { 679 return X509_VERIFY_PARAM_set_trust(ctx->param, trust); 680 } 681 682 int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param) 683 { 684 return X509_VERIFY_PARAM_set1(ctx->param, param); 685 } 686 687 void X509_STORE_set_verify_cb(X509_STORE *ctx, 688 int (*verify_cb) (int, X509_STORE_CTX *)) 689 { 690 ctx->verify_cb = verify_cb; 691 } 692 693 void X509_STORE_set_lookup_crls_cb(X509_STORE *ctx, 694 STACK_OF (X509_CRL) * 695 (*cb) (X509_STORE_CTX *ctx, X509_NAME *nm)) 696 { 697 ctx->lookup_crls = cb; 698 } 699 700 X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx) 701 { 702 return ctx->ctx; 703 } 704