• 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     sk_X509_OBJECT_sort(h);
477     if (!sk_X509_OBJECT_find(h, &idx, &stmp))
478         return -1;
479 
480     if (pnmatch != NULL) {
481         int tidx;
482         const X509_OBJECT *tobj, *pstmp;
483         *pnmatch = 1;
484         pstmp = &stmp;
485         for (tidx = idx + 1; tidx < (int)sk_X509_OBJECT_num(h); tidx++) {
486             tobj = sk_X509_OBJECT_value(h, tidx);
487             if (x509_object_cmp(&tobj, &pstmp))
488                 break;
489             (*pnmatch)++;
490         }
491     }
492 
493     return idx;
494 }
495 
X509_OBJECT_idx_by_subject(STACK_OF (X509_OBJECT)* h,int type,X509_NAME * name)496 int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
497                                X509_NAME *name)
498 {
499     return x509_object_idx_cnt(h, type, name, NULL);
500 }
501 
X509_OBJECT_retrieve_by_subject(STACK_OF (X509_OBJECT)* h,int type,X509_NAME * name)502 X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
503                                              int type, X509_NAME *name)
504 {
505     int idx;
506     idx = X509_OBJECT_idx_by_subject(h, type, name);
507     if (idx == -1)
508         return NULL;
509     return sk_X509_OBJECT_value(h, idx);
510 }
511 
STACK_OF(X509_OBJECT)512 STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *st)
513 {
514     return st->objs;
515 }
516 
STACK_OF(X509)517 STACK_OF (X509) * X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
518 {
519     int i, idx, cnt;
520     STACK_OF(X509) *sk;
521     X509 *x;
522     X509_OBJECT *obj;
523     sk = sk_X509_new_null();
524     if (sk == NULL)
525         return NULL;
526     CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
527     idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
528     if (idx < 0) {
529         /*
530          * Nothing found in cache: do lookup to possibly add new objects to
531          * cache
532          */
533         X509_OBJECT xobj;
534         CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock);
535         if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) {
536             sk_X509_free(sk);
537             return NULL;
538         }
539         X509_OBJECT_free_contents(&xobj);
540         CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
541         idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
542         if (idx < 0) {
543             CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock);
544             sk_X509_free(sk);
545             return NULL;
546         }
547     }
548     for (i = 0; i < cnt; i++, idx++) {
549         obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
550         x = obj->data.x509;
551         if (!sk_X509_push(sk, x)) {
552             CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock);
553             sk_X509_pop_free(sk, X509_free);
554             return NULL;
555         }
556         X509_up_ref(x);
557     }
558     CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock);
559     return sk;
560 
561 }
562 
STACK_OF(X509_CRL)563 STACK_OF (X509_CRL) * X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
564 {
565     int i, idx, cnt;
566     STACK_OF(X509_CRL) *sk;
567     X509_CRL *x;
568     X509_OBJECT *obj, xobj;
569     sk = sk_X509_CRL_new_null();
570     if (sk == NULL)
571         return NULL;
572 
573     /* Always do lookup to possibly add new CRLs to cache. */
574     if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj)) {
575         sk_X509_CRL_free(sk);
576         return NULL;
577     }
578     X509_OBJECT_free_contents(&xobj);
579     CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
580     idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
581     if (idx < 0) {
582         CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock);
583         sk_X509_CRL_free(sk);
584         return NULL;
585     }
586 
587     for (i = 0; i < cnt; i++, idx++) {
588         obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
589         x = obj->data.crl;
590         X509_CRL_up_ref(x);
591         if (!sk_X509_CRL_push(sk, x)) {
592             CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock);
593             X509_CRL_free(x);
594             sk_X509_CRL_pop_free(sk, X509_CRL_free);
595             return NULL;
596         }
597     }
598     CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock);
599     return sk;
600 }
601 
X509_OBJECT_retrieve_match(STACK_OF (X509_OBJECT)* h,X509_OBJECT * x)602 X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
603                                         X509_OBJECT *x)
604 {
605     size_t idx, i;
606     X509_OBJECT *obj;
607 
608     sk_X509_OBJECT_sort(h);
609     if (!sk_X509_OBJECT_find(h, &idx, x)) {
610         return NULL;
611     }
612     if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
613         return sk_X509_OBJECT_value(h, idx);
614     for (i = idx; i < sk_X509_OBJECT_num(h); i++) {
615         obj = sk_X509_OBJECT_value(h, i);
616         if (x509_object_cmp
617             ((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x))
618             return NULL;
619         if (x->type == X509_LU_X509) {
620             if (!X509_cmp(obj->data.x509, x->data.x509))
621                 return obj;
622         } else if (x->type == X509_LU_CRL) {
623             if (!X509_CRL_match(obj->data.crl, x->data.crl))
624                 return obj;
625         } else
626             return obj;
627     }
628     return NULL;
629 }
630 
631 /*
632  * Try to get issuer certificate from store. Due to limitations of the API
633  * this can only retrieve a single certificate matching a given subject name.
634  * However it will fill the cache with all matching certificates, so we can
635  * examine the cache for all matches. Return values are: 1 lookup
636  * successful.  0 certificate not found. -1 some other error.
637  */
X509_STORE_CTX_get1_issuer(X509 ** issuer,X509_STORE_CTX * ctx,X509 * x)638 int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
639 {
640     X509_NAME *xn;
641     X509_OBJECT obj, *pobj;
642     int idx, ret;
643     size_t i;
644     xn = X509_get_issuer_name(x);
645     if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj))
646         return 0;
647     /* If certificate matches all OK */
648     if (ctx->check_issued(ctx, x, obj.data.x509)) {
649         *issuer = obj.data.x509;
650         return 1;
651     }
652     X509_OBJECT_free_contents(&obj);
653 
654     /* Else find index of first cert accepted by 'check_issued' */
655     ret = 0;
656     CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
657     idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
658     if (idx != -1) {            /* should be true as we've had at least one
659                                  * match */
660         /* Look through all matching certs for suitable issuer */
661         for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) {
662             pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i);
663             /* See if we've run past the matches */
664             if (pobj->type != X509_LU_X509)
665                 break;
666             if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509)))
667                 break;
668             if (ctx->check_issued(ctx, x, pobj->data.x509)) {
669                 *issuer = pobj->data.x509;
670                 X509_OBJECT_up_ref_count(pobj);
671                 ret = 1;
672                 break;
673             }
674         }
675     }
676     CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock);
677     return ret;
678 }
679 
X509_STORE_set_flags(X509_STORE * ctx,unsigned long flags)680 int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
681 {
682     return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
683 }
684 
X509_STORE_set_depth(X509_STORE * ctx,int depth)685 int X509_STORE_set_depth(X509_STORE *ctx, int depth)
686 {
687     X509_VERIFY_PARAM_set_depth(ctx->param, depth);
688     return 1;
689 }
690 
X509_STORE_set_purpose(X509_STORE * ctx,int purpose)691 int X509_STORE_set_purpose(X509_STORE *ctx, int purpose)
692 {
693     return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
694 }
695 
X509_STORE_set_trust(X509_STORE * ctx,int trust)696 int X509_STORE_set_trust(X509_STORE *ctx, int trust)
697 {
698     return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
699 }
700 
X509_STORE_set1_param(X509_STORE * ctx,X509_VERIFY_PARAM * param)701 int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param)
702 {
703     return X509_VERIFY_PARAM_set1(ctx->param, param);
704 }
705 
X509_STORE_get0_param(X509_STORE * ctx)706 X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx)
707 {
708     return ctx->param;
709 }
710 
X509_STORE_set_verify(X509_STORE * ctx,X509_STORE_CTX_verify_fn verify)711 void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify)
712 {
713     ctx->verify = verify;
714 }
715 
X509_STORE_get_verify(X509_STORE * ctx)716 X509_STORE_CTX_verify_fn X509_STORE_get_verify(X509_STORE *ctx)
717 {
718     return ctx->verify;
719 }
720 
X509_STORE_set_verify_cb(X509_STORE * ctx,X509_STORE_CTX_verify_cb verify_cb)721 void X509_STORE_set_verify_cb(X509_STORE *ctx,
722                               X509_STORE_CTX_verify_cb verify_cb)
723 {
724     ctx->verify_cb = verify_cb;
725 }
726 
X509_STORE_get_verify_cb(X509_STORE * ctx)727 X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(X509_STORE *ctx)
728 {
729     return ctx->verify_cb;
730 }
731 
X509_STORE_set_get_issuer(X509_STORE * ctx,X509_STORE_CTX_get_issuer_fn get_issuer)732 void X509_STORE_set_get_issuer(X509_STORE *ctx,
733                                X509_STORE_CTX_get_issuer_fn get_issuer)
734 {
735     ctx->get_issuer = get_issuer;
736 }
737 
X509_STORE_get_get_issuer(X509_STORE * ctx)738 X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(X509_STORE *ctx)
739 {
740     return ctx->get_issuer;
741 }
742 
X509_STORE_set_check_issued(X509_STORE * ctx,X509_STORE_CTX_check_issued_fn check_issued)743 void X509_STORE_set_check_issued(X509_STORE *ctx,
744                                  X509_STORE_CTX_check_issued_fn check_issued)
745 {
746     ctx->check_issued = check_issued;
747 }
748 
X509_STORE_get_check_issued(X509_STORE * ctx)749 X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(X509_STORE *ctx)
750 {
751     return ctx->check_issued;
752 }
753 
X509_STORE_set_check_revocation(X509_STORE * ctx,X509_STORE_CTX_check_revocation_fn check_revocation)754 void X509_STORE_set_check_revocation(X509_STORE *ctx,
755                                      X509_STORE_CTX_check_revocation_fn check_revocation)
756 {
757     ctx->check_revocation = check_revocation;
758 }
759 
X509_STORE_get_check_revocation(X509_STORE * ctx)760 X509_STORE_CTX_check_revocation_fn X509_STORE_get_check_revocation(X509_STORE *ctx)
761 {
762     return ctx->check_revocation;
763 }
764 
X509_STORE_set_get_crl(X509_STORE * ctx,X509_STORE_CTX_get_crl_fn get_crl)765 void X509_STORE_set_get_crl(X509_STORE *ctx,
766                             X509_STORE_CTX_get_crl_fn get_crl)
767 {
768     ctx->get_crl = get_crl;
769 }
770 
X509_STORE_get_get_crl(X509_STORE * ctx)771 X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(X509_STORE *ctx)
772 {
773     return ctx->get_crl;
774 }
775 
X509_STORE_set_check_crl(X509_STORE * ctx,X509_STORE_CTX_check_crl_fn check_crl)776 void X509_STORE_set_check_crl(X509_STORE *ctx,
777                               X509_STORE_CTX_check_crl_fn check_crl)
778 {
779     ctx->check_crl = check_crl;
780 }
781 
X509_STORE_get_check_crl(X509_STORE * ctx)782 X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(X509_STORE *ctx)
783 {
784     return ctx->check_crl;
785 }
786 
X509_STORE_set_cert_crl(X509_STORE * ctx,X509_STORE_CTX_cert_crl_fn cert_crl)787 void X509_STORE_set_cert_crl(X509_STORE *ctx,
788                              X509_STORE_CTX_cert_crl_fn cert_crl)
789 {
790     ctx->cert_crl = cert_crl;
791 }
792 
X509_STORE_get_cert_crl(X509_STORE * ctx)793 X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(X509_STORE *ctx)
794 {
795     return ctx->cert_crl;
796 }
797 
X509_STORE_set_lookup_certs(X509_STORE * ctx,X509_STORE_CTX_lookup_certs_fn lookup_certs)798 void X509_STORE_set_lookup_certs(X509_STORE *ctx,
799                                  X509_STORE_CTX_lookup_certs_fn lookup_certs)
800 {
801     ctx->lookup_certs = lookup_certs;
802 }
803 
X509_STORE_get_lookup_certs(X509_STORE * ctx)804 X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(X509_STORE *ctx)
805 {
806     return ctx->lookup_certs;
807 }
808 
X509_STORE_set_lookup_crls(X509_STORE * ctx,X509_STORE_CTX_lookup_crls_fn lookup_crls)809 void X509_STORE_set_lookup_crls(X509_STORE *ctx,
810                                 X509_STORE_CTX_lookup_crls_fn lookup_crls)
811 {
812     ctx->lookup_crls = lookup_crls;
813 }
814 
X509_STORE_get_lookup_crls(X509_STORE * ctx)815 X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(X509_STORE *ctx)
816 {
817     return ctx->lookup_crls;
818 }
819 
X509_STORE_set_cleanup(X509_STORE * ctx,X509_STORE_CTX_cleanup_fn ctx_cleanup)820 void X509_STORE_set_cleanup(X509_STORE *ctx,
821                             X509_STORE_CTX_cleanup_fn ctx_cleanup)
822 {
823     ctx->cleanup = ctx_cleanup;
824 }
825 
X509_STORE_get_cleanup(X509_STORE * ctx)826 X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(X509_STORE *ctx)
827 {
828     return ctx->cleanup;
829 }
830 
X509_STORE_CTX_get0_store(X509_STORE_CTX * ctx)831 X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx)
832 {
833     return ctx->ctx;
834 }
835