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/mem.h> 62 #include <openssl/thread.h> 63 #include <openssl/x509.h> 64 #include <openssl/x509v3.h> 65 66 #include "../internal.h" 67 68 X509_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 88 void 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 97 int 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 107 int 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 117 int 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 128 int 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 138 int 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 146 int 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 155 int 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 163 static 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 184 X509_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 219 int X509_STORE_up_ref(X509_STORE *store) 220 { 221 CRYPTO_refcount_inc(&store->references); 222 return 1; 223 } 224 225 static 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 241 void 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 270 X509_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 298 int 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 334 int 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 370 int 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 406 void X509_STORE_set0_additional_untrusted(X509_STORE *ctx, 407 STACK_OF(X509) *untrusted) { 408 ctx->additional_untrusted = untrusted; 409 } 410 411 int 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 424 void 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 436 int X509_OBJECT_get_type(const X509_OBJECT *a) 437 { 438 return a->type; 439 } 440 441 X509 *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 449 static 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 495 int 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 501 X509_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 511 STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *st) 512 { 513 return st->objs; 514 } 515 516 STACK_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 562 STACK_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 601 X509_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 */ 636 int 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 678 int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags) 679 { 680 return X509_VERIFY_PARAM_set_flags(ctx->param, flags); 681 } 682 683 int X509_STORE_set_depth(X509_STORE *ctx, int depth) 684 { 685 X509_VERIFY_PARAM_set_depth(ctx->param, depth); 686 return 1; 687 } 688 689 int X509_STORE_set_purpose(X509_STORE *ctx, int purpose) 690 { 691 return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose); 692 } 693 694 int X509_STORE_set_trust(X509_STORE *ctx, int trust) 695 { 696 return X509_VERIFY_PARAM_set_trust(ctx->param, trust); 697 } 698 699 int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param) 700 { 701 return X509_VERIFY_PARAM_set1(ctx->param, param); 702 } 703 704 X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx) 705 { 706 return ctx->param; 707 } 708 709 void 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 715 void 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 722 X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx) 723 { 724 return ctx->ctx; 725 } 726