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