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