1/* crypto/x509/x509_lu.c */ 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@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@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@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@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/mem.h> 62#include <openssl/thread.h> 63#include <openssl/x509.h> 64#include <openssl/x509v3.h> 65 66#include "../internal.h" 67 68X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method) 69{ 70 X509_LOOKUP *ret; 71 72 ret = (X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP)); 73 if (ret == NULL) 74 return NULL; 75 76 ret->init = 0; 77 ret->skip = 0; 78 ret->method = method; 79 ret->method_data = NULL; 80 ret->store_ctx = NULL; 81 if ((method->new_item != NULL) && !method->new_item(ret)) { 82 OPENSSL_free(ret); 83 return NULL; 84 } 85 return ret; 86} 87 88void X509_LOOKUP_free(X509_LOOKUP *ctx) 89{ 90 if (ctx == NULL) 91 return; 92 if ((ctx->method != NULL) && (ctx->method->free != NULL)) 93 (*ctx->method->free) (ctx); 94 OPENSSL_free(ctx); 95} 96 97int X509_LOOKUP_init(X509_LOOKUP *ctx) 98{ 99 if (ctx->method == NULL) 100 return 0; 101 if (ctx->method->init != NULL) 102 return ctx->method->init(ctx); 103 else 104 return 1; 105} 106 107int X509_LOOKUP_shutdown(X509_LOOKUP *ctx) 108{ 109 if (ctx->method == NULL) 110 return 0; 111 if (ctx->method->shutdown != NULL) 112 return ctx->method->shutdown(ctx); 113 else 114 return 1; 115} 116 117int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, 118 char **ret) 119{ 120 if (ctx->method == NULL) 121 return -1; 122 if (ctx->method->ctrl != NULL) 123 return ctx->method->ctrl(ctx, cmd, argc, argl, ret); 124 else 125 return 1; 126} 127 128int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, 129 X509_OBJECT *ret) 130{ 131 if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL)) 132 return 0; 133 if (ctx->skip) 134 return 0; 135 return ctx->method->get_by_subject(ctx, type, name, ret) > 0; 136} 137 138int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name, 139 ASN1_INTEGER *serial, X509_OBJECT *ret) 140{ 141 if ((ctx->method == NULL) || (ctx->method->get_by_issuer_serial == NULL)) 142 return 0; 143 return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret) > 0; 144} 145 146int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, 147 unsigned char *bytes, int len, 148 X509_OBJECT *ret) 149{ 150 if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL)) 151 return 0; 152 return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret) > 0; 153} 154 155int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len, 156 X509_OBJECT *ret) 157{ 158 if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL)) 159 return 0; 160 return ctx->method->get_by_alias(ctx, type, str, len, ret) > 0; 161} 162 163static int x509_object_cmp(const X509_OBJECT **a, const X509_OBJECT **b) 164{ 165 int ret; 166 167 ret = ((*a)->type - (*b)->type); 168 if (ret) 169 return ret; 170 switch ((*a)->type) { 171 case X509_LU_X509: 172 ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509); 173 break; 174 case X509_LU_CRL: 175 ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl); 176 break; 177 default: 178 /* abort(); */ 179 return 0; 180 } 181 return ret; 182} 183 184X509_STORE *X509_STORE_new(void) 185{ 186 X509_STORE *ret; 187 188 if ((ret = (X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL) 189 return NULL; 190 OPENSSL_memset(ret, 0, sizeof(*ret)); 191 CRYPTO_MUTEX_init(&ret->objs_lock); 192 ret->objs = sk_X509_OBJECT_new(x509_object_cmp); 193 if (ret->objs == NULL) 194 goto err; 195 ret->cache = 1; 196 ret->get_cert_methods = sk_X509_LOOKUP_new_null(); 197 if (ret->get_cert_methods == NULL) 198 goto err; 199 ret->param = X509_VERIFY_PARAM_new(); 200 if (ret->param == NULL) 201 goto err; 202 203 ret->references = 1; 204 return ret; 205 err: 206 if (ret) { 207 CRYPTO_MUTEX_cleanup(&ret->objs_lock); 208 if (ret->param) 209 X509_VERIFY_PARAM_free(ret->param); 210 if (ret->get_cert_methods) 211 sk_X509_LOOKUP_free(ret->get_cert_methods); 212 if (ret->objs) 213 sk_X509_OBJECT_free(ret->objs); 214 OPENSSL_free(ret); 215 } 216 return NULL; 217} 218 219int X509_STORE_up_ref(X509_STORE *store) 220{ 221 CRYPTO_refcount_inc(&store->references); 222 return 1; 223} 224 225static void cleanup(X509_OBJECT *a) 226{ 227 if (a == NULL) { 228 return; 229 } 230 if (a->type == X509_LU_X509) { 231 X509_free(a->data.x509); 232 } else if (a->type == X509_LU_CRL) { 233 X509_CRL_free(a->data.crl); 234 } else { 235 /* abort(); */ 236 } 237 238 OPENSSL_free(a); 239} 240 241void X509_STORE_free(X509_STORE *vfy) 242{ 243 size_t j; 244 STACK_OF(X509_LOOKUP) *sk; 245 X509_LOOKUP *lu; 246 247 if (vfy == NULL) 248 return; 249 250 if (!CRYPTO_refcount_dec_and_test_zero(&vfy->references)) { 251 return; 252 } 253 254 CRYPTO_MUTEX_cleanup(&vfy->objs_lock); 255 256 sk = vfy->get_cert_methods; 257 for (j = 0; j < sk_X509_LOOKUP_num(sk); j++) { 258 lu = sk_X509_LOOKUP_value(sk, j); 259 X509_LOOKUP_shutdown(lu); 260 X509_LOOKUP_free(lu); 261 } 262 sk_X509_LOOKUP_free(sk); 263 sk_X509_OBJECT_pop_free(vfy->objs, cleanup); 264 265 if (vfy->param) 266 X509_VERIFY_PARAM_free(vfy->param); 267 OPENSSL_free(vfy); 268} 269 270X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m) 271{ 272 size_t i; 273 STACK_OF(X509_LOOKUP) *sk; 274 X509_LOOKUP *lu; 275 276 sk = v->get_cert_methods; 277 for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) { 278 lu = sk_X509_LOOKUP_value(sk, i); 279 if (m == lu->method) { 280 return lu; 281 } 282 } 283 /* a new one */ 284 lu = X509_LOOKUP_new(m); 285 if (lu == NULL) 286 return NULL; 287 else { 288 lu->store_ctx = v; 289 if (sk_X509_LOOKUP_push(v->get_cert_methods, lu)) 290 return lu; 291 else { 292 X509_LOOKUP_free(lu); 293 return NULL; 294 } 295 } 296} 297 298int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name, 299 X509_OBJECT *ret) 300{ 301 X509_STORE *ctx = vs->ctx; 302 X509_LOOKUP *lu; 303 X509_OBJECT stmp, *tmp; 304 int i; 305 306 CRYPTO_MUTEX_lock_write(&ctx->objs_lock); 307 tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name); 308 CRYPTO_MUTEX_unlock_write(&ctx->objs_lock); 309 310 if (tmp == NULL || type == X509_LU_CRL) { 311 for (i = 0; i < (int)sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) { 312 lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i); 313 if (X509_LOOKUP_by_subject(lu, type, name, &stmp)) { 314 tmp = &stmp; 315 break; 316 } 317 } 318 if (tmp == NULL) 319 return 0; 320 } 321 322 /* 323 * if (ret->data.ptr != NULL) X509_OBJECT_free_contents(ret); 324 */ 325 326 ret->type = tmp->type; 327 ret->data.ptr = tmp->data.ptr; 328 329 X509_OBJECT_up_ref_count(ret); 330 331 return 1; 332} 333 334int X509_STORE_add_cert(X509_STORE *ctx, X509 *x) 335{ 336 X509_OBJECT *obj; 337 int ret = 1; 338 339 if (x == NULL) 340 return 0; 341 obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); 342 if (obj == NULL) { 343 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); 344 return 0; 345 } 346 obj->type = X509_LU_X509; 347 obj->data.x509 = x; 348 349 CRYPTO_MUTEX_lock_write(&ctx->objs_lock); 350 351 X509_OBJECT_up_ref_count(obj); 352 353 if (X509_OBJECT_retrieve_match(ctx->objs, obj)) { 354 X509_OBJECT_free_contents(obj); 355 OPENSSL_free(obj); 356 OPENSSL_PUT_ERROR(X509, X509_R_CERT_ALREADY_IN_HASH_TABLE); 357 ret = 0; 358 } else if (!sk_X509_OBJECT_push(ctx->objs, obj)) { 359 X509_OBJECT_free_contents(obj); 360 OPENSSL_free(obj); 361 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); 362 ret = 0; 363 } 364 365 CRYPTO_MUTEX_unlock_write(&ctx->objs_lock); 366 367 return ret; 368} 369 370int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x) 371{ 372 X509_OBJECT *obj; 373 int ret = 1; 374 375 if (x == NULL) 376 return 0; 377 obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); 378 if (obj == NULL) { 379 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); 380 return 0; 381 } 382 obj->type = X509_LU_CRL; 383 obj->data.crl = x; 384 385 CRYPTO_MUTEX_lock_write(&ctx->objs_lock); 386 387 X509_OBJECT_up_ref_count(obj); 388 389 if (X509_OBJECT_retrieve_match(ctx->objs, obj)) { 390 X509_OBJECT_free_contents(obj); 391 OPENSSL_free(obj); 392 OPENSSL_PUT_ERROR(X509, X509_R_CERT_ALREADY_IN_HASH_TABLE); 393 ret = 0; 394 } else if (!sk_X509_OBJECT_push(ctx->objs, obj)) { 395 X509_OBJECT_free_contents(obj); 396 OPENSSL_free(obj); 397 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); 398 ret = 0; 399 } 400 401 CRYPTO_MUTEX_unlock_write(&ctx->objs_lock); 402 403 return ret; 404} 405 406void X509_STORE_set0_additional_untrusted(X509_STORE *ctx, 407 STACK_OF(X509) *untrusted) { 408 ctx->additional_untrusted = untrusted; 409} 410 411int X509_OBJECT_up_ref_count(X509_OBJECT *a) 412{ 413 switch (a->type) { 414 case X509_LU_X509: 415 X509_up_ref(a->data.x509); 416 break; 417 case X509_LU_CRL: 418 X509_CRL_up_ref(a->data.crl); 419 break; 420 } 421 return 1; 422} 423 424void X509_OBJECT_free_contents(X509_OBJECT *a) 425{ 426 switch (a->type) { 427 case X509_LU_X509: 428 X509_free(a->data.x509); 429 break; 430 case X509_LU_CRL: 431 X509_CRL_free(a->data.crl); 432 break; 433 } 434} 435 436int X509_OBJECT_get_type(const X509_OBJECT *a) 437{ 438 return a->type; 439} 440 441X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a) 442{ 443 if (a == NULL || a->type != X509_LU_X509) { 444 return NULL; 445 } 446 return a->data.x509; 447} 448 449static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type, 450 X509_NAME *name, int *pnmatch) 451{ 452 X509_OBJECT stmp; 453 X509 x509_s; 454 X509_CINF cinf_s; 455 X509_CRL crl_s; 456 X509_CRL_INFO crl_info_s; 457 458 stmp.type = type; 459 switch (type) { 460 case X509_LU_X509: 461 stmp.data.x509 = &x509_s; 462 x509_s.cert_info = &cinf_s; 463 cinf_s.subject = name; 464 break; 465 case X509_LU_CRL: 466 stmp.data.crl = &crl_s; 467 crl_s.crl = &crl_info_s; 468 crl_info_s.issuer = name; 469 break; 470 default: 471 /* abort(); */ 472 return -1; 473 } 474 475 size_t idx; 476 if (!sk_X509_OBJECT_find(h, &idx, &stmp)) 477 return -1; 478 479 if (pnmatch != NULL) { 480 int tidx; 481 const X509_OBJECT *tobj, *pstmp; 482 *pnmatch = 1; 483 pstmp = &stmp; 484 for (tidx = idx + 1; tidx < (int)sk_X509_OBJECT_num(h); tidx++) { 485 tobj = sk_X509_OBJECT_value(h, tidx); 486 if (x509_object_cmp(&tobj, &pstmp)) 487 break; 488 (*pnmatch)++; 489 } 490 } 491 492 return idx; 493} 494 495int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, 496 X509_NAME *name) 497{ 498 return x509_object_idx_cnt(h, type, name, NULL); 499} 500 501X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, 502 int type, X509_NAME *name) 503{ 504 int idx; 505 idx = X509_OBJECT_idx_by_subject(h, type, name); 506 if (idx == -1) 507 return NULL; 508 return sk_X509_OBJECT_value(h, idx); 509} 510 511STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *st) 512{ 513 return st->objs; 514} 515 516STACK_OF (X509) * X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm) 517{ 518 int i, idx, cnt; 519 STACK_OF(X509) *sk; 520 X509 *x; 521 X509_OBJECT *obj; 522 sk = sk_X509_new_null(); 523 if (sk == NULL) 524 return NULL; 525 CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); 526 idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); 527 if (idx < 0) { 528 /* 529 * Nothing found in cache: do lookup to possibly add new objects to 530 * cache 531 */ 532 X509_OBJECT xobj; 533 CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); 534 if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) { 535 sk_X509_free(sk); 536 return NULL; 537 } 538 X509_OBJECT_free_contents(&xobj); 539 CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); 540 idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); 541 if (idx < 0) { 542 CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); 543 sk_X509_free(sk); 544 return NULL; 545 } 546 } 547 for (i = 0; i < cnt; i++, idx++) { 548 obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); 549 x = obj->data.x509; 550 if (!sk_X509_push(sk, x)) { 551 CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); 552 sk_X509_pop_free(sk, X509_free); 553 return NULL; 554 } 555 X509_up_ref(x); 556 } 557 CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); 558 return sk; 559 560} 561 562STACK_OF (X509_CRL) * X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm) 563{ 564 int i, idx, cnt; 565 STACK_OF(X509_CRL) *sk; 566 X509_CRL *x; 567 X509_OBJECT *obj, xobj; 568 sk = sk_X509_CRL_new_null(); 569 if (sk == NULL) 570 return NULL; 571 572 /* Always do lookup to possibly add new CRLs to cache. */ 573 if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj)) { 574 sk_X509_CRL_free(sk); 575 return NULL; 576 } 577 X509_OBJECT_free_contents(&xobj); 578 CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); 579 idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt); 580 if (idx < 0) { 581 CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); 582 sk_X509_CRL_free(sk); 583 return NULL; 584 } 585 586 for (i = 0; i < cnt; i++, idx++) { 587 obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); 588 x = obj->data.crl; 589 X509_CRL_up_ref(x); 590 if (!sk_X509_CRL_push(sk, x)) { 591 CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); 592 X509_CRL_free(x); 593 sk_X509_CRL_pop_free(sk, X509_CRL_free); 594 return NULL; 595 } 596 } 597 CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); 598 return sk; 599} 600 601X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, 602 X509_OBJECT *x) 603{ 604 size_t idx, i; 605 X509_OBJECT *obj; 606 607 if (!sk_X509_OBJECT_find(h, &idx, x)) { 608 return NULL; 609 } 610 if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL)) 611 return sk_X509_OBJECT_value(h, idx); 612 for (i = idx; i < sk_X509_OBJECT_num(h); i++) { 613 obj = sk_X509_OBJECT_value(h, i); 614 if (x509_object_cmp 615 ((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x)) 616 return NULL; 617 if (x->type == X509_LU_X509) { 618 if (!X509_cmp(obj->data.x509, x->data.x509)) 619 return obj; 620 } else if (x->type == X509_LU_CRL) { 621 if (!X509_CRL_match(obj->data.crl, x->data.crl)) 622 return obj; 623 } else 624 return obj; 625 } 626 return NULL; 627} 628 629/* 630 * Try to get issuer certificate from store. Due to limitations of the API 631 * this can only retrieve a single certificate matching a given subject name. 632 * However it will fill the cache with all matching certificates, so we can 633 * examine the cache for all matches. Return values are: 1 lookup 634 * successful. 0 certificate not found. -1 some other error. 635 */ 636int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) 637{ 638 X509_NAME *xn; 639 X509_OBJECT obj, *pobj; 640 int idx, ret; 641 size_t i; 642 xn = X509_get_issuer_name(x); 643 if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj)) 644 return 0; 645 /* If certificate matches all OK */ 646 if (ctx->check_issued(ctx, x, obj.data.x509)) { 647 *issuer = obj.data.x509; 648 return 1; 649 } 650 X509_OBJECT_free_contents(&obj); 651 652 /* Else find index of first cert accepted by 'check_issued' */ 653 ret = 0; 654 CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); 655 idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn); 656 if (idx != -1) { /* should be true as we've had at least one 657 * match */ 658 /* Look through all matching certs for suitable issuer */ 659 for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) { 660 pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i); 661 /* See if we've run past the matches */ 662 if (pobj->type != X509_LU_X509) 663 break; 664 if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509))) 665 break; 666 if (ctx->check_issued(ctx, x, pobj->data.x509)) { 667 *issuer = pobj->data.x509; 668 X509_OBJECT_up_ref_count(pobj); 669 ret = 1; 670 break; 671 } 672 } 673 } 674 CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); 675 return ret; 676} 677 678int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags) 679{ 680 return X509_VERIFY_PARAM_set_flags(ctx->param, flags); 681} 682 683int X509_STORE_set_depth(X509_STORE *ctx, int depth) 684{ 685 X509_VERIFY_PARAM_set_depth(ctx->param, depth); 686 return 1; 687} 688 689int X509_STORE_set_purpose(X509_STORE *ctx, int purpose) 690{ 691 return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose); 692} 693 694int X509_STORE_set_trust(X509_STORE *ctx, int trust) 695{ 696 return X509_VERIFY_PARAM_set_trust(ctx->param, trust); 697} 698 699int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param) 700{ 701 return X509_VERIFY_PARAM_set1(ctx->param, param); 702} 703 704X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx) 705{ 706 return ctx->param; 707} 708 709void X509_STORE_set_verify_cb(X509_STORE *ctx, 710 int (*verify_cb) (int, X509_STORE_CTX *)) 711{ 712 ctx->verify_cb = verify_cb; 713} 714 715void X509_STORE_set_lookup_crls_cb(X509_STORE *ctx, 716 STACK_OF (X509_CRL) * 717 (*cb) (X509_STORE_CTX *ctx, X509_NAME *nm)) 718{ 719 ctx->lookup_crls = cb; 720} 721 722X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx) 723{ 724 return ctx->ctx; 725} 726