GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/x509/x509_lu.c Lines: 159 358 44.4 %
Date: 2017-11-07 Branches: 53 187 28.3 %

Line Branch Exec Source
1
/* $OpenBSD: x509_lu.c,v 1.23 2017/01/29 17:49:23 beck 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
67
static void X509_OBJECT_dec_ref_count(X509_OBJECT *a);
68
/* static void X509_OBJECT_up_ref_count(X509_OBJECT *a); */
69
70
X509_LOOKUP *
71
X509_LOOKUP_new(X509_LOOKUP_METHOD *method)
72
{
73
	X509_LOOKUP *ret;
74
75
724
	ret = malloc(sizeof(X509_LOOKUP));
76
362
	if (ret == NULL)
77
		return NULL;
78
79
362
	ret->init = 0;
80
362
	ret->skip = 0;
81
362
	ret->method = method;
82
362
	ret->method_data = NULL;
83
362
	ret->store_ctx = NULL;
84

480
	if ((method->new_item != NULL) && !method->new_item(ret)) {
85
		free(ret);
86
		return NULL;
87
	}
88
362
	return ret;
89
362
}
90
91
void
92
X509_LOOKUP_free(X509_LOOKUP *ctx)
93
{
94
724
	if (ctx == NULL)
95
		return;
96

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