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