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