summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/x509/x509_lu.c
diff options
context:
space:
mode:
authorcvs2svn <admin@example.com>2025-04-14 17:32:06 +0000
committercvs2svn <admin@example.com>2025-04-14 17:32:06 +0000
commiteb8dd9dca1228af0cd132f515509051ecfabf6f6 (patch)
treeedb6da6af7e865d488dc1a29309f1e1ec226e603 /src/lib/libcrypto/x509/x509_lu.c
parent247f0352e0ed72a4f476db9dc91f4d982bc83eb2 (diff)
downloadopenbsd-tb_20250414.tar.gz
openbsd-tb_20250414.tar.bz2
openbsd-tb_20250414.zip
This commit was manufactured by cvs2git to create tag 'tb_20250414'.tb_20250414
Diffstat (limited to 'src/lib/libcrypto/x509/x509_lu.c')
-rw-r--r--src/lib/libcrypto/x509/x509_lu.c883
1 files changed, 0 insertions, 883 deletions
diff --git a/src/lib/libcrypto/x509/x509_lu.c b/src/lib/libcrypto/x509/x509_lu.c
deleted file mode 100644
index 0367794fca..0000000000
--- a/src/lib/libcrypto/x509/x509_lu.c
+++ /dev/null
@@ -1,883 +0,0 @@
1/* $OpenBSD: x509_lu.c,v 1.67 2025/03/09 15:20:20 tb 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#include <string.h>
61
62#include <openssl/err.h>
63#include <openssl/lhash.h>
64#include <openssl/x509.h>
65#include <openssl/x509v3.h>
66
67#include "x509_local.h"
68
69static int X509_OBJECT_up_ref_count(X509_OBJECT *a);
70
71static X509_LOOKUP *
72X509_LOOKUP_new(const X509_LOOKUP_METHOD *method)
73{
74 X509_LOOKUP *lu;
75
76 if ((lu = calloc(1, sizeof(*lu))) == NULL) {
77 X509error(ERR_R_MALLOC_FAILURE);
78 return NULL;
79 }
80
81 lu->method = method;
82
83 if (method->new_item != NULL && !method->new_item(lu)) {
84 free(lu);
85 return NULL;
86 }
87
88 return lu;
89}
90
91void
92X509_LOOKUP_free(X509_LOOKUP *ctx)
93{
94 if (ctx == NULL)
95 return;
96 if (ctx->method != NULL && ctx->method->free != NULL)
97 ctx->method->free(ctx);
98 free(ctx);
99}
100LCRYPTO_ALIAS(X509_LOOKUP_free);
101
102int
103X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
104 char **ret)
105{
106 if (ctx->method == NULL)
107 return -1;
108 if (ctx->method->ctrl == NULL)
109 return 1;
110 return ctx->method->ctrl(ctx, cmd, argc, argl, ret);
111}
112LCRYPTO_ALIAS(X509_LOOKUP_ctrl);
113
114static int
115X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, X509_NAME *name,
116 X509_OBJECT *ret)
117{
118 if (ctx->method == NULL || ctx->method->get_by_subject == NULL)
119 return 0;
120 return ctx->method->get_by_subject(ctx, type, name, ret);
121}
122
123static int
124x509_object_cmp(const X509_OBJECT * const *a, const X509_OBJECT * const *b)
125{
126 int ret;
127
128 if ((ret = (*a)->type - (*b)->type) != 0)
129 return ret;
130
131 switch ((*a)->type) {
132 case X509_LU_X509:
133 return X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509);
134 case X509_LU_CRL:
135 return X509_CRL_cmp((*a)->data.crl, (*b)->data.crl);
136 }
137 return 0;
138}
139
140X509_STORE *
141X509_STORE_new(void)
142{
143 X509_STORE *store;
144
145 if ((store = calloc(1, sizeof(*store))) == NULL)
146 goto err;
147
148 if ((store->objs = sk_X509_OBJECT_new(x509_object_cmp)) == NULL)
149 goto err;
150 if ((store->get_cert_methods = sk_X509_LOOKUP_new_null()) == NULL)
151 goto err;
152 if ((store->param = X509_VERIFY_PARAM_new()) == NULL)
153 goto err;
154
155 if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, store,
156 &store->ex_data))
157 goto err;
158
159 store->references = 1;
160
161 return store;
162
163 err:
164 X509error(ERR_R_MALLOC_FAILURE);
165 X509_STORE_free(store);
166
167 return NULL;
168}
169LCRYPTO_ALIAS(X509_STORE_new);
170
171X509_OBJECT *
172X509_OBJECT_new(void)
173{
174 X509_OBJECT *obj;
175
176 if ((obj = calloc(1, sizeof(*obj))) == NULL) {
177 X509error(ERR_R_MALLOC_FAILURE);
178 return NULL;
179 }
180
181 obj->type = X509_LU_NONE;
182
183 return obj;
184}
185LCRYPTO_ALIAS(X509_OBJECT_new);
186
187void
188X509_OBJECT_free(X509_OBJECT *a)
189{
190 if (a == NULL)
191 return;
192
193 switch (a->type) {
194 case X509_LU_X509:
195 X509_free(a->data.x509);
196 break;
197 case X509_LU_CRL:
198 X509_CRL_free(a->data.crl);
199 break;
200 }
201
202 free(a);
203}
204LCRYPTO_ALIAS(X509_OBJECT_free);
205
206static X509_OBJECT *
207x509_object_dup(const X509_OBJECT *obj)
208{
209 X509_OBJECT *copy;
210
211 if ((copy = X509_OBJECT_new()) == NULL) {
212 X509error(ERR_R_MALLOC_FAILURE);
213 return NULL;
214 }
215
216 copy->type = obj->type;
217 copy->data = obj->data;
218
219 X509_OBJECT_up_ref_count(copy);
220
221 return copy;
222}
223
224void
225X509_STORE_free(X509_STORE *store)
226{
227 if (store == NULL)
228 return;
229
230 if (CRYPTO_add(&store->references, -1, CRYPTO_LOCK_X509_STORE) > 0)
231 return;
232
233 sk_X509_LOOKUP_pop_free(store->get_cert_methods, X509_LOOKUP_free);
234 sk_X509_OBJECT_pop_free(store->objs, X509_OBJECT_free);
235
236 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, store, &store->ex_data);
237 X509_VERIFY_PARAM_free(store->param);
238 free(store);
239}
240LCRYPTO_ALIAS(X509_STORE_free);
241
242int
243X509_STORE_up_ref(X509_STORE *store)
244{
245 return CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE) > 1;
246}
247LCRYPTO_ALIAS(X509_STORE_up_ref);
248
249X509_LOOKUP *
250X509_STORE_add_lookup(X509_STORE *store, const X509_LOOKUP_METHOD *method)
251{
252 STACK_OF(X509_LOOKUP) *sk;
253 X509_LOOKUP *lu;
254 int i;
255
256 sk = store->get_cert_methods;
257 for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
258 lu = sk_X509_LOOKUP_value(sk, i);
259 if (method == lu->method) {
260 return lu;
261 }
262 }
263
264 if ((lu = X509_LOOKUP_new(method)) == NULL)
265 return NULL;
266
267 lu->store_ctx = store;
268 if (sk_X509_LOOKUP_push(store->get_cert_methods, lu) <= 0) {
269 X509error(ERR_R_MALLOC_FAILURE);
270 X509_LOOKUP_free(lu);
271 return NULL;
272 }
273
274 return lu;
275}
276LCRYPTO_ALIAS(X509_STORE_add_lookup);
277
278X509_OBJECT *
279X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type,
280 X509_NAME *name)
281{
282 X509_OBJECT *obj;
283
284 if ((obj = X509_OBJECT_new()) == NULL)
285 return NULL;
286 if (!X509_STORE_CTX_get_by_subject(vs, type, name, obj)) {
287 X509_OBJECT_free(obj);
288 return NULL;
289 }
290
291 return obj;
292}
293LCRYPTO_ALIAS(X509_STORE_CTX_get_obj_by_subject);
294
295int
296X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type,
297 X509_NAME *name, X509_OBJECT *ret)
298{
299 X509_STORE *ctx = vs->store;
300 X509_LOOKUP *lu;
301 X509_OBJECT stmp, *tmp;
302 int i;
303
304 if (ctx == NULL)
305 return 0;
306
307 memset(&stmp, 0, sizeof(stmp));
308
309 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
310 tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name);
311 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
312
313 if (tmp == NULL || type == X509_LU_CRL) {
314 for (i = 0; i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) {
315 lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i);
316 if (X509_LOOKUP_by_subject(lu, type, name, &stmp) != 0) {
317 tmp = &stmp;
318 break;
319 }
320 }
321 if (tmp == NULL)
322 return 0;
323 }
324
325 if (!X509_OBJECT_up_ref_count(tmp))
326 return 0;
327
328 *ret = *tmp;
329
330 return 1;
331}
332LCRYPTO_ALIAS(X509_STORE_CTX_get_by_subject);
333
334/* Add obj to the store. Takes ownership of obj. */
335static int
336X509_STORE_add_object(X509_STORE *store, X509_OBJECT *obj)
337{
338 int ret = 0;
339
340 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
341
342 if (X509_OBJECT_retrieve_match(store->objs, obj) != NULL) {
343 /* Object is already present in the store. That's fine. */
344 ret = 1;
345 goto out;
346 }
347
348 if (sk_X509_OBJECT_push(store->objs, obj) <= 0) {
349 X509error(ERR_R_MALLOC_FAILURE);
350 goto out;
351 }
352
353 obj = NULL;
354 ret = 1;
355
356 out:
357 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
358 X509_OBJECT_free(obj);
359
360 return ret;
361}
362
363int
364X509_STORE_add_cert(X509_STORE *store, X509 *x)
365{
366 X509_OBJECT *obj;
367
368 if (x == NULL)
369 return 0;
370
371 if ((obj = X509_OBJECT_new()) == NULL)
372 return 0;
373
374 if (!X509_up_ref(x)) {
375 X509_OBJECT_free(obj);
376 return 0;
377 }
378
379 obj->type = X509_LU_X509;
380 obj->data.x509 = x;
381
382 return X509_STORE_add_object(store, obj);
383}
384LCRYPTO_ALIAS(X509_STORE_add_cert);
385
386int
387X509_STORE_add_crl(X509_STORE *store, X509_CRL *x)
388{
389 X509_OBJECT *obj;
390
391 if (x == NULL)
392 return 0;
393
394 if ((obj = X509_OBJECT_new()) == NULL)
395 return 0;
396
397 if (!X509_CRL_up_ref(x)) {
398 X509_OBJECT_free(obj);
399 return 0;
400 }
401
402 obj->type = X509_LU_CRL;
403 obj->data.crl = x;
404
405 return X509_STORE_add_object(store, obj);
406}
407LCRYPTO_ALIAS(X509_STORE_add_crl);
408
409static int
410X509_OBJECT_up_ref_count(X509_OBJECT *a)
411{
412 switch (a->type) {
413 case X509_LU_X509:
414 return X509_up_ref(a->data.x509);
415 case X509_LU_CRL:
416 return X509_CRL_up_ref(a->data.crl);
417 }
418 return 1;
419}
420
421X509_LOOKUP_TYPE
422X509_OBJECT_get_type(const X509_OBJECT *a)
423{
424 return a->type;
425}
426LCRYPTO_ALIAS(X509_OBJECT_get_type);
427
428static int
429x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
430 X509_NAME *name, int *pnmatch)
431{
432 X509_OBJECT stmp;
433 X509 x509_s;
434 X509_CINF cinf_s;
435 X509_CRL crl_s;
436 X509_CRL_INFO crl_info_s;
437 int idx;
438
439 stmp.type = type;
440 switch (type) {
441 case X509_LU_X509:
442 stmp.data.x509 = &x509_s;
443 x509_s.cert_info = &cinf_s;
444 cinf_s.subject = name;
445 break;
446 case X509_LU_CRL:
447 stmp.data.crl = &crl_s;
448 crl_s.crl = &crl_info_s;
449 crl_info_s.issuer = name;
450 break;
451 default:
452 return -1;
453 }
454
455 idx = sk_X509_OBJECT_find(h, &stmp);
456 if (idx >= 0 && pnmatch) {
457 int tidx;
458 const X509_OBJECT *tobj, *pstmp;
459
460 *pnmatch = 1;
461 pstmp = &stmp;
462 for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++) {
463 tobj = sk_X509_OBJECT_value(h, tidx);
464 if (x509_object_cmp(&tobj, &pstmp))
465 break;
466 (*pnmatch)++;
467 }
468 }
469 return idx;
470}
471
472int
473X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
474 X509_NAME *name)
475{
476 return x509_object_idx_cnt(h, type, name, NULL);
477}
478LCRYPTO_ALIAS(X509_OBJECT_idx_by_subject);
479
480X509_OBJECT *
481X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
482 X509_NAME *name)
483{
484 int idx;
485
486 idx = X509_OBJECT_idx_by_subject(h, type, name);
487 if (idx == -1)
488 return NULL;
489 return sk_X509_OBJECT_value(h, idx);
490}
491LCRYPTO_ALIAS(X509_OBJECT_retrieve_by_subject);
492
493X509 *
494X509_OBJECT_get0_X509(const X509_OBJECT *xo)
495{
496 if (xo != NULL && xo->type == X509_LU_X509)
497 return xo->data.x509;
498 return NULL;
499}
500LCRYPTO_ALIAS(X509_OBJECT_get0_X509);
501
502X509_CRL *
503X509_OBJECT_get0_X509_CRL(X509_OBJECT *xo)
504{
505 if (xo != NULL && xo->type == X509_LU_CRL)
506 return xo->data.crl;
507 return NULL;
508}
509LCRYPTO_ALIAS(X509_OBJECT_get0_X509_CRL);
510
511static STACK_OF(X509) *
512X509_get1_certs_from_cache(X509_STORE *store, X509_NAME *name)
513{
514 STACK_OF(X509) *sk = NULL;
515 X509 *x = NULL;
516 X509_OBJECT *obj;
517 int i, idx, cnt;
518
519 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
520
521 idx = x509_object_idx_cnt(store->objs, X509_LU_X509, name, &cnt);
522 if (idx < 0)
523 goto err;
524
525 if ((sk = sk_X509_new_null()) == NULL)
526 goto err;
527
528 for (i = 0; i < cnt; i++, idx++) {
529 obj = sk_X509_OBJECT_value(store->objs, idx);
530
531 x = obj->data.x509;
532 if (!X509_up_ref(x)) {
533 x = NULL;
534 goto err;
535 }
536 if (!sk_X509_push(sk, x))
537 goto err;
538 }
539
540 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
541
542 return sk;
543
544 err:
545 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
546 sk_X509_pop_free(sk, X509_free);
547 X509_free(x);
548
549 return NULL;
550}
551
552STACK_OF(X509) *
553X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_NAME *name)
554{
555 X509_STORE *store = ctx->store;
556 STACK_OF(X509) *sk;
557 X509_OBJECT *obj;
558
559 if (store == NULL)
560 return NULL;
561
562 if ((sk = X509_get1_certs_from_cache(store, name)) != NULL)
563 return sk;
564
565 /* Nothing found: do lookup to possibly add new objects to cache. */
566 obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_X509, name);
567 if (obj == NULL)
568 return NULL;
569 X509_OBJECT_free(obj);
570
571 return X509_get1_certs_from_cache(store, name);
572}
573LCRYPTO_ALIAS(X509_STORE_CTX_get1_certs);
574
575STACK_OF(X509_CRL) *
576X509_STORE_CTX_get1_crls(X509_STORE_CTX *ctx, X509_NAME *name)
577{
578 X509_STORE *store = ctx->store;
579 STACK_OF(X509_CRL) *sk = NULL;
580 X509_CRL *x = NULL;
581 X509_OBJECT *obj = NULL;
582 int i, idx, cnt;
583
584 if (store == NULL)
585 return NULL;
586
587 /* Always do lookup to possibly add new CRLs to cache */
588 obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_CRL, name);
589 if (obj == NULL)
590 return NULL;
591
592 X509_OBJECT_free(obj);
593 obj = NULL;
594
595 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
596 idx = x509_object_idx_cnt(store->objs, X509_LU_CRL, name, &cnt);
597 if (idx < 0)
598 goto err;
599
600 if ((sk = sk_X509_CRL_new_null()) == NULL)
601 goto err;
602
603 for (i = 0; i < cnt; i++, idx++) {
604 obj = sk_X509_OBJECT_value(store->objs, idx);
605
606 x = obj->data.crl;
607 if (!X509_CRL_up_ref(x)) {
608 x = NULL;
609 goto err;
610 }
611 if (!sk_X509_CRL_push(sk, x))
612 goto err;
613 }
614
615 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
616 return sk;
617
618 err:
619 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
620 X509_CRL_free(x);
621 sk_X509_CRL_pop_free(sk, X509_CRL_free);
622 return NULL;
623}
624LCRYPTO_ALIAS(X509_STORE_CTX_get1_crls);
625
626X509_OBJECT *
627X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x)
628{
629 int idx, i;
630 X509_OBJECT *obj;
631
632 idx = sk_X509_OBJECT_find(h, x);
633 if (idx == -1)
634 return NULL;
635 if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
636 return sk_X509_OBJECT_value(h, idx);
637 for (i = idx; i < sk_X509_OBJECT_num(h); i++) {
638 obj = sk_X509_OBJECT_value(h, i);
639 if (x509_object_cmp((const X509_OBJECT **)&obj,
640 (const X509_OBJECT **)&x))
641 return NULL;
642 if (x->type == X509_LU_X509) {
643 if (!X509_cmp(obj->data.x509, x->data.x509))
644 return obj;
645 } else if (x->type == X509_LU_CRL) {
646 if (!X509_CRL_match(obj->data.crl, x->data.crl))
647 return obj;
648 } else
649 return obj;
650 }
651 return NULL;
652}
653LCRYPTO_ALIAS(X509_OBJECT_retrieve_match);
654
655/* Try to get issuer certificate from store. Due to limitations
656 * of the API this can only retrieve a single certificate matching
657 * a given subject name. However it will fill the cache with all
658 * matching certificates, so we can examine the cache for all
659 * matches.
660 *
661 * Return values are:
662 * 1 lookup successful.
663 * 0 certificate not found.
664 * -1 some other error.
665 */
666int
667X509_STORE_CTX_get1_issuer(X509 **out_issuer, X509_STORE_CTX *ctx, X509 *x)
668{
669 X509_NAME *xn;
670 X509_OBJECT *obj, *pobj;
671 X509 *issuer = NULL;
672 int i, idx, ret;
673
674 *out_issuer = NULL;
675
676 xn = X509_get_issuer_name(x);
677 obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_X509, xn);
678 if (obj == NULL)
679 return 0;
680
681 if ((issuer = X509_OBJECT_get0_X509(obj)) == NULL) {
682 X509_OBJECT_free(obj);
683 return 0;
684 }
685 if (!X509_up_ref(issuer)) {
686 X509_OBJECT_free(obj);
687 return -1;
688 }
689
690 /* If certificate matches all OK */
691 if (ctx->check_issued(ctx, x, issuer)) {
692 if (x509_check_cert_time(ctx, issuer, -1)) {
693 *out_issuer = issuer;
694 X509_OBJECT_free(obj);
695 return 1;
696 }
697 }
698 X509_free(issuer);
699 issuer = NULL;
700 X509_OBJECT_free(obj);
701 obj = NULL;
702
703 if (ctx->store == NULL)
704 return 0;
705
706 /* Else find index of first cert accepted by 'check_issued' */
707 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
708 idx = X509_OBJECT_idx_by_subject(ctx->store->objs, X509_LU_X509, xn);
709 if (idx != -1) /* should be true as we've had at least one match */ {
710 /* Look through all matching certs for suitable issuer */
711 for (i = idx; i < sk_X509_OBJECT_num(ctx->store->objs); i++) {
712 pobj = sk_X509_OBJECT_value(ctx->store->objs, i);
713 /* See if we've run past the matches */
714 if (pobj->type != X509_LU_X509)
715 break;
716 if (X509_NAME_cmp(xn,
717 X509_get_subject_name(pobj->data.x509)))
718 break;
719 if (ctx->check_issued(ctx, x, pobj->data.x509)) {
720 issuer = pobj->data.x509;
721 /*
722 * If times check, exit with match,
723 * otherwise keep looking. Leave last
724 * match in issuer so we return nearest
725 * match if no certificate time is OK.
726 */
727 if (x509_check_cert_time(ctx, issuer, -1))
728 break;
729 }
730 }
731 }
732 ret = 0;
733 if (issuer != NULL) {
734 if (!X509_up_ref(issuer)) {
735 ret = -1;
736 } else {
737 *out_issuer = issuer;
738 ret = 1;
739 }
740 }
741 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
742 return ret;
743}
744LCRYPTO_ALIAS(X509_STORE_CTX_get1_issuer);
745
746STACK_OF(X509_OBJECT) *
747X509_STORE_get0_objects(X509_STORE *xs)
748{
749 return xs->objs;
750}
751LCRYPTO_ALIAS(X509_STORE_get0_objects);
752
753static STACK_OF(X509_OBJECT) *
754sk_X509_OBJECT_deep_copy(const STACK_OF(X509_OBJECT) *objs)
755{
756 STACK_OF(X509_OBJECT) *copy = NULL;
757 X509_OBJECT *obj = NULL;
758 int i;
759
760 if ((copy = sk_X509_OBJECT_new(x509_object_cmp)) == NULL) {
761 X509error(ERR_R_MALLOC_FAILURE);
762 goto err;
763 }
764
765 for (i = 0; i < sk_X509_OBJECT_num(objs); i++) {
766 if ((obj = x509_object_dup(sk_X509_OBJECT_value(objs, i))) == NULL)
767 goto err;
768 if (!sk_X509_OBJECT_push(copy, obj))
769 goto err;
770 obj = NULL;
771 }
772
773 return copy;
774
775 err:
776 X509_OBJECT_free(obj);
777 sk_X509_OBJECT_pop_free(copy, X509_OBJECT_free);
778
779 return NULL;
780}
781
782STACK_OF(X509_OBJECT) *
783X509_STORE_get1_objects(X509_STORE *store)
784{
785 STACK_OF(X509_OBJECT) *objs;
786
787 if (store == NULL) {
788 X509error(ERR_R_PASSED_NULL_PARAMETER);
789 return NULL;
790 }
791
792 CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE);
793 objs = sk_X509_OBJECT_deep_copy(store->objs);
794 CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE);
795
796 return objs;
797}
798LCRYPTO_ALIAS(X509_STORE_get1_objects);
799
800void *
801X509_STORE_get_ex_data(X509_STORE *xs, int idx)
802{
803 return CRYPTO_get_ex_data(&xs->ex_data, idx);
804}
805LCRYPTO_ALIAS(X509_STORE_get_ex_data);
806
807int
808X509_STORE_set_ex_data(X509_STORE *xs, int idx, void *data)
809{
810 return CRYPTO_set_ex_data(&xs->ex_data, idx, data);
811}
812LCRYPTO_ALIAS(X509_STORE_set_ex_data);
813
814int
815X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
816{
817 return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
818}
819LCRYPTO_ALIAS(X509_STORE_set_flags);
820
821int
822X509_STORE_set_depth(X509_STORE *ctx, int depth)
823{
824 X509_VERIFY_PARAM_set_depth(ctx->param, depth);
825 return 1;
826}
827LCRYPTO_ALIAS(X509_STORE_set_depth);
828
829int
830X509_STORE_set_purpose(X509_STORE *ctx, int purpose)
831{
832 return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
833}
834LCRYPTO_ALIAS(X509_STORE_set_purpose);
835
836int
837X509_STORE_set_trust(X509_STORE *ctx, int trust)
838{
839 return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
840}
841LCRYPTO_ALIAS(X509_STORE_set_trust);
842
843int
844X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param)
845{
846 return X509_VERIFY_PARAM_set1(ctx->param, param);
847}
848LCRYPTO_ALIAS(X509_STORE_set1_param);
849
850X509_VERIFY_PARAM *
851X509_STORE_get0_param(X509_STORE *ctx)
852{
853 return ctx->param;
854}
855LCRYPTO_ALIAS(X509_STORE_get0_param);
856
857void
858X509_STORE_set_verify(X509_STORE *store, X509_STORE_CTX_verify_fn verify)
859{
860 store->verify = verify;
861}
862LCRYPTO_ALIAS(X509_STORE_set_verify);
863
864X509_STORE_CTX_verify_fn
865X509_STORE_get_verify(X509_STORE *store)
866{
867 return store->verify;
868}
869LCRYPTO_ALIAS(X509_STORE_get_verify);
870
871void
872X509_STORE_set_verify_cb(X509_STORE *store, X509_STORE_CTX_verify_cb verify_cb)
873{
874 store->verify_cb = verify_cb;
875}
876LCRYPTO_ALIAS(X509_STORE_set_verify_cb);
877
878X509_STORE_CTX_verify_cb
879X509_STORE_get_verify_cb(X509_STORE *store)
880{
881 return store->verify_cb;
882}
883LCRYPTO_ALIAS(X509_STORE_get_verify_cb);