• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* crypto/x509/x509_lu.c */
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 #include <string.h>
59 
60 #include <openssl/err.h>
61 #include <openssl/mem.h>
62 #include <openssl/thread.h>
63 #include <openssl/x509.h>
64 #include <openssl/x509v3.h>
65 
66 #include "../internal.h"
67 
X509_LOOKUP_new(X509_LOOKUP_METHOD * method)68 X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method)
69 {
70     X509_LOOKUP *ret;
71 
72     ret = (X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP));
73     if (ret == NULL)
74         return NULL;
75 
76     ret->init = 0;
77     ret->skip = 0;
78     ret->method = method;
79     ret->method_data = NULL;
80     ret->store_ctx = NULL;
81     if ((method->new_item != NULL) && !method->new_item(ret)) {
82         OPENSSL_free(ret);
83         return NULL;
84     }
85     return ret;
86 }
87 
X509_LOOKUP_free(X509_LOOKUP * ctx)88 void X509_LOOKUP_free(X509_LOOKUP *ctx)
89 {
90     if (ctx == NULL)
91         return;
92     if ((ctx->method != NULL) && (ctx->method->free != NULL))
93         (*ctx->method->free) (ctx);
94     OPENSSL_free(ctx);
95 }
96 
X509_LOOKUP_init(X509_LOOKUP * ctx)97 int X509_LOOKUP_init(X509_LOOKUP *ctx)
98 {
99     if (ctx->method == NULL)
100         return 0;
101     if (ctx->method->init != NULL)
102         return ctx->method->init(ctx);
103     else
104         return 1;
105 }
106 
X509_LOOKUP_shutdown(X509_LOOKUP * ctx)107 int X509_LOOKUP_shutdown(X509_LOOKUP *ctx)
108 {
109     if (ctx->method == NULL)
110         return 0;
111     if (ctx->method->shutdown != NULL)
112         return ctx->method->shutdown(ctx);
113     else
114         return 1;
115 }
116 
X509_LOOKUP_ctrl(X509_LOOKUP * ctx,int cmd,const char * argc,long argl,char ** ret)117 int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
118                      char **ret)
119 {
120     if (ctx->method == NULL)
121         return -1;
122     if (ctx->method->ctrl != NULL)
123         return ctx->method->ctrl(ctx, cmd, argc, argl, ret);
124     else
125         return 1;
126 }
127 
X509_LOOKUP_by_subject(X509_LOOKUP * ctx,int type,X509_NAME * name,X509_OBJECT * ret)128 int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
129                            X509_OBJECT *ret)
130 {
131     if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL))
132         return 0;
133     if (ctx->skip)
134         return 0;
135     return ctx->method->get_by_subject(ctx, type, name, ret) > 0;
136 }
137 
X509_LOOKUP_by_issuer_serial(X509_LOOKUP * ctx,int type,X509_NAME * name,ASN1_INTEGER * serial,X509_OBJECT * ret)138 int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
139                                  ASN1_INTEGER *serial, X509_OBJECT *ret)
140 {
141     if ((ctx->method == NULL) || (ctx->method->get_by_issuer_serial == NULL))
142         return 0;
143     return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret) > 0;
144 }
145 
X509_LOOKUP_by_fingerprint(X509_LOOKUP * ctx,int type,unsigned char * bytes,int len,X509_OBJECT * ret)146 int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
147                                unsigned char *bytes, int len,
148                                X509_OBJECT *ret)
149 {
150     if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL))
151         return 0;
152     return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret) > 0;
153 }
154 
X509_LOOKUP_by_alias(X509_LOOKUP * ctx,int type,char * str,int len,X509_OBJECT * ret)155 int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len,
156                          X509_OBJECT *ret)
157 {
158     if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL))
159         return 0;
160     return ctx->method->get_by_alias(ctx, type, str, len, ret) > 0;
161 }
162 
x509_object_cmp(const X509_OBJECT ** a,const X509_OBJECT ** b)163 static int x509_object_cmp(const X509_OBJECT **a, const X509_OBJECT **b)
164 {
165     int ret;
166 
167     ret = ((*a)->type - (*b)->type);
168     if (ret)
169         return ret;
170     switch ((*a)->type) {
171     case X509_LU_X509:
172         ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509);
173         break;
174     case X509_LU_CRL:
175         ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl);
176         break;
177     default:
178         /* abort(); */
179         return 0;
180     }
181     return ret;
182 }
183 
X509_STORE_new(void)184 X509_STORE *X509_STORE_new(void)
185 {
186     X509_STORE *ret;
187 
188     if ((ret = (X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL)
189         return NULL;
190     OPENSSL_memset(ret, 0, sizeof(*ret));
191     CRYPTO_MUTEX_init(&ret->objs_lock);
192     ret->objs = sk_X509_OBJECT_new(x509_object_cmp);
193     if (ret->objs == NULL)
194         goto err;
195     ret->cache = 1;
196     ret->get_cert_methods = sk_X509_LOOKUP_new_null();
197     if (ret->get_cert_methods == NULL)
198         goto err;
199     ret->param = X509_VERIFY_PARAM_new();
200     if (ret->param == NULL)
201         goto err;
202 
203     ret->references = 1;
204     return ret;
205  err:
206     if (ret) {
207         CRYPTO_MUTEX_cleanup(&ret->objs_lock);
208         if (ret->param)
209             X509_VERIFY_PARAM_free(ret->param);
210         if (ret->get_cert_methods)
211             sk_X509_LOOKUP_free(ret->get_cert_methods);
212         if (ret->objs)
213             sk_X509_OBJECT_free(ret->objs);
214         OPENSSL_free(ret);
215     }
216     return NULL;
217 }
218 
X509_STORE_up_ref(X509_STORE * store)219 int X509_STORE_up_ref(X509_STORE *store)
220 {
221     CRYPTO_refcount_inc(&store->references);
222     return 1;
223 }
224 
cleanup(X509_OBJECT * a)225 static void cleanup(X509_OBJECT *a)
226 {
227     if (a == NULL) {
228         return;
229     }
230     if (a->type == X509_LU_X509) {
231         X509_free(a->data.x509);
232     } else if (a->type == X509_LU_CRL) {
233         X509_CRL_free(a->data.crl);
234     } else {
235         /* abort(); */
236     }
237 
238     OPENSSL_free(a);
239 }
240 
X509_STORE_free(X509_STORE * vfy)241 void X509_STORE_free(X509_STORE *vfy)
242 {
243     size_t j;
244     STACK_OF(X509_LOOKUP) *sk;
245     X509_LOOKUP *lu;
246 
247     if (vfy == NULL)
248         return;
249 
250     if (!CRYPTO_refcount_dec_and_test_zero(&vfy->references)) {
251         return;
252     }
253 
254     CRYPTO_MUTEX_cleanup(&vfy->objs_lock);
255 
256     sk = vfy->get_cert_methods;
257     for (j = 0; j < sk_X509_LOOKUP_num(sk); j++) {
258         lu = sk_X509_LOOKUP_value(sk, j);
259         X509_LOOKUP_shutdown(lu);
260         X509_LOOKUP_free(lu);
261     }
262     sk_X509_LOOKUP_free(sk);
263     sk_X509_OBJECT_pop_free(vfy->objs, cleanup);
264 
265     if (vfy->param)
266         X509_VERIFY_PARAM_free(vfy->param);
267     OPENSSL_free(vfy);
268 }
269 
X509_STORE_add_lookup(X509_STORE * v,X509_LOOKUP_METHOD * m)270 X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m)
271 {
272     size_t i;
273     STACK_OF(X509_LOOKUP) *sk;
274     X509_LOOKUP *lu;
275 
276     sk = v->get_cert_methods;
277     for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
278         lu = sk_X509_LOOKUP_value(sk, i);
279         if (m == lu->method) {
280             return lu;
281         }
282     }
283     /* a new one */
284     lu = X509_LOOKUP_new(m);
285     if (lu == NULL)
286         return NULL;
287     else {
288         lu->store_ctx = v;
289         if (sk_X509_LOOKUP_push(v->get_cert_methods, lu))
290             return lu;
291         else {
292             X509_LOOKUP_free(lu);
293             return NULL;
294         }
295     }
296 }
297 
X509_STORE_get_by_subject(X509_STORE_CTX * vs,int type,X509_NAME * name,X509_OBJECT * ret)298 int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
299                               X509_OBJECT *ret)
300 {
301     X509_STORE *ctx = vs->ctx;
302     X509_LOOKUP *lu;
303     X509_OBJECT stmp, *tmp;
304     int i;
305 
306     CRYPTO_MUTEX_lock_write(&ctx->objs_lock);
307     tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name);
308     CRYPTO_MUTEX_unlock_write(&ctx->objs_lock);
309 
310     if (tmp == NULL || type == X509_LU_CRL) {
311         for (i = 0; i < (int)sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) {
312             lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i);
313             if (X509_LOOKUP_by_subject(lu, type, name, &stmp)) {
314                 tmp = &stmp;
315                 break;
316             }
317         }
318         if (tmp == NULL)
319             return 0;
320     }
321 
322     /*
323      * if (ret->data.ptr != NULL) X509_OBJECT_free_contents(ret);
324      */
325 
326     ret->type = tmp->type;
327     ret->data.ptr = tmp->data.ptr;
328 
329     X509_OBJECT_up_ref_count(ret);
330 
331     return 1;
332 }
333 
X509_STORE_add_cert(X509_STORE * ctx,X509 * x)334 int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
335 {
336     X509_OBJECT *obj;
337     int ret = 1;
338 
339     if (x == NULL)
340         return 0;
341     obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
342     if (obj == NULL) {
343         OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
344         return 0;
345     }
346     obj->type = X509_LU_X509;
347     obj->data.x509 = x;
348 
349     CRYPTO_MUTEX_lock_write(&ctx->objs_lock);
350 
351     X509_OBJECT_up_ref_count(obj);
352 
353     if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
354         X509_OBJECT_free_contents(obj);
355         OPENSSL_free(obj);
356         OPENSSL_PUT_ERROR(X509, X509_R_CERT_ALREADY_IN_HASH_TABLE);
357         ret = 0;
358     } else if (!sk_X509_OBJECT_push(ctx->objs, obj)) {
359         X509_OBJECT_free_contents(obj);
360         OPENSSL_free(obj);
361         OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
362         ret = 0;
363     }
364 
365     CRYPTO_MUTEX_unlock_write(&ctx->objs_lock);
366 
367     return ret;
368 }
369 
X509_STORE_add_crl(X509_STORE * ctx,X509_CRL * x)370 int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
371 {
372     X509_OBJECT *obj;
373     int ret = 1;
374 
375     if (x == NULL)
376         return 0;
377     obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
378     if (obj == NULL) {
379         OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
380         return 0;
381     }
382     obj->type = X509_LU_CRL;
383     obj->data.crl = x;
384 
385     CRYPTO_MUTEX_lock_write(&ctx->objs_lock);
386 
387     X509_OBJECT_up_ref_count(obj);
388 
389     if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
390         X509_OBJECT_free_contents(obj);
391         OPENSSL_free(obj);
392         OPENSSL_PUT_ERROR(X509, X509_R_CERT_ALREADY_IN_HASH_TABLE);
393         ret = 0;
394     } else if (!sk_X509_OBJECT_push(ctx->objs, obj)) {
395         X509_OBJECT_free_contents(obj);
396         OPENSSL_free(obj);
397         OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
398         ret = 0;
399     }
400 
401     CRYPTO_MUTEX_unlock_write(&ctx->objs_lock);
402 
403     return ret;
404 }
405 
X509_STORE_set0_additional_untrusted(X509_STORE * ctx,STACK_OF (X509)* untrusted)406 void X509_STORE_set0_additional_untrusted(X509_STORE *ctx,
407                                           STACK_OF(X509) *untrusted) {
408   ctx->additional_untrusted = untrusted;
409 }
410 
X509_OBJECT_up_ref_count(X509_OBJECT * a)411 int X509_OBJECT_up_ref_count(X509_OBJECT *a)
412 {
413     switch (a->type) {
414     case X509_LU_X509:
415         X509_up_ref(a->data.x509);
416         break;
417     case X509_LU_CRL:
418         X509_CRL_up_ref(a->data.crl);
419         break;
420     }
421     return 1;
422 }
423 
X509_OBJECT_free_contents(X509_OBJECT * a)424 void X509_OBJECT_free_contents(X509_OBJECT *a)
425 {
426     switch (a->type) {
427     case X509_LU_X509:
428         X509_free(a->data.x509);
429         break;
430     case X509_LU_CRL:
431         X509_CRL_free(a->data.crl);
432         break;
433     }
434 }
435 
X509_OBJECT_get_type(const X509_OBJECT * a)436 int X509_OBJECT_get_type(const X509_OBJECT *a)
437 {
438     return a->type;
439 }
440 
X509_OBJECT_get0_X509(const X509_OBJECT * a)441 X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a)
442 {
443     if (a == NULL || a->type != X509_LU_X509) {
444         return NULL;
445     }
446     return a->data.x509;
447 }
448 
x509_object_idx_cnt(STACK_OF (X509_OBJECT)* h,int type,X509_NAME * name,int * pnmatch)449 static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type,
450                                X509_NAME *name, int *pnmatch)
451 {
452     X509_OBJECT stmp;
453     X509 x509_s;
454     X509_CINF cinf_s;
455     X509_CRL crl_s;
456     X509_CRL_INFO crl_info_s;
457 
458     stmp.type = type;
459     switch (type) {
460     case X509_LU_X509:
461         stmp.data.x509 = &x509_s;
462         x509_s.cert_info = &cinf_s;
463         cinf_s.subject = name;
464         break;
465     case X509_LU_CRL:
466         stmp.data.crl = &crl_s;
467         crl_s.crl = &crl_info_s;
468         crl_info_s.issuer = name;
469         break;
470     default:
471         /* abort(); */
472         return -1;
473     }
474 
475     size_t idx;
476     if (!sk_X509_OBJECT_find(h, &idx, &stmp))
477         return -1;
478 
479     if (pnmatch != NULL) {
480         int tidx;
481         const X509_OBJECT *tobj, *pstmp;
482         *pnmatch = 1;
483         pstmp = &stmp;
484         for (tidx = idx + 1; tidx < (int)sk_X509_OBJECT_num(h); tidx++) {
485             tobj = sk_X509_OBJECT_value(h, tidx);
486             if (x509_object_cmp(&tobj, &pstmp))
487                 break;
488             (*pnmatch)++;
489         }
490     }
491 
492     return idx;
493 }
494 
X509_OBJECT_idx_by_subject(STACK_OF (X509_OBJECT)* h,int type,X509_NAME * name)495 int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
496                                X509_NAME *name)
497 {
498     return x509_object_idx_cnt(h, type, name, NULL);
499 }
500 
X509_OBJECT_retrieve_by_subject(STACK_OF (X509_OBJECT)* h,int type,X509_NAME * name)501 X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
502                                              int type, X509_NAME *name)
503 {
504     int idx;
505     idx = X509_OBJECT_idx_by_subject(h, type, name);
506     if (idx == -1)
507         return NULL;
508     return sk_X509_OBJECT_value(h, idx);
509 }
510 
STACK_OF(X509_OBJECT)511 STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *st)
512 {
513     return st->objs;
514 }
515 
STACK_OF(X509)516 STACK_OF (X509) * X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
517 {
518     int i, idx, cnt;
519     STACK_OF(X509) *sk;
520     X509 *x;
521     X509_OBJECT *obj;
522     sk = sk_X509_new_null();
523     if (sk == NULL)
524         return NULL;
525     CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
526     idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
527     if (idx < 0) {
528         /*
529          * Nothing found in cache: do lookup to possibly add new objects to
530          * cache
531          */
532         X509_OBJECT xobj;
533         CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock);
534         if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) {
535             sk_X509_free(sk);
536             return NULL;
537         }
538         X509_OBJECT_free_contents(&xobj);
539         CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
540         idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
541         if (idx < 0) {
542             CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock);
543             sk_X509_free(sk);
544             return NULL;
545         }
546     }
547     for (i = 0; i < cnt; i++, idx++) {
548         obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
549         x = obj->data.x509;
550         if (!sk_X509_push(sk, x)) {
551             CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock);
552             sk_X509_pop_free(sk, X509_free);
553             return NULL;
554         }
555         X509_up_ref(x);
556     }
557     CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock);
558     return sk;
559 
560 }
561 
STACK_OF(X509_CRL)562 STACK_OF (X509_CRL) * X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
563 {
564     int i, idx, cnt;
565     STACK_OF(X509_CRL) *sk;
566     X509_CRL *x;
567     X509_OBJECT *obj, xobj;
568     sk = sk_X509_CRL_new_null();
569     if (sk == NULL)
570         return NULL;
571 
572     /* Always do lookup to possibly add new CRLs to cache. */
573     if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj)) {
574         sk_X509_CRL_free(sk);
575         return NULL;
576     }
577     X509_OBJECT_free_contents(&xobj);
578     CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
579     idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
580     if (idx < 0) {
581         CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock);
582         sk_X509_CRL_free(sk);
583         return NULL;
584     }
585 
586     for (i = 0; i < cnt; i++, idx++) {
587         obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
588         x = obj->data.crl;
589         X509_CRL_up_ref(x);
590         if (!sk_X509_CRL_push(sk, x)) {
591             CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock);
592             X509_CRL_free(x);
593             sk_X509_CRL_pop_free(sk, X509_CRL_free);
594             return NULL;
595         }
596     }
597     CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock);
598     return sk;
599 }
600 
X509_OBJECT_retrieve_match(STACK_OF (X509_OBJECT)* h,X509_OBJECT * x)601 X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
602                                         X509_OBJECT *x)
603 {
604     size_t idx, i;
605     X509_OBJECT *obj;
606 
607     if (!sk_X509_OBJECT_find(h, &idx, x)) {
608         return NULL;
609     }
610     if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
611         return sk_X509_OBJECT_value(h, idx);
612     for (i = idx; i < sk_X509_OBJECT_num(h); i++) {
613         obj = sk_X509_OBJECT_value(h, i);
614         if (x509_object_cmp
615             ((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x))
616             return NULL;
617         if (x->type == X509_LU_X509) {
618             if (!X509_cmp(obj->data.x509, x->data.x509))
619                 return obj;
620         } else if (x->type == X509_LU_CRL) {
621             if (!X509_CRL_match(obj->data.crl, x->data.crl))
622                 return obj;
623         } else
624             return obj;
625     }
626     return NULL;
627 }
628 
629 /*
630  * Try to get issuer certificate from store. Due to limitations of the API
631  * this can only retrieve a single certificate matching a given subject name.
632  * However it will fill the cache with all matching certificates, so we can
633  * examine the cache for all matches. Return values are: 1 lookup
634  * successful.  0 certificate not found. -1 some other error.
635  */
X509_STORE_CTX_get1_issuer(X509 ** issuer,X509_STORE_CTX * ctx,X509 * x)636 int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
637 {
638     X509_NAME *xn;
639     X509_OBJECT obj, *pobj;
640     int idx, ret;
641     size_t i;
642     xn = X509_get_issuer_name(x);
643     if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj))
644         return 0;
645     /* If certificate matches all OK */
646     if (ctx->check_issued(ctx, x, obj.data.x509)) {
647         *issuer = obj.data.x509;
648         return 1;
649     }
650     X509_OBJECT_free_contents(&obj);
651 
652     /* Else find index of first cert accepted by 'check_issued' */
653     ret = 0;
654     CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
655     idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
656     if (idx != -1) {            /* should be true as we've had at least one
657                                  * match */
658         /* Look through all matching certs for suitable issuer */
659         for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) {
660             pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i);
661             /* See if we've run past the matches */
662             if (pobj->type != X509_LU_X509)
663                 break;
664             if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509)))
665                 break;
666             if (ctx->check_issued(ctx, x, pobj->data.x509)) {
667                 *issuer = pobj->data.x509;
668                 X509_OBJECT_up_ref_count(pobj);
669                 ret = 1;
670                 break;
671             }
672         }
673     }
674     CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock);
675     return ret;
676 }
677 
X509_STORE_set_flags(X509_STORE * ctx,unsigned long flags)678 int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
679 {
680     return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
681 }
682 
X509_STORE_set_depth(X509_STORE * ctx,int depth)683 int X509_STORE_set_depth(X509_STORE *ctx, int depth)
684 {
685     X509_VERIFY_PARAM_set_depth(ctx->param, depth);
686     return 1;
687 }
688 
X509_STORE_set_purpose(X509_STORE * ctx,int purpose)689 int X509_STORE_set_purpose(X509_STORE *ctx, int purpose)
690 {
691     return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
692 }
693 
X509_STORE_set_trust(X509_STORE * ctx,int trust)694 int X509_STORE_set_trust(X509_STORE *ctx, int trust)
695 {
696     return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
697 }
698 
X509_STORE_set1_param(X509_STORE * ctx,X509_VERIFY_PARAM * param)699 int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param)
700 {
701     return X509_VERIFY_PARAM_set1(ctx->param, param);
702 }
703 
X509_STORE_get0_param(X509_STORE * ctx)704 X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx)
705 {
706     return ctx->param;
707 }
708 
X509_STORE_set_verify_cb(X509_STORE * ctx,int (* verify_cb)(int,X509_STORE_CTX *))709 void X509_STORE_set_verify_cb(X509_STORE *ctx,
710                               int (*verify_cb) (int, X509_STORE_CTX *))
711 {
712     ctx->verify_cb = verify_cb;
713 }
714 
X509_STORE_set_lookup_crls_cb(X509_STORE * ctx,STACK_OF (X509_CRL)* (* cb)(X509_STORE_CTX * ctx,X509_NAME * nm))715 void X509_STORE_set_lookup_crls_cb(X509_STORE *ctx,
716                                    STACK_OF (X509_CRL) *
717                                    (*cb) (X509_STORE_CTX *ctx, X509_NAME *nm))
718 {
719     ctx->lookup_crls = cb;
720 }
721 
X509_STORE_CTX_get0_store(X509_STORE_CTX * ctx)722 X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx)
723 {
724     return ctx->ctx;
725 }
726