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 70 X509_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 90 void 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 99 int 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 108 int 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 117 int 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 127 int 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 136 int 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 145 int 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 153 int 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 162 static 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 183 X509_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 CRYPTO_MUTEX_init(&ret->objs_lock); 191 ret->objs = sk_X509_OBJECT_new(x509_object_cmp); 192 if (ret->objs == NULL) 193 goto err; 194 ret->cache = 1; 195 ret->get_cert_methods = sk_X509_LOOKUP_new_null(); 196 if (ret->get_cert_methods == NULL) 197 goto err; 198 ret->param = X509_VERIFY_PARAM_new(); 199 if (ret->param == NULL) 200 goto err; 201 202 ret->references = 1; 203 return ret; 204 err: 205 if (ret) 206 { 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 219 static void cleanup(X509_OBJECT *a) 220 { 221 if (a->type == X509_LU_X509) 222 { 223 X509_free(a->data.x509); 224 } 225 else if (a->type == X509_LU_CRL) 226 { 227 X509_CRL_free(a->data.crl); 228 } 229 else 230 { 231 /* abort(); */ 232 } 233 234 OPENSSL_free(a); 235 } 236 237 void X509_STORE_free(X509_STORE *vfy) 238 { 239 size_t j; 240 STACK_OF(X509_LOOKUP) *sk; 241 X509_LOOKUP *lu; 242 243 if (vfy == NULL) 244 return; 245 246 if (!CRYPTO_refcount_dec_and_test_zero(&vfy->references)) { 247 return; 248 } 249 250 CRYPTO_MUTEX_cleanup(&vfy->objs_lock); 251 252 sk=vfy->get_cert_methods; 253 for (j=0; j<sk_X509_LOOKUP_num(sk); j++) 254 { 255 lu=sk_X509_LOOKUP_value(sk,j); 256 X509_LOOKUP_shutdown(lu); 257 X509_LOOKUP_free(lu); 258 } 259 sk_X509_LOOKUP_free(sk); 260 sk_X509_OBJECT_pop_free(vfy->objs, cleanup); 261 262 if (vfy->param) 263 X509_VERIFY_PARAM_free(vfy->param); 264 OPENSSL_free(vfy); 265 } 266 267 X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m) 268 { 269 size_t i; 270 STACK_OF(X509_LOOKUP) *sk; 271 X509_LOOKUP *lu; 272 273 sk=v->get_cert_methods; 274 for (i=0; i<sk_X509_LOOKUP_num(sk); i++) 275 { 276 lu=sk_X509_LOOKUP_value(sk,i); 277 if (m == lu->method) 278 { 279 return lu; 280 } 281 } 282 /* a new one */ 283 lu=X509_LOOKUP_new(m); 284 if (lu == NULL) 285 return NULL; 286 else 287 { 288 lu->store_ctx=v; 289 if (sk_X509_LOOKUP_push(v->get_cert_methods,lu)) 290 return lu; 291 else 292 { 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,j; 306 307 CRYPTO_MUTEX_lock_write(&ctx->objs_lock); 308 tmp=X509_OBJECT_retrieve_by_subject(ctx->objs,type,name); 309 CRYPTO_MUTEX_unlock(&ctx->objs_lock); 310 311 if (tmp == NULL || type == X509_LU_CRL) 312 { 313 for (i=vs->current_method; i<(int)sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) 314 { 315 lu=sk_X509_LOOKUP_value(ctx->get_cert_methods,i); 316 j=X509_LOOKUP_by_subject(lu,type,name,&stmp); 317 if (j < 0) 318 { 319 vs->current_method=j; 320 return j; 321 } 322 else if (j) 323 { 324 tmp= &stmp; 325 break; 326 } 327 } 328 vs->current_method=0; 329 if (tmp == NULL) 330 return 0; 331 } 332 333 /* if (ret->data.ptr != NULL) 334 X509_OBJECT_free_contents(ret); */ 335 336 ret->type=tmp->type; 337 ret->data.ptr=tmp->data.ptr; 338 339 X509_OBJECT_up_ref_count(ret); 340 341 return 1; 342 } 343 344 int X509_STORE_add_cert(X509_STORE *ctx, X509 *x) 345 { 346 X509_OBJECT *obj; 347 int ret=1; 348 349 if (x == NULL) return 0; 350 obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); 351 if (obj == NULL) 352 { 353 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); 354 return 0; 355 } 356 obj->type=X509_LU_X509; 357 obj->data.x509=x; 358 359 CRYPTO_MUTEX_lock_write(&ctx->objs_lock); 360 361 X509_OBJECT_up_ref_count(obj); 362 363 if (X509_OBJECT_retrieve_match(ctx->objs, obj)) 364 { 365 X509_OBJECT_free_contents(obj); 366 OPENSSL_free(obj); 367 OPENSSL_PUT_ERROR(X509, X509_R_CERT_ALREADY_IN_HASH_TABLE); 368 ret=0; 369 } 370 else sk_X509_OBJECT_push(ctx->objs, obj); 371 372 CRYPTO_MUTEX_unlock(&ctx->objs_lock); 373 374 return ret; 375 } 376 377 int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x) 378 { 379 X509_OBJECT *obj; 380 int ret=1; 381 382 if (x == NULL) return 0; 383 obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); 384 if (obj == NULL) 385 { 386 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); 387 return 0; 388 } 389 obj->type=X509_LU_CRL; 390 obj->data.crl=x; 391 392 CRYPTO_MUTEX_lock_write(&ctx->objs_lock); 393 394 X509_OBJECT_up_ref_count(obj); 395 396 if (X509_OBJECT_retrieve_match(ctx->objs, obj)) 397 { 398 X509_OBJECT_free_contents(obj); 399 OPENSSL_free(obj); 400 OPENSSL_PUT_ERROR(X509, X509_R_CERT_ALREADY_IN_HASH_TABLE); 401 ret=0; 402 } 403 else sk_X509_OBJECT_push(ctx->objs, obj); 404 405 CRYPTO_MUTEX_unlock(&ctx->objs_lock); 406 407 return ret; 408 } 409 410 void X509_OBJECT_up_ref_count(X509_OBJECT *a) 411 { 412 switch (a->type) 413 { 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 } 422 423 void X509_OBJECT_free_contents(X509_OBJECT *a) 424 { 425 switch (a->type) 426 { 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 436 static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type, 437 X509_NAME *name, int *pnmatch) 438 { 439 X509_OBJECT stmp; 440 X509 x509_s; 441 X509_CINF cinf_s; 442 X509_CRL crl_s; 443 X509_CRL_INFO crl_info_s; 444 445 stmp.type=type; 446 switch (type) 447 { 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 { 469 int tidx; 470 const X509_OBJECT *tobj, *pstmp; 471 *pnmatch = 1; 472 pstmp = &stmp; 473 for (tidx = idx + 1; tidx < (int)sk_X509_OBJECT_num(h); tidx++) 474 { 475 tobj = sk_X509_OBJECT_value(h, tidx); 476 if (x509_object_cmp(&tobj, &pstmp)) 477 break; 478 (*pnmatch)++; 479 } 480 } 481 482 return idx; 483 } 484 485 486 int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, 487 X509_NAME *name) 488 { 489 return x509_object_idx_cnt(h, type, name, NULL); 490 } 491 492 X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type, 493 X509_NAME *name) 494 { 495 int idx; 496 idx = X509_OBJECT_idx_by_subject(h, type, name); 497 if (idx==-1) return NULL; 498 return sk_X509_OBJECT_value(h, idx); 499 } 500 501 STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm) 502 { 503 int i, idx, cnt; 504 STACK_OF(X509) *sk; 505 X509 *x; 506 X509_OBJECT *obj; 507 sk = sk_X509_new_null(); 508 if (sk == NULL) 509 return NULL; 510 CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); 511 idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); 512 if (idx < 0) 513 { 514 /* Nothing found in cache: do lookup to possibly add new 515 * objects to cache 516 */ 517 X509_OBJECT xobj; 518 CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock); 519 if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) 520 { 521 sk_X509_free(sk); 522 return NULL; 523 } 524 X509_OBJECT_free_contents(&xobj); 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 CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock); 530 sk_X509_free(sk); 531 return NULL; 532 } 533 } 534 for (i = 0; i < cnt; i++, idx++) 535 { 536 obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); 537 x = obj->data.x509; 538 if (!sk_X509_push(sk, X509_up_ref(x))) 539 { 540 CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock); 541 X509_free(x); 542 sk_X509_pop_free(sk, X509_free); 543 return NULL; 544 } 545 } 546 CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock); 547 return sk; 548 549 } 550 551 STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm) 552 { 553 int i, idx, cnt; 554 STACK_OF(X509_CRL) *sk; 555 X509_CRL *x; 556 X509_OBJECT *obj, xobj; 557 sk = sk_X509_CRL_new_null(); 558 if (sk == NULL) 559 return NULL; 560 561 /* Always do lookup to possibly add new CRLs to cache. */ 562 if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj)) 563 { 564 sk_X509_CRL_free(sk); 565 return NULL; 566 } 567 X509_OBJECT_free_contents(&xobj); 568 CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); 569 idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_CRL, nm, &cnt); 570 if (idx < 0) 571 { 572 CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock); 573 sk_X509_CRL_free(sk); 574 return NULL; 575 } 576 577 for (i = 0; i < cnt; i++, idx++) 578 { 579 obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); 580 x = obj->data.crl; 581 X509_CRL_up_ref(x); 582 if (!sk_X509_CRL_push(sk, x)) 583 { 584 CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock); 585 X509_CRL_free(x); 586 sk_X509_CRL_pop_free(sk, X509_CRL_free); 587 return NULL; 588 } 589 } 590 CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock); 591 return sk; 592 } 593 594 X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x) 595 { 596 size_t idx, i; 597 X509_OBJECT *obj; 598 599 if (!sk_X509_OBJECT_find(h, &idx, x)) { 600 return NULL; 601 } 602 if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL)) 603 return sk_X509_OBJECT_value(h, idx); 604 for (i = idx; i < sk_X509_OBJECT_num(h); i++) 605 { 606 obj = sk_X509_OBJECT_value(h, i); 607 if (x509_object_cmp((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x)) 608 return NULL; 609 if (x->type == X509_LU_X509) 610 { 611 if (!X509_cmp(obj->data.x509, x->data.x509)) 612 return obj; 613 } 614 else if (x->type == X509_LU_CRL) 615 { 616 if (!X509_CRL_match(obj->data.crl, x->data.crl)) 617 return obj; 618 } 619 else 620 return obj; 621 } 622 return NULL; 623 } 624 625 626 /* Try to get issuer certificate from store. Due to limitations 627 * of the API this can only retrieve a single certificate matching 628 * a given subject name. However it will fill the cache with all 629 * matching certificates, so we can examine the cache for all 630 * matches. 631 * 632 * Return values are: 633 * 1 lookup successful. 634 * 0 certificate not found. 635 * -1 some other error. 636 */ 637 int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) 638 { 639 X509_NAME *xn; 640 X509_OBJECT obj, *pobj; 641 int ok, idx, ret; 642 size_t i; 643 xn=X509_get_issuer_name(x); 644 ok=X509_STORE_get_by_subject(ctx,X509_LU_X509,xn,&obj); 645 if (ok != X509_LU_X509) 646 { 647 if (ok == X509_LU_RETRY) 648 { 649 X509_OBJECT_free_contents(&obj); 650 OPENSSL_PUT_ERROR(X509, X509_R_SHOULD_RETRY); 651 return -1; 652 } 653 else if (ok != X509_LU_FAIL) 654 { 655 X509_OBJECT_free_contents(&obj); 656 /* not good :-(, break anyway */ 657 return -1; 658 } 659 return 0; 660 } 661 /* If certificate matches all OK */ 662 if (ctx->check_issued(ctx, x, obj.data.x509)) 663 { 664 *issuer = obj.data.x509; 665 return 1; 666 } 667 X509_OBJECT_free_contents(&obj); 668 669 /* Else find index of first cert accepted by 'check_issued' */ 670 ret = 0; 671 CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); 672 idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn); 673 if (idx != -1) /* should be true as we've had at least one match */ 674 { 675 /* Look through all matching certs for suitable issuer */ 676 for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) 677 { 678 pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i); 679 /* See if we've run past the matches */ 680 if (pobj->type != X509_LU_X509) 681 break; 682 if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509))) 683 break; 684 if (ctx->check_issued(ctx, x, pobj->data.x509)) 685 { 686 *issuer = pobj->data.x509; 687 X509_OBJECT_up_ref_count(pobj); 688 ret = 1; 689 break; 690 } 691 } 692 } 693 CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock); 694 return ret; 695 } 696 697 int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags) 698 { 699 return X509_VERIFY_PARAM_set_flags(ctx->param, flags); 700 } 701 702 int X509_STORE_set_depth(X509_STORE *ctx, int depth) 703 { 704 X509_VERIFY_PARAM_set_depth(ctx->param, depth); 705 return 1; 706 } 707 708 int X509_STORE_set_purpose(X509_STORE *ctx, int purpose) 709 { 710 return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose); 711 } 712 713 int X509_STORE_set_trust(X509_STORE *ctx, int trust) 714 { 715 return X509_VERIFY_PARAM_set_trust(ctx->param, trust); 716 } 717 718 int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param) 719 { 720 return X509_VERIFY_PARAM_set1(ctx->param, param); 721 } 722 723 void X509_STORE_set_verify_cb(X509_STORE *ctx, 724 int (*verify_cb)(int, X509_STORE_CTX *)) 725 { 726 ctx->verify_cb = verify_cb; 727 } 728 729 void X509_STORE_set_lookup_crls_cb(X509_STORE *ctx, 730 STACK_OF(X509_CRL)* (*cb)(X509_STORE_CTX *ctx, X509_NAME *nm)) 731 { 732 ctx->lookup_crls = cb; 733 } 734 735 X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx) 736 { 737 return ctx->ctx; 738 } 739