1 /* 2 * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <stdio.h> 11 #include "internal/cryptlib.h" 12 #include "internal/refcount.h" 13 #include <openssl/x509.h> 14 #include "crypto/x509.h" 15 #include <openssl/x509v3.h> 16 #include "x509_local.h" 17 18 X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method) 19 { 20 X509_LOOKUP *ret = OPENSSL_zalloc(sizeof(*ret)); 21 22 if (ret == NULL) 23 return NULL; 24 25 ret->method = method; 26 if (method->new_item != NULL && method->new_item(ret) == 0) { 27 OPENSSL_free(ret); 28 return NULL; 29 } 30 return ret; 31 } 32 33 void X509_LOOKUP_free(X509_LOOKUP *ctx) 34 { 35 if (ctx == NULL) 36 return; 37 if ((ctx->method != NULL) && (ctx->method->free != NULL)) 38 (*ctx->method->free) (ctx); 39 OPENSSL_free(ctx); 40 } 41 42 int X509_STORE_lock(X509_STORE *xs) 43 { 44 return CRYPTO_THREAD_write_lock(xs->lock); 45 } 46 47 int ossl_x509_store_read_lock(X509_STORE *xs) 48 { 49 return CRYPTO_THREAD_read_lock(xs->lock); 50 } 51 52 int X509_STORE_unlock(X509_STORE *xs) 53 { 54 return CRYPTO_THREAD_unlock(xs->lock); 55 } 56 57 int X509_LOOKUP_init(X509_LOOKUP *ctx) 58 { 59 if (ctx->method == NULL) 60 return 0; 61 if (ctx->method->init != NULL) 62 return ctx->method->init(ctx); 63 else 64 return 1; 65 } 66 67 int X509_LOOKUP_shutdown(X509_LOOKUP *ctx) 68 { 69 if (ctx->method == NULL) 70 return 0; 71 if (ctx->method->shutdown != NULL) 72 return ctx->method->shutdown(ctx); 73 else 74 return 1; 75 } 76 77 int X509_LOOKUP_ctrl_ex(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, 78 char **ret, OSSL_LIB_CTX *libctx, const char *propq) 79 { 80 if (ctx->method == NULL) 81 return -1; 82 if (ctx->method->ctrl_ex != NULL) 83 return ctx->method->ctrl_ex(ctx, cmd, argc, argl, ret, libctx, propq); 84 if (ctx->method->ctrl != NULL) 85 return ctx->method->ctrl(ctx, cmd, argc, argl, ret); 86 return 1; 87 } 88 89 int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, 90 char **ret) 91 { 92 return X509_LOOKUP_ctrl_ex(ctx, cmd, argc, argl, ret, NULL, NULL); 93 } 94 95 int X509_LOOKUP_by_subject_ex(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, 96 const X509_NAME *name, X509_OBJECT *ret, 97 OSSL_LIB_CTX *libctx, const char *propq) 98 { 99 if (ctx->skip 100 || ctx->method == NULL 101 || (ctx->method->get_by_subject == NULL 102 && ctx->method->get_by_subject_ex == NULL)) 103 return 0; 104 if (ctx->method->get_by_subject_ex != NULL) 105 return ctx->method->get_by_subject_ex(ctx, type, name, ret, libctx, 106 propq); 107 else 108 return ctx->method->get_by_subject(ctx, type, name, ret); 109 } 110 111 int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, 112 const X509_NAME *name, X509_OBJECT *ret) 113 { 114 return X509_LOOKUP_by_subject_ex(ctx, type, name, ret, NULL, NULL); 115 } 116 117 int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, 118 const X509_NAME *name, 119 const ASN1_INTEGER *serial, 120 X509_OBJECT *ret) 121 { 122 if ((ctx->method == NULL) || (ctx->method->get_by_issuer_serial == NULL)) 123 return 0; 124 return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret); 125 } 126 127 int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, 128 const unsigned char *bytes, int len, 129 X509_OBJECT *ret) 130 { 131 if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL)) 132 return 0; 133 return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret); 134 } 135 136 int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, 137 const char *str, int len, X509_OBJECT *ret) 138 { 139 if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL)) 140 return 0; 141 return ctx->method->get_by_alias(ctx, type, str, len, ret); 142 } 143 144 int X509_LOOKUP_set_method_data(X509_LOOKUP *ctx, void *data) 145 { 146 ctx->method_data = data; 147 return 1; 148 } 149 150 void *X509_LOOKUP_get_method_data(const X509_LOOKUP *ctx) 151 { 152 return ctx->method_data; 153 } 154 155 X509_STORE *X509_LOOKUP_get_store(const X509_LOOKUP *ctx) 156 { 157 return ctx->store_ctx; 158 } 159 160 static int x509_object_cmp(const X509_OBJECT *const *a, 161 const X509_OBJECT *const *b) 162 { 163 int ret; 164 165 ret = ((*a)->type - (*b)->type); 166 if (ret) 167 return ret; 168 switch ((*a)->type) { 169 case X509_LU_X509: 170 ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509); 171 break; 172 case X509_LU_CRL: 173 ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl); 174 break; 175 case X509_LU_NONE: 176 /* abort(); */ 177 return 0; 178 } 179 return ret; 180 } 181 182 X509_STORE *X509_STORE_new(void) 183 { 184 X509_STORE *ret = OPENSSL_zalloc(sizeof(*ret)); 185 186 if (ret == NULL) 187 return NULL; 188 if ((ret->objs = sk_X509_OBJECT_new(x509_object_cmp)) == NULL) { 189 ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); 190 goto err; 191 } 192 ret->cache = 1; 193 if ((ret->get_cert_methods = sk_X509_LOOKUP_new_null()) == NULL) { 194 ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); 195 goto err; 196 } 197 198 if ((ret->param = X509_VERIFY_PARAM_new()) == NULL) { 199 ERR_raise(ERR_LIB_X509, ERR_R_X509_LIB); 200 goto err; 201 } 202 if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data)) { 203 ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); 204 goto err; 205 } 206 207 ret->lock = CRYPTO_THREAD_lock_new(); 208 if (ret->lock == NULL) { 209 ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); 210 goto err; 211 } 212 213 if (!CRYPTO_NEW_REF(&ret->references, 1)) 214 goto err; 215 return ret; 216 217 err: 218 X509_VERIFY_PARAM_free(ret->param); 219 sk_X509_OBJECT_free(ret->objs); 220 sk_X509_LOOKUP_free(ret->get_cert_methods); 221 CRYPTO_THREAD_lock_free(ret->lock); 222 OPENSSL_free(ret); 223 return NULL; 224 } 225 226 void X509_STORE_free(X509_STORE *xs) 227 { 228 int i; 229 STACK_OF(X509_LOOKUP) *sk; 230 X509_LOOKUP *lu; 231 232 if (xs == NULL) 233 return; 234 CRYPTO_DOWN_REF(&xs->references, &i); 235 REF_PRINT_COUNT("X509_STORE", i, xs); 236 if (i > 0) 237 return; 238 REF_ASSERT_ISNT(i < 0); 239 240 sk = xs->get_cert_methods; 241 for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) { 242 lu = sk_X509_LOOKUP_value(sk, i); 243 X509_LOOKUP_shutdown(lu); 244 X509_LOOKUP_free(lu); 245 } 246 sk_X509_LOOKUP_free(sk); 247 sk_X509_OBJECT_pop_free(xs->objs, X509_OBJECT_free); 248 249 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, xs, &xs->ex_data); 250 X509_VERIFY_PARAM_free(xs->param); 251 CRYPTO_THREAD_lock_free(xs->lock); 252 CRYPTO_FREE_REF(&xs->references); 253 OPENSSL_free(xs); 254 } 255 256 int X509_STORE_up_ref(X509_STORE *xs) 257 { 258 int i; 259 260 if (CRYPTO_UP_REF(&xs->references, &i) <= 0) 261 return 0; 262 263 REF_PRINT_COUNT("X509_STORE", i, xs); 264 REF_ASSERT_ISNT(i < 2); 265 return i > 1 ? 1 : 0; 266 } 267 268 X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *xs, X509_LOOKUP_METHOD *m) 269 { 270 int i; 271 STACK_OF(X509_LOOKUP) *sk; 272 X509_LOOKUP *lu; 273 274 sk = xs->get_cert_methods; 275 for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) { 276 lu = sk_X509_LOOKUP_value(sk, i); 277 if (m == lu->method) { 278 return lu; 279 } 280 } 281 /* a new one */ 282 lu = X509_LOOKUP_new(m); 283 if (lu == NULL) { 284 ERR_raise(ERR_LIB_X509, ERR_R_X509_LIB); 285 return NULL; 286 } 287 288 lu->store_ctx = xs; 289 if (sk_X509_LOOKUP_push(xs->get_cert_methods, lu)) 290 return lu; 291 /* sk_X509_LOOKUP_push() failed */ 292 ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); 293 X509_LOOKUP_free(lu); 294 return NULL; 295 } 296 297 /* Also fill the cache (ctx->store->objs) with all matching certificates. */ 298 X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *ctx, 299 X509_LOOKUP_TYPE type, 300 const X509_NAME *name) 301 { 302 X509_OBJECT *ret = X509_OBJECT_new(); 303 304 if (ret == NULL) 305 return NULL; 306 if (!X509_STORE_CTX_get_by_subject(ctx, type, name, ret)) { 307 X509_OBJECT_free(ret); 308 return NULL; 309 } 310 return ret; 311 } 312 313 /* 314 * May be called with |ret| == NULL just for the side effect of 315 * caching all certs matching the given subject DN in |ctx->store->objs|. 316 * Returns 1 if successful, 317 * 0 if not found or X509_LOOKUP_by_subject_ex() returns an error, 318 * -1 on failure 319 */ 320 int ossl_x509_store_ctx_get_by_subject(const X509_STORE_CTX *ctx, X509_LOOKUP_TYPE type, 321 const X509_NAME *name, X509_OBJECT *ret) 322 { 323 X509_STORE *store = ctx->store; 324 X509_LOOKUP *lu; 325 X509_OBJECT stmp, *tmp; 326 int i, j; 327 328 if (store == NULL) 329 return 0; 330 331 stmp.type = X509_LU_NONE; 332 stmp.data.x509 = NULL; 333 334 if (!ossl_x509_store_read_lock(store)) 335 return 0; 336 /* Should already be sorted...but just in case */ 337 if (!sk_X509_OBJECT_is_sorted(store->objs)) { 338 X509_STORE_unlock(store); 339 /* Take a write lock instead of a read lock */ 340 if (!X509_STORE_lock(store)) 341 return 0; 342 /* 343 * Another thread might have sorted it in the meantime. But if so, 344 * sk_X509_OBJECT_sort() exits early. 345 */ 346 sk_X509_OBJECT_sort(store->objs); 347 } 348 tmp = X509_OBJECT_retrieve_by_subject(store->objs, type, name); 349 X509_STORE_unlock(store); 350 351 if (tmp == NULL || type == X509_LU_CRL) { 352 for (i = 0; i < sk_X509_LOOKUP_num(store->get_cert_methods); i++) { 353 lu = sk_X509_LOOKUP_value(store->get_cert_methods, i); 354 if (lu->skip) 355 continue; 356 if (lu->method == NULL) 357 return -1; 358 j = X509_LOOKUP_by_subject_ex(lu, type, name, &stmp, 359 ctx->libctx, ctx->propq); 360 if (j != 0) { /* non-zero value is considered success here */ 361 tmp = &stmp; 362 break; 363 } 364 } 365 if (tmp == NULL) 366 return 0; 367 } 368 369 if (ret != NULL) { 370 if (!X509_OBJECT_up_ref_count(tmp)) 371 return -1; 372 ret->type = tmp->type; 373 ret->data = tmp->data; 374 } 375 return 1; 376 } 377 378 /* Also fill the cache |ctx->store->objs| with all matching certificates. */ 379 int X509_STORE_CTX_get_by_subject(const X509_STORE_CTX *ctx, 380 X509_LOOKUP_TYPE type, 381 const X509_NAME *name, X509_OBJECT *ret) 382 { 383 return ossl_x509_store_ctx_get_by_subject(ctx, type, name, ret) > 0; 384 } 385 386 static int x509_store_add(X509_STORE *store, void *x, int crl) 387 { 388 X509_OBJECT *obj; 389 int ret = 0, added = 0; 390 391 if (x == NULL) 392 return 0; 393 obj = X509_OBJECT_new(); 394 if (obj == NULL) 395 return 0; 396 397 if (crl) { 398 obj->type = X509_LU_CRL; 399 obj->data.crl = (X509_CRL *)x; 400 } else { 401 obj->type = X509_LU_X509; 402 obj->data.x509 = (X509 *)x; 403 } 404 if (!X509_OBJECT_up_ref_count(obj)) { 405 obj->type = X509_LU_NONE; 406 X509_OBJECT_free(obj); 407 return 0; 408 } 409 410 if (!X509_STORE_lock(store)) { 411 obj->type = X509_LU_NONE; 412 X509_OBJECT_free(obj); 413 return 0; 414 } 415 416 if (X509_OBJECT_retrieve_match(store->objs, obj)) { 417 ret = 1; 418 } else { 419 added = sk_X509_OBJECT_push(store->objs, obj); 420 ret = added != 0; 421 } 422 X509_STORE_unlock(store); 423 424 if (added == 0) /* obj not pushed */ 425 X509_OBJECT_free(obj); 426 427 return ret; 428 } 429 430 int X509_STORE_add_cert(X509_STORE *xs, X509 *x) 431 { 432 if (!x509_store_add(xs, x, 0)) { 433 ERR_raise(ERR_LIB_X509, ERR_R_X509_LIB); 434 return 0; 435 } 436 return 1; 437 } 438 439 int X509_STORE_add_crl(X509_STORE *xs, X509_CRL *x) 440 { 441 if (!x509_store_add(xs, x, 1)) { 442 ERR_raise(ERR_LIB_X509, ERR_R_X509_LIB); 443 return 0; 444 } 445 return 1; 446 } 447 448 int X509_OBJECT_up_ref_count(X509_OBJECT *a) 449 { 450 switch (a->type) { 451 case X509_LU_NONE: 452 break; 453 case X509_LU_X509: 454 return X509_up_ref(a->data.x509); 455 case X509_LU_CRL: 456 return X509_CRL_up_ref(a->data.crl); 457 } 458 return 1; 459 } 460 461 X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a) 462 { 463 if (a == NULL || a->type != X509_LU_X509) 464 return NULL; 465 return a->data.x509; 466 } 467 468 X509_CRL *X509_OBJECT_get0_X509_CRL(const X509_OBJECT *a) 469 { 470 if (a == NULL || a->type != X509_LU_CRL) 471 return NULL; 472 return a->data.crl; 473 } 474 475 X509_LOOKUP_TYPE X509_OBJECT_get_type(const X509_OBJECT *a) 476 { 477 return a->type; 478 } 479 480 X509_OBJECT *X509_OBJECT_new(void) 481 { 482 X509_OBJECT *ret = OPENSSL_zalloc(sizeof(*ret)); 483 484 if (ret == NULL) 485 return NULL; 486 ret->type = X509_LU_NONE; 487 return ret; 488 } 489 490 static void x509_object_free_internal(X509_OBJECT *a) 491 { 492 if (a == NULL) 493 return; 494 switch (a->type) { 495 case X509_LU_NONE: 496 break; 497 case X509_LU_X509: 498 X509_free(a->data.x509); 499 break; 500 case X509_LU_CRL: 501 X509_CRL_free(a->data.crl); 502 break; 503 } 504 } 505 506 int X509_OBJECT_set1_X509(X509_OBJECT *a, X509 *obj) 507 { 508 if (a == NULL || !X509_up_ref(obj)) 509 return 0; 510 511 x509_object_free_internal(a); 512 a->type = X509_LU_X509; 513 a->data.x509 = obj; 514 return 1; 515 } 516 517 int X509_OBJECT_set1_X509_CRL(X509_OBJECT *a, X509_CRL *obj) 518 { 519 if (a == NULL || !X509_CRL_up_ref(obj)) 520 return 0; 521 522 x509_object_free_internal(a); 523 a->type = X509_LU_CRL; 524 a->data.crl = obj; 525 return 1; 526 } 527 528 void X509_OBJECT_free(X509_OBJECT *a) 529 { 530 x509_object_free_internal(a); 531 OPENSSL_free(a); 532 } 533 534 /* Returns -1 if not found, but also on error */ 535 static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type, 536 const X509_NAME *name, int *pnmatch) 537 { 538 X509_OBJECT stmp; 539 X509 x509_s; 540 X509_CRL crl_s; 541 542 stmp.type = type; 543 switch (type) { 544 case X509_LU_X509: 545 stmp.data.x509 = &x509_s; 546 x509_s.cert_info.subject = (X509_NAME *)name; /* won't modify it */ 547 break; 548 case X509_LU_CRL: 549 stmp.data.crl = &crl_s; 550 crl_s.crl.issuer = (X509_NAME *)name; /* won't modify it */ 551 break; 552 case X509_LU_NONE: 553 default: 554 /* abort(); */ 555 return -1; 556 } 557 558 /* Assumes h is locked for read if applicable */ 559 return sk_X509_OBJECT_find_all(h, &stmp, pnmatch); 560 } 561 562 /* Assumes h is locked for read if applicable */ 563 int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type, 564 const X509_NAME *name) 565 { 566 return x509_object_idx_cnt(h, type, name, NULL); 567 } 568 569 /* Assumes h is locked for read if applicable */ 570 X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, 571 X509_LOOKUP_TYPE type, 572 const X509_NAME *name) 573 { 574 int idx = X509_OBJECT_idx_by_subject(h, type, name); 575 576 if (idx == -1) 577 return NULL; 578 return sk_X509_OBJECT_value(h, idx); 579 } 580 581 STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(const X509_STORE *xs) 582 { 583 return xs->objs; 584 } 585 586 static X509_OBJECT *x509_object_dup(const X509_OBJECT *obj) 587 { 588 X509_OBJECT *ret = X509_OBJECT_new(); 589 if (ret == NULL) 590 return NULL; 591 592 ret->type = obj->type; 593 ret->data = obj->data; 594 X509_OBJECT_up_ref_count(ret); 595 return ret; 596 } 597 598 STACK_OF(X509_OBJECT) *X509_STORE_get1_objects(X509_STORE *store) 599 { 600 STACK_OF(X509_OBJECT) *objs; 601 602 if (store == NULL) { 603 ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); 604 return NULL; 605 } 606 607 if (!ossl_x509_store_read_lock(store)) 608 return NULL; 609 610 objs = sk_X509_OBJECT_deep_copy(store->objs, x509_object_dup, 611 X509_OBJECT_free); 612 X509_STORE_unlock(store); 613 return objs; 614 } 615 616 STACK_OF(X509) *X509_STORE_get1_all_certs(X509_STORE *store) 617 { 618 STACK_OF(X509) *sk; 619 STACK_OF(X509_OBJECT) *objs; 620 int i; 621 622 if (store == NULL) { 623 ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); 624 return NULL; 625 } 626 if ((sk = sk_X509_new_null()) == NULL) 627 return NULL; 628 if (!X509_STORE_lock(store)) 629 goto out_free; 630 631 sk_X509_OBJECT_sort(store->objs); 632 objs = X509_STORE_get0_objects(store); 633 for (i = 0; i < sk_X509_OBJECT_num(objs); i++) { 634 X509 *cert = X509_OBJECT_get0_X509(sk_X509_OBJECT_value(objs, i)); 635 636 if (cert != NULL 637 && !X509_add_cert(sk, cert, X509_ADD_FLAG_UP_REF)) 638 goto err; 639 } 640 X509_STORE_unlock(store); 641 return sk; 642 643 err: 644 X509_STORE_unlock(store); 645 out_free: 646 OSSL_STACK_OF_X509_free(sk); 647 return NULL; 648 } 649 650 /*- 651 * Collect from |ctx->store| all certs with subject matching |nm|. 652 * Returns NULL on internal/fatal error, empty stack if not found. 653 */ 654 STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, 655 const X509_NAME *nm) 656 { 657 int i, idx, cnt; 658 STACK_OF(X509) *sk = NULL; 659 X509 *x; 660 X509_OBJECT *obj; 661 X509_STORE *store = ctx->store; 662 663 if (store == NULL) 664 return sk_X509_new_null(); 665 666 if (!X509_STORE_lock(store)) 667 return NULL; 668 669 sk_X509_OBJECT_sort(store->objs); 670 idx = x509_object_idx_cnt(store->objs, X509_LU_X509, nm, &cnt); 671 if (idx < 0) { 672 /* 673 * Nothing found in cache: do lookup to possibly add new objects to 674 * cache 675 */ 676 X509_STORE_unlock(store); 677 i = ossl_x509_store_ctx_get_by_subject(ctx, X509_LU_X509, nm, NULL); 678 if (i <= 0) 679 return i < 0 ? NULL : sk_X509_new_null(); 680 if (!X509_STORE_lock(store)) 681 return NULL; 682 sk_X509_OBJECT_sort(store->objs); 683 idx = x509_object_idx_cnt(store->objs, X509_LU_X509, nm, &cnt); 684 } 685 686 sk = sk_X509_new_null(); 687 if (idx < 0 || sk == NULL) 688 goto end; 689 for (i = 0; i < cnt; i++, idx++) { 690 obj = sk_X509_OBJECT_value(store->objs, idx); 691 x = obj->data.x509; 692 if (!X509_add_cert(sk, x, X509_ADD_FLAG_UP_REF)) { 693 X509_STORE_unlock(store); 694 OSSL_STACK_OF_X509_free(sk); 695 return NULL; 696 } 697 } 698 end: 699 X509_STORE_unlock(store); 700 return sk; 701 } 702 703 /* Returns NULL on internal/fatal error, empty stack if not found */ 704 STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(const X509_STORE_CTX *ctx, 705 const X509_NAME *nm) 706 { 707 int i = 1, idx, cnt; 708 STACK_OF(X509_CRL) *sk; 709 X509_CRL *x; 710 X509_OBJECT *obj; 711 X509_STORE *store = ctx->store; 712 713 /* Always do lookup to possibly add new CRLs to cache */ 714 i = ossl_x509_store_ctx_get_by_subject(ctx, X509_LU_CRL, nm, NULL); 715 if (i < 0) 716 return NULL; 717 sk = sk_X509_CRL_new_null(); 718 if (i == 0) 719 return sk; 720 if (!X509_STORE_lock(store)) { 721 sk_X509_CRL_free(sk); 722 return NULL; 723 } 724 sk_X509_OBJECT_sort(store->objs); 725 idx = x509_object_idx_cnt(store->objs, X509_LU_CRL, nm, &cnt); 726 if (idx < 0) { 727 X509_STORE_unlock(store); 728 return sk; 729 } 730 731 for (i = 0; i < cnt; i++, idx++) { 732 obj = sk_X509_OBJECT_value(store->objs, idx); 733 x = obj->data.crl; 734 if (!X509_CRL_up_ref(x)) { 735 X509_STORE_unlock(store); 736 sk_X509_CRL_pop_free(sk, X509_CRL_free); 737 return NULL; 738 } 739 if (!sk_X509_CRL_push(sk, x)) { 740 X509_STORE_unlock(store); 741 X509_CRL_free(x); 742 sk_X509_CRL_pop_free(sk, X509_CRL_free); 743 return NULL; 744 } 745 } 746 X509_STORE_unlock(store); 747 return sk; 748 } 749 750 X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, 751 X509_OBJECT *x) 752 { 753 int idx, i, num; 754 X509_OBJECT *obj; 755 756 idx = sk_X509_OBJECT_find(h, x); 757 if (idx < 0) 758 return NULL; 759 if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL)) 760 return sk_X509_OBJECT_value(h, idx); 761 for (i = idx, num = sk_X509_OBJECT_num(h); i < num; i++) { 762 obj = sk_X509_OBJECT_value(h, i); 763 if (x509_object_cmp((const X509_OBJECT **)&obj, 764 (const X509_OBJECT **)&x)) 765 return NULL; 766 if (x->type == X509_LU_X509) { 767 if (!X509_cmp(obj->data.x509, x->data.x509)) 768 return obj; 769 } else if (x->type == X509_LU_CRL) { 770 if (X509_CRL_match(obj->data.crl, x->data.crl) == 0) 771 return obj; 772 } else { 773 return obj; 774 } 775 } 776 return NULL; 777 } 778 779 int X509_STORE_set_flags(X509_STORE *xs, unsigned long flags) 780 { 781 return X509_VERIFY_PARAM_set_flags(xs->param, flags); 782 } 783 784 int X509_STORE_set_depth(X509_STORE *xs, int depth) 785 { 786 X509_VERIFY_PARAM_set_depth(xs->param, depth); 787 return 1; 788 } 789 790 int X509_STORE_set_purpose(X509_STORE *xs, int purpose) 791 { 792 return X509_VERIFY_PARAM_set_purpose(xs->param, purpose); 793 } 794 795 int X509_STORE_set_trust(X509_STORE *xs, int trust) 796 { 797 return X509_VERIFY_PARAM_set_trust(xs->param, trust); 798 } 799 800 int X509_STORE_set1_param(X509_STORE *xs, const X509_VERIFY_PARAM *param) 801 { 802 return X509_VERIFY_PARAM_set1(xs->param, param); 803 } 804 805 X509_VERIFY_PARAM *X509_STORE_get0_param(const X509_STORE *xs) 806 { 807 return xs->param; 808 } 809 810 void X509_STORE_set_verify(X509_STORE *xs, X509_STORE_CTX_verify_fn verify) 811 { 812 xs->verify = verify; 813 } 814 815 X509_STORE_CTX_verify_fn X509_STORE_get_verify(const X509_STORE *xs) 816 { 817 return xs->verify; 818 } 819 820 void X509_STORE_set_verify_cb(X509_STORE *xs, 821 X509_STORE_CTX_verify_cb verify_cb) 822 { 823 xs->verify_cb = verify_cb; 824 } 825 826 X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(const X509_STORE *xs) 827 { 828 return xs->verify_cb; 829 } 830 831 void X509_STORE_set_get_issuer(X509_STORE *xs, 832 X509_STORE_CTX_get_issuer_fn get_issuer) 833 { 834 xs->get_issuer = get_issuer; 835 } 836 837 X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(const X509_STORE *xs) 838 { 839 return xs->get_issuer; 840 } 841 842 void X509_STORE_set_check_issued(X509_STORE *xs, 843 X509_STORE_CTX_check_issued_fn check_issued) 844 { 845 xs->check_issued = check_issued; 846 } 847 848 X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(const X509_STORE *xs) 849 { 850 return xs->check_issued; 851 } 852 853 void X509_STORE_set_check_revocation(X509_STORE *xs, 854 X509_STORE_CTX_check_revocation_fn cb) 855 { 856 xs->check_revocation = cb; 857 } 858 859 X509_STORE_CTX_check_revocation_fn X509_STORE_get_check_revocation(const X509_STORE *xs) 860 { 861 return xs->check_revocation; 862 } 863 864 void X509_STORE_set_get_crl(X509_STORE *xs, 865 X509_STORE_CTX_get_crl_fn get_crl) 866 { 867 xs->get_crl = get_crl; 868 } 869 870 X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(const X509_STORE *xs) 871 { 872 return xs->get_crl; 873 } 874 875 void X509_STORE_set_check_crl(X509_STORE *xs, 876 X509_STORE_CTX_check_crl_fn check_crl) 877 { 878 xs->check_crl = check_crl; 879 } 880 881 X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(const X509_STORE *xs) 882 { 883 return xs->check_crl; 884 } 885 886 void X509_STORE_set_cert_crl(X509_STORE *xs, 887 X509_STORE_CTX_cert_crl_fn cert_crl) 888 { 889 xs->cert_crl = cert_crl; 890 } 891 892 X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(const X509_STORE *xs) 893 { 894 return xs->cert_crl; 895 } 896 897 void X509_STORE_set_check_policy(X509_STORE *xs, 898 X509_STORE_CTX_check_policy_fn check_policy) 899 { 900 xs->check_policy = check_policy; 901 } 902 903 X509_STORE_CTX_check_policy_fn X509_STORE_get_check_policy(const X509_STORE *xs) 904 { 905 return xs->check_policy; 906 } 907 908 void X509_STORE_set_lookup_certs(X509_STORE *xs, 909 X509_STORE_CTX_lookup_certs_fn lookup_certs) 910 { 911 xs->lookup_certs = lookup_certs; 912 } 913 914 X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(const X509_STORE *xs) 915 { 916 return xs->lookup_certs; 917 } 918 919 void X509_STORE_set_lookup_crls(X509_STORE *xs, 920 X509_STORE_CTX_lookup_crls_fn lookup_crls) 921 { 922 xs->lookup_crls = lookup_crls; 923 } 924 925 X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(const X509_STORE *xs) 926 { 927 return xs->lookup_crls; 928 } 929 930 void X509_STORE_set_cleanup(X509_STORE *xs, 931 X509_STORE_CTX_cleanup_fn cleanup) 932 { 933 xs->cleanup = cleanup; 934 } 935 936 X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(const X509_STORE *xs) 937 { 938 return xs->cleanup; 939 } 940 941 int X509_STORE_set_ex_data(X509_STORE *xs, int idx, void *data) 942 { 943 return CRYPTO_set_ex_data(&xs->ex_data, idx, data); 944 } 945 946 void *X509_STORE_get_ex_data(const X509_STORE *xs, int idx) 947 { 948 return CRYPTO_get_ex_data(&xs->ex_data, idx); 949 } 950 951 X509_STORE *X509_STORE_CTX_get0_store(const X509_STORE_CTX *ctx) 952 { 953 return ctx->store; 954 } 955