2 * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
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
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"
18 DEFINE_STACK_OF(X509_LOOKUP)
19 DEFINE_STACK_OF(X509_OBJECT)
20 DEFINE_STACK_OF(X509_CRL)
23 X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method)
25 X509_LOOKUP *ret = OPENSSL_zalloc(sizeof(*ret));
28 X509err(X509_F_X509_LOOKUP_NEW, ERR_R_MALLOC_FAILURE);
33 if (method->new_item != NULL && method->new_item(ret) == 0) {
40 void X509_LOOKUP_free(X509_LOOKUP *ctx)
44 if ((ctx->method != NULL) && (ctx->method->free != NULL))
45 (*ctx->method->free) (ctx);
49 int X509_STORE_lock(X509_STORE *s)
51 return CRYPTO_THREAD_write_lock(s->lock);
54 int X509_STORE_unlock(X509_STORE *s)
56 return CRYPTO_THREAD_unlock(s->lock);
59 int X509_LOOKUP_init(X509_LOOKUP *ctx)
61 if (ctx->method == NULL)
63 if (ctx->method->init != NULL)
64 return ctx->method->init(ctx);
69 int X509_LOOKUP_shutdown(X509_LOOKUP *ctx)
71 if (ctx->method == NULL)
73 if (ctx->method->shutdown != NULL)
74 return ctx->method->shutdown(ctx);
79 int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
82 if (ctx->method == NULL)
84 if (ctx->method->ctrl != NULL)
85 return ctx->method->ctrl(ctx, cmd, argc, argl, ret);
90 int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
91 const X509_NAME *name, X509_OBJECT *ret)
93 if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL))
97 return ctx->method->get_by_subject(ctx, type, name, ret);
100 int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
101 const X509_NAME *name,
102 const ASN1_INTEGER *serial,
105 if ((ctx->method == NULL) || (ctx->method->get_by_issuer_serial == NULL))
107 return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret);
110 int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
111 const unsigned char *bytes, int len,
114 if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL))
116 return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret);
119 int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
120 const char *str, int len, X509_OBJECT *ret)
122 if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL))
124 return ctx->method->get_by_alias(ctx, type, str, len, ret);
127 int X509_LOOKUP_set_method_data(X509_LOOKUP *ctx, void *data)
129 ctx->method_data = data;
133 void *X509_LOOKUP_get_method_data(const X509_LOOKUP *ctx)
135 return ctx->method_data;
138 X509_STORE *X509_LOOKUP_get_store(const X509_LOOKUP *ctx)
140 return ctx->store_ctx;
144 static int x509_object_cmp(const X509_OBJECT *const *a,
145 const X509_OBJECT *const *b)
149 ret = ((*a)->type - (*b)->type);
152 switch ((*a)->type) {
154 ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509);
157 ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl);
166 X509_STORE *X509_STORE_new(void)
168 X509_STORE *ret = OPENSSL_zalloc(sizeof(*ret));
171 X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE);
174 if ((ret->objs = sk_X509_OBJECT_new(x509_object_cmp)) == NULL) {
175 X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE);
179 if ((ret->get_cert_methods = sk_X509_LOOKUP_new_null()) == NULL) {
180 X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE);
184 if ((ret->param = X509_VERIFY_PARAM_new()) == NULL) {
185 X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE);
188 if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data)) {
189 X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE);
193 ret->lock = CRYPTO_THREAD_lock_new();
194 if (ret->lock == NULL) {
195 X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE);
203 X509_VERIFY_PARAM_free(ret->param);
204 sk_X509_OBJECT_free(ret->objs);
205 sk_X509_LOOKUP_free(ret->get_cert_methods);
210 void X509_STORE_free(X509_STORE *vfy)
213 STACK_OF(X509_LOOKUP) *sk;
218 CRYPTO_DOWN_REF(&vfy->references, &i, vfy->lock);
219 REF_PRINT_COUNT("X509_STORE", vfy);
222 REF_ASSERT_ISNT(i < 0);
224 sk = vfy->get_cert_methods;
225 for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
226 lu = sk_X509_LOOKUP_value(sk, i);
227 X509_LOOKUP_shutdown(lu);
228 X509_LOOKUP_free(lu);
230 sk_X509_LOOKUP_free(sk);
231 sk_X509_OBJECT_pop_free(vfy->objs, X509_OBJECT_free);
233 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data);
234 X509_VERIFY_PARAM_free(vfy->param);
235 CRYPTO_THREAD_lock_free(vfy->lock);
239 int X509_STORE_up_ref(X509_STORE *vfy)
243 if (CRYPTO_UP_REF(&vfy->references, &i, vfy->lock) <= 0)
246 REF_PRINT_COUNT("X509_STORE", vfy);
247 REF_ASSERT_ISNT(i < 2);
248 return ((i > 1) ? 1 : 0);
251 X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m)
254 STACK_OF(X509_LOOKUP) *sk;
257 sk = v->get_cert_methods;
258 for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
259 lu = sk_X509_LOOKUP_value(sk, i);
260 if (m == lu->method) {
265 lu = X509_LOOKUP_new(m);
267 X509err(X509_F_X509_STORE_ADD_LOOKUP, ERR_R_MALLOC_FAILURE);
272 if (sk_X509_LOOKUP_push(v->get_cert_methods, lu))
275 X509err(X509_F_X509_STORE_ADD_LOOKUP, ERR_R_MALLOC_FAILURE);
276 X509_LOOKUP_free(lu);
280 X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs,
281 X509_LOOKUP_TYPE type,
282 const X509_NAME *name)
284 X509_OBJECT *ret = X509_OBJECT_new();
288 if (!X509_STORE_CTX_get_by_subject(vs, type, name, ret)) {
289 X509_OBJECT_free(ret);
295 int X509_STORE_CTX_get_by_subject(const X509_STORE_CTX *vs,
296 X509_LOOKUP_TYPE type,
297 const X509_NAME *name, X509_OBJECT *ret)
299 X509_STORE *store = vs->store;
301 X509_OBJECT stmp, *tmp;
307 stmp.type = X509_LU_NONE;
308 stmp.data.ptr = NULL;
311 X509_STORE_lock(store);
312 tmp = X509_OBJECT_retrieve_by_subject(store->objs, type, name);
313 X509_STORE_unlock(store);
315 if (tmp == NULL || type == X509_LU_CRL) {
316 for (i = 0; i < sk_X509_LOOKUP_num(store->get_cert_methods); i++) {
317 lu = sk_X509_LOOKUP_value(store->get_cert_methods, i);
318 j = X509_LOOKUP_by_subject(lu, type, name, &stmp);
328 if (!X509_OBJECT_up_ref_count(tmp))
331 ret->type = tmp->type;
332 ret->data.ptr = tmp->data.ptr;
337 static int x509_store_add(X509_STORE *store, void *x, int crl) {
339 int ret = 0, added = 0;
343 obj = X509_OBJECT_new();
348 obj->type = X509_LU_CRL;
349 obj->data.crl = (X509_CRL *)x;
351 obj->type = X509_LU_X509;
352 obj->data.x509 = (X509 *)x;
354 if (!X509_OBJECT_up_ref_count(obj)) {
355 obj->type = X509_LU_NONE;
356 X509_OBJECT_free(obj);
360 X509_STORE_lock(store);
361 if (X509_OBJECT_retrieve_match(store->objs, obj)) {
364 added = sk_X509_OBJECT_push(store->objs, obj);
367 X509_STORE_unlock(store);
369 if (added == 0) /* obj not pushed */
370 X509_OBJECT_free(obj);
375 int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
377 if (!x509_store_add(ctx, x, 0)) {
378 X509err(X509_F_X509_STORE_ADD_CERT, ERR_R_MALLOC_FAILURE);
384 int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
386 if (!x509_store_add(ctx, x, 1)) {
387 X509err(X509_F_X509_STORE_ADD_CRL, ERR_R_MALLOC_FAILURE);
393 int X509_OBJECT_up_ref_count(X509_OBJECT *a)
399 return X509_up_ref(a->data.x509);
401 return X509_CRL_up_ref(a->data.crl);
406 X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a)
408 if (a == NULL || a->type != X509_LU_X509)
413 X509_CRL *X509_OBJECT_get0_X509_CRL(const X509_OBJECT *a)
415 if (a == NULL || a->type != X509_LU_CRL)
420 X509_LOOKUP_TYPE X509_OBJECT_get_type(const X509_OBJECT *a)
425 X509_OBJECT *X509_OBJECT_new(void)
427 X509_OBJECT *ret = OPENSSL_zalloc(sizeof(*ret));
430 X509err(X509_F_X509_OBJECT_NEW, ERR_R_MALLOC_FAILURE);
433 ret->type = X509_LU_NONE;
437 static void x509_object_free_internal(X509_OBJECT *a)
445 X509_free(a->data.x509);
448 X509_CRL_free(a->data.crl);
453 int X509_OBJECT_set1_X509(X509_OBJECT *a, X509 *obj)
455 if (a == NULL || !X509_up_ref(obj))
458 x509_object_free_internal(a);
459 a->type = X509_LU_X509;
464 int X509_OBJECT_set1_X509_CRL(X509_OBJECT *a, X509_CRL *obj)
466 if (a == NULL || !X509_CRL_up_ref(obj))
469 x509_object_free_internal(a);
470 a->type = X509_LU_CRL;
475 void X509_OBJECT_free(X509_OBJECT *a)
477 x509_object_free_internal(a);
481 static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
482 const X509_NAME *name, int *pnmatch)
492 stmp.data.x509 = &x509_s;
493 x509_s.cert_info.subject = (X509_NAME *)name; /* won't modify it */
496 stmp.data.crl = &crl_s;
497 crl_s.crl.issuer = (X509_NAME *)name; /* won't modify it */
504 idx = sk_X509_OBJECT_find(h, &stmp);
505 if (idx >= 0 && pnmatch) {
507 const X509_OBJECT *tobj, *pstmp;
510 for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++) {
511 tobj = sk_X509_OBJECT_value(h, tidx);
512 if (x509_object_cmp(&tobj, &pstmp))
520 int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
521 const X509_NAME *name)
523 return x509_object_idx_cnt(h, type, name, NULL);
526 X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
527 X509_LOOKUP_TYPE type,
528 const X509_NAME *name)
531 idx = X509_OBJECT_idx_by_subject(h, type, name);
534 return sk_X509_OBJECT_value(h, idx);
537 STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(const X509_STORE *v)
542 /* TODO param type could be constified as change to lock is intermittent */
543 STACK_OF(X509) *X509_STORE_get1_all_certs(X509_STORE *store)
546 STACK_OF(X509_OBJECT) *objs;
550 X509err(0, ERR_R_PASSED_NULL_PARAMETER);
553 if ((sk = sk_X509_new_null()) == NULL)
555 X509_STORE_lock(store);
556 objs = X509_STORE_get0_objects(store);
557 for (i = 0; i < sk_X509_OBJECT_num(objs); i++) {
558 X509 *cert = X509_OBJECT_get0_X509(sk_X509_OBJECT_value(objs, i));
561 if (!X509_up_ref(cert))
563 if (!sk_X509_push(sk, cert)) {
569 X509_STORE_unlock(store);
573 X509_STORE_unlock(store);
574 sk_X509_pop_free(sk, X509_free);
578 STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx,
582 STACK_OF(X509) *sk = NULL;
585 X509_STORE *store = ctx->store;
590 X509_STORE_lock(store);
591 idx = x509_object_idx_cnt(store->objs, X509_LU_X509, nm, &cnt);
594 * Nothing found in cache: do lookup to possibly add new objects to
597 X509_OBJECT *xobj = X509_OBJECT_new();
599 X509_STORE_unlock(store);
603 if (!X509_STORE_CTX_get_by_subject(ctx, X509_LU_X509, nm, xobj)) {
604 X509_OBJECT_free(xobj);
607 X509_OBJECT_free(xobj);
608 X509_STORE_lock(store);
609 idx = x509_object_idx_cnt(store->objs, X509_LU_X509, nm, &cnt);
611 X509_STORE_unlock(store);
616 sk = sk_X509_new_null();
617 for (i = 0; i < cnt; i++, idx++) {
618 obj = sk_X509_OBJECT_value(store->objs, idx);
620 if (!X509_up_ref(x)) {
621 X509_STORE_unlock(store);
622 sk_X509_pop_free(sk, X509_free);
625 if (!sk_X509_push(sk, x)) {
626 X509_STORE_unlock(store);
628 sk_X509_pop_free(sk, X509_free);
632 X509_STORE_unlock(store);
636 STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(const X509_STORE_CTX *ctx,
640 STACK_OF(X509_CRL) *sk = sk_X509_CRL_new_null();
642 X509_OBJECT *obj, *xobj = X509_OBJECT_new();
643 X509_STORE *store = ctx->store;
645 /* Always do lookup to possibly add new CRLs to cache */
649 || !X509_STORE_CTX_get_by_subject(ctx, X509_LU_CRL, nm, xobj)) {
650 X509_OBJECT_free(xobj);
651 sk_X509_CRL_free(sk);
654 X509_OBJECT_free(xobj);
655 X509_STORE_lock(store);
656 idx = x509_object_idx_cnt(store->objs, X509_LU_CRL, nm, &cnt);
658 X509_STORE_unlock(store);
659 sk_X509_CRL_free(sk);
663 for (i = 0; i < cnt; i++, idx++) {
664 obj = sk_X509_OBJECT_value(store->objs, idx);
666 if (!X509_CRL_up_ref(x)) {
667 X509_STORE_unlock(store);
668 sk_X509_CRL_pop_free(sk, X509_CRL_free);
671 if (!sk_X509_CRL_push(sk, x)) {
672 X509_STORE_unlock(store);
674 sk_X509_CRL_pop_free(sk, X509_CRL_free);
678 X509_STORE_unlock(store);
682 X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
688 idx = sk_X509_OBJECT_find(h, x);
691 if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
692 return sk_X509_OBJECT_value(h, idx);
693 for (i = idx, num = sk_X509_OBJECT_num(h); i < num; i++) {
694 obj = sk_X509_OBJECT_value(h, i);
695 if (x509_object_cmp((const X509_OBJECT **)&obj,
696 (const X509_OBJECT **)&x))
698 if (x->type == X509_LU_X509) {
699 if (!X509_cmp(obj->data.x509, x->data.x509))
701 } else if (x->type == X509_LU_CRL) {
702 if (!X509_CRL_match(obj->data.crl, x->data.crl))
711 * Try to get issuer certificate from store. Due to limitations
712 * of the API this can only retrieve a single certificate matching
713 * a given subject name. However it will fill the cache with all
714 * matching certificates, so we can examine the cache for all
718 * 1 lookup successful.
719 * 0 certificate not found.
720 * -1 some other error.
722 int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
725 X509_OBJECT *obj = X509_OBJECT_new(), *pobj = NULL;
726 X509_STORE *store = ctx->store;
732 xn = X509_get_issuer_name(x);
733 ok = X509_STORE_CTX_get_by_subject(ctx, X509_LU_X509, xn, obj);
735 X509_OBJECT_free(obj);
738 /* If certificate matches all OK */
739 if (ctx->check_issued(ctx, x, obj->data.x509)) {
740 if (x509_check_cert_time(ctx, obj->data.x509, -1)) {
741 *issuer = obj->data.x509;
742 if (!X509_up_ref(*issuer)) {
746 X509_OBJECT_free(obj);
750 X509_OBJECT_free(obj);
755 /* Else find index of first cert accepted by 'check_issued' */
757 X509_STORE_lock(store);
758 idx = X509_OBJECT_idx_by_subject(store->objs, X509_LU_X509, xn);
759 if (idx != -1) { /* should be true as we've had at least one
761 /* Look through all matching certs for suitable issuer */
762 for (i = idx; i < sk_X509_OBJECT_num(store->objs); i++) {
763 pobj = sk_X509_OBJECT_value(store->objs, i);
764 /* See if we've run past the matches */
765 if (pobj->type != X509_LU_X509)
767 if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509)))
769 if (ctx->check_issued(ctx, x, pobj->data.x509)) {
770 *issuer = pobj->data.x509;
773 * If times check, exit with match,
774 * otherwise keep looking. Leave last
775 * match in issuer so we return nearest
776 * match if no certificate time is OK.
779 if (x509_check_cert_time(ctx, *issuer, -1))
784 if (*issuer && !X509_up_ref(*issuer)) {
788 X509_STORE_unlock(store);
792 int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
794 return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
797 int X509_STORE_set_depth(X509_STORE *ctx, int depth)
799 X509_VERIFY_PARAM_set_depth(ctx->param, depth);
803 int X509_STORE_set_purpose(X509_STORE *ctx, int purpose)
805 return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
808 int X509_STORE_set_trust(X509_STORE *ctx, int trust)
810 return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
813 int X509_STORE_set1_param(X509_STORE *ctx, const X509_VERIFY_PARAM *param)
815 return X509_VERIFY_PARAM_set1(ctx->param, param);
818 X509_VERIFY_PARAM *X509_STORE_get0_param(const X509_STORE *ctx)
823 void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify)
825 ctx->verify = verify;
828 X509_STORE_CTX_verify_fn X509_STORE_get_verify(const X509_STORE *ctx)
833 void X509_STORE_set_verify_cb(X509_STORE *ctx,
834 X509_STORE_CTX_verify_cb verify_cb)
836 ctx->verify_cb = verify_cb;
839 X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(const X509_STORE *ctx)
841 return ctx->verify_cb;
844 void X509_STORE_set_get_issuer(X509_STORE *ctx,
845 X509_STORE_CTX_get_issuer_fn get_issuer)
847 ctx->get_issuer = get_issuer;
850 X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(const X509_STORE *ctx)
852 return ctx->get_issuer;
855 void X509_STORE_set_check_issued(X509_STORE *ctx,
856 X509_STORE_CTX_check_issued_fn check_issued)
858 ctx->check_issued = check_issued;
861 X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(const X509_STORE *ctx)
863 return ctx->check_issued;
866 void X509_STORE_set_check_revocation(X509_STORE *ctx,
867 X509_STORE_CTX_check_revocation_fn check_revocation)
869 ctx->check_revocation = check_revocation;
872 X509_STORE_CTX_check_revocation_fn X509_STORE_get_check_revocation(const X509_STORE *ctx)
874 return ctx->check_revocation;
877 void X509_STORE_set_get_crl(X509_STORE *ctx,
878 X509_STORE_CTX_get_crl_fn get_crl)
880 ctx->get_crl = get_crl;
883 X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(const X509_STORE *ctx)
888 void X509_STORE_set_check_crl(X509_STORE *ctx,
889 X509_STORE_CTX_check_crl_fn check_crl)
891 ctx->check_crl = check_crl;
894 X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(const X509_STORE *ctx)
896 return ctx->check_crl;
899 void X509_STORE_set_cert_crl(X509_STORE *ctx,
900 X509_STORE_CTX_cert_crl_fn cert_crl)
902 ctx->cert_crl = cert_crl;
905 X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(const X509_STORE *ctx)
907 return ctx->cert_crl;
910 void X509_STORE_set_check_policy(X509_STORE *ctx,
911 X509_STORE_CTX_check_policy_fn check_policy)
913 ctx->check_policy = check_policy;
916 X509_STORE_CTX_check_policy_fn X509_STORE_get_check_policy(const X509_STORE *ctx)
918 return ctx->check_policy;
921 void X509_STORE_set_lookup_certs(X509_STORE *ctx,
922 X509_STORE_CTX_lookup_certs_fn lookup_certs)
924 ctx->lookup_certs = lookup_certs;
927 X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(const X509_STORE *ctx)
929 return ctx->lookup_certs;
932 void X509_STORE_set_lookup_crls(X509_STORE *ctx,
933 X509_STORE_CTX_lookup_crls_fn lookup_crls)
935 ctx->lookup_crls = lookup_crls;
938 X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(const X509_STORE *ctx)
940 return ctx->lookup_crls;
943 void X509_STORE_set_cleanup(X509_STORE *ctx,
944 X509_STORE_CTX_cleanup_fn ctx_cleanup)
946 ctx->cleanup = ctx_cleanup;
949 X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(const X509_STORE *ctx)
954 int X509_STORE_set_ex_data(X509_STORE *ctx, int idx, void *data)
956 return CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
959 void *X509_STORE_get_ex_data(const X509_STORE *ctx, int idx)
961 return CRYPTO_get_ex_data(&ctx->ex_data, idx);
964 X509_STORE *X509_STORE_CTX_get0_store(const X509_STORE_CTX *ctx)