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