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