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