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