]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/x509/x509_lu.c
Update the example in proxy_certificates.txt
[thirdparty/openssl.git] / crypto / x509 / x509_lu.c
CommitLineData
b1322259
RS
1/*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
d02b48c6 3 *
b1322259
RS
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
d02b48c6
RE
8 */
9
10#include <stdio.h>
b39fc560 11#include "internal/cryptlib.h"
ec577822
BM
12#include <openssl/lhash.h>
13#include <openssl/x509.h>
e3e57192 14#include "internal/x509_int.h"
926a56bf 15#include <openssl/x509v3.h>
0930251d 16#include "x509_lcl.h"
d02b48c6 17
6b691a5c 18X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method)
0f113f3e
MC
19{
20 X509_LOOKUP *ret;
21
64b25758 22 ret = OPENSSL_zalloc(sizeof(*ret));
0f113f3e
MC
23 if (ret == NULL)
24 return NULL;
25
0f113f3e 26 ret->method = method;
0f113f3e
MC
27 if ((method->new_item != NULL) && !method->new_item(ret)) {
28 OPENSSL_free(ret);
29 return NULL;
30 }
31 return ret;
32}
d02b48c6 33
6b691a5c 34void X509_LOOKUP_free(X509_LOOKUP *ctx)
0f113f3e
MC
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}
d02b48c6 42
3067095e
RL
43int X509_STORE_lock(X509_STORE *s)
44{
45 return CRYPTO_THREAD_write_lock(s->lock);
46}
47
48int X509_STORE_unlock(X509_STORE *s)
49{
50 return CRYPTO_THREAD_unlock(s->lock);
51}
52
6b691a5c 53int X509_LOOKUP_init(X509_LOOKUP *ctx)
0f113f3e
MC
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}
d02b48c6 62
6b691a5c 63int X509_LOOKUP_shutdown(X509_LOOKUP *ctx)
0f113f3e
MC
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}
d02b48c6 72
303c0028 73int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
0f113f3e
MC
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}
d02b48c6 83
6b691a5c 84int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
0f113f3e
MC
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}
d02b48c6 93
6b691a5c 94int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
0f113f3e
MC
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}
d02b48c6 101
6b691a5c 102int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
0f113f3e
MC
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}
d02b48c6 110
6b691a5c 111int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len,
0f113f3e
MC
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
119static 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}
d02b48c6 140
6b691a5c 141X509_STORE *X509_STORE_new(void)
0f113f3e
MC
142{
143 X509_STORE *ret;
144
64b25758 145 if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
0f113f3e 146 return NULL;
90945fa3
MC
147 if ((ret->objs = sk_X509_OBJECT_new(x509_object_cmp)) == NULL)
148 goto err;
0f113f3e 149 ret->cache = 1;
90945fa3
MC
150 if ((ret->get_cert_methods = sk_X509_LOOKUP_new_null()) == NULL)
151 goto err;
0f113f3e
MC
152
153 if ((ret->param = X509_VERIFY_PARAM_new()) == NULL)
90945fa3 154 goto err;
0f113f3e 155
90945fa3
MC
156 if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data))
157 goto err;
0f113f3e 158
c001ce33
AG
159 ret->lock = CRYPTO_THREAD_lock_new();
160 if (ret->lock == NULL)
161 goto err;
162
0f113f3e
MC
163 ret->references = 1;
164 return ret;
c001ce33 165
90945fa3
MC
166err:
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;
0f113f3e 172}
d02b48c6 173
6b691a5c 174static void cleanup(X509_OBJECT *a)
0f113f3e 175{
222561fe
RS
176 if (!a)
177 return;
0f113f3e
MC
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}
d02b48c6 188
6b691a5c 189void X509_STORE_free(X509_STORE *vfy)
0f113f3e
MC
190{
191 int i;
192 STACK_OF(X509_LOOKUP) *sk;
193 X509_LOOKUP *lu;
d02b48c6 194
0f113f3e
MC
195 if (vfy == NULL)
196 return;
e03ddfae 197
c001ce33 198 CRYPTO_atomic_add(&vfy->references, -1, &i, vfy->lock);
f3f1cf84 199 REF_PRINT_COUNT("X509_STORE", vfy);
0f113f3e
MC
200 if (i > 0)
201 return;
f3f1cf84 202 REF_ASSERT_ISNT(i < 0);
bff9ce4d 203
0f113f3e
MC
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);
222561fe 214 X509_VERIFY_PARAM_free(vfy->param);
c001ce33 215 CRYPTO_THREAD_lock_free(vfy->lock);
0f113f3e
MC
216 OPENSSL_free(vfy);
217}
d02b48c6 218
c001ce33
AG
219int 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
6b691a5c 231X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m)
0f113f3e
MC
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}
d02b48c6 258
6ddbb4cd
RS
259X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs, int type,
260 X509_NAME *name)
f0e0fd51 261{
6ddbb4cd 262 X509_OBJECT *ret = X509_OBJECT_new();
f0e0fd51 263
6ddbb4cd 264 if (ret == NULL)
f0e0fd51 265 return NULL;
6ddbb4cd
RS
266 if (!X509_STORE_CTX_get_by_subject(vs, type, name, ret)) {
267 X509_OBJECT_free(ret);
f0e0fd51
RS
268 return NULL;
269 }
270 return ret;
271}
272
6ddbb4cd
RS
273int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type,
274 X509_NAME *name, X509_OBJECT *ret)
0f113f3e
MC
275{
276 X509_STORE *ctx = vs->ctx;
277 X509_LOOKUP *lu;
278 X509_OBJECT stmp, *tmp;
279 int i, j;
280
c001ce33 281 CRYPTO_THREAD_write_lock(ctx->lock);
0f113f3e 282 tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name);
c001ce33 283 CRYPTO_THREAD_unlock(ctx->lock);
0f113f3e
MC
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
0f113f3e
MC
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}
d02b48c6 310
2f043896 311int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
0f113f3e
MC
312{
313 X509_OBJECT *obj;
68efafc5 314 int ret = 1, added = 1;
0f113f3e
MC
315
316 if (x == NULL)
317 return 0;
6ddbb4cd
RS
318 obj = X509_OBJECT_new();
319 if (obj == NULL)
0f113f3e 320 return 0;
0f113f3e
MC
321 obj->type = X509_LU_X509;
322 obj->data.x509 = x;
68efafc5 323 X509_OBJECT_up_ref_count(obj);
0f113f3e 324
c001ce33 325 CRYPTO_THREAD_write_lock(ctx->lock);
0f113f3e 326
0f113f3e 327 if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
0f113f3e
MC
328 X509err(X509_F_X509_STORE_ADD_CERT,
329 X509_R_CERT_ALREADY_IN_HASH_TABLE);
330 ret = 0;
68efafc5
F
331 } else {
332 added = sk_X509_OBJECT_push(ctx->objs, obj);
333 ret = added != 0;
334 }
0f113f3e 335
c001ce33 336 CRYPTO_THREAD_unlock(ctx->lock);
0f113f3e 337
68efafc5
F
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
0f113f3e
MC
343 return ret;
344}
2f043896
DSH
345
346int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
0f113f3e
MC
347{
348 X509_OBJECT *obj;
68efafc5 349 int ret = 1, added = 1;
0f113f3e
MC
350
351 if (x == NULL)
352 return 0;
6ddbb4cd
RS
353 obj = X509_OBJECT_new();
354 if (obj == NULL)
0f113f3e 355 return 0;
0f113f3e
MC
356 obj->type = X509_LU_CRL;
357 obj->data.crl = x;
68efafc5 358 X509_OBJECT_up_ref_count(obj);
0f113f3e 359
c001ce33 360 CRYPTO_THREAD_write_lock(ctx->lock);
0f113f3e 361
0f113f3e 362 if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
0f113f3e
MC
363 X509err(X509_F_X509_STORE_ADD_CRL, X509_R_CERT_ALREADY_IN_HASH_TABLE);
364 ret = 0;
68efafc5
F
365 } else {
366 added = sk_X509_OBJECT_push(ctx->objs, obj);
367 ret = added != 0;
368 }
0f113f3e 369
c001ce33 370 CRYPTO_THREAD_unlock(ctx->lock);
0f113f3e 371
68efafc5
F
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
0f113f3e
MC
377 return ret;
378}
2f043896 379
c5ebfcab 380int X509_OBJECT_up_ref_count(X509_OBJECT *a)
0f113f3e
MC
381{
382 switch (a->type) {
bca3f06b
RS
383 default:
384 break;
0f113f3e 385 case X509_LU_X509:
c5ebfcab 386 return X509_up_ref(a->data.x509);
0f113f3e 387 case X509_LU_CRL:
c5ebfcab 388 return X509_CRL_up_ref(a->data.crl);
0f113f3e 389 }
c5ebfcab 390 return 1;
0f113f3e 391}
d02b48c6 392
7d7da288 393X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a)
f0e0fd51 394{
6ddbb4cd
RS
395 if (a == NULL || a->type != X509_LU_X509)
396 return NULL;
f0e0fd51
RS
397 return a->data.x509;
398}
399
6ddbb4cd
RS
400X509_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
7d7da288 407int X509_OBJECT_get_type(const X509_OBJECT *a)
f0c58c32
CH
408{
409 return a->type;
410}
411
6ddbb4cd 412X509_OBJECT *X509_OBJECT_new()
f0e0fd51 413{
6ddbb4cd
RS
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;
f0e0fd51
RS
422}
423
6ddbb4cd
RS
424
425void X509_OBJECT_free(X509_OBJECT *a)
0f113f3e 426{
f0e0fd51 427 if (a == NULL)
222561fe 428 return;
0f113f3e 429 switch (a->type) {
bca3f06b
RS
430 default:
431 break;
0f113f3e
MC
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 }
6ddbb4cd 439 OPENSSL_free(a);
0f113f3e 440}
d02b48c6 441
4d50a2b4 442static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type,
0f113f3e
MC
443 X509_NAME *name, int *pnmatch)
444{
445 X509_OBJECT stmp;
446 X509 x509_s;
0f113f3e 447 X509_CRL crl_s;
0f113f3e
MC
448 int idx;
449
450 stmp.type = type;
451 switch (type) {
452 case X509_LU_X509:
453 stmp.data.x509 = &x509_s;
5cf6abd8 454 x509_s.cert_info.subject = name;
0f113f3e
MC
455 break;
456 case X509_LU_CRL:
457 stmp.data.crl = &crl_s;
7aef39a7 458 crl_s.crl.issuer = name;
0f113f3e
MC
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}
4d50a2b4
DSH
480
481int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
0f113f3e
MC
482 X509_NAME *name)
483{
484 return x509_object_idx_cnt(h, type, name, NULL);
485}
486
487X509_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}
11262391 496
f0c58c32
CH
497STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *v)
498{
499 return v->objs;
500}
501
6ddbb4cd 502STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
0f113f3e
MC
503{
504 int i, idx, cnt;
6ddbb4cd 505 STACK_OF(X509) *sk = NULL;
0f113f3e
MC
506 X509 *x;
507 X509_OBJECT *obj;
6ddbb4cd 508
c001ce33 509 CRYPTO_THREAD_write_lock(ctx->ctx->lock);
0f113f3e
MC
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 */
6ddbb4cd
RS
516 X509_OBJECT *xobj = X509_OBJECT_new();
517
c001ce33 518 CRYPTO_THREAD_unlock(ctx->ctx->lock);
6ddbb4cd
RS
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);
0f113f3e
MC
523 return NULL;
524 }
6ddbb4cd 525 X509_OBJECT_free(xobj);
c001ce33 526 CRYPTO_THREAD_write_lock(ctx->ctx->lock);
0f113f3e
MC
527 idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
528 if (idx < 0) {
c001ce33 529 CRYPTO_THREAD_unlock(ctx->ctx->lock);
0f113f3e
MC
530 return NULL;
531 }
532 }
6ddbb4cd
RS
533
534 sk = sk_X509_new_null();
0f113f3e
MC
535 for (i = 0; i < cnt; i++, idx++) {
536 obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
537 x = obj->data.x509;
05f0fb9f 538 X509_up_ref(x);
0f113f3e 539 if (!sk_X509_push(sk, x)) {
c001ce33 540 CRYPTO_THREAD_unlock(ctx->ctx->lock);
0f113f3e
MC
541 X509_free(x);
542 sk_X509_pop_free(sk, X509_free);
543 return NULL;
544 }
545 }
c001ce33 546 CRYPTO_THREAD_unlock(ctx->ctx->lock);
0f113f3e 547 return sk;
0f113f3e 548}
4d50a2b4 549
6ddbb4cd 550STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
0f113f3e
MC
551{
552 int i, idx, cnt;
6ddbb4cd 553 STACK_OF(X509_CRL) *sk = sk_X509_CRL_new_null();
0f113f3e 554 X509_CRL *x;
6ddbb4cd 555 X509_OBJECT *obj, *xobj = X509_OBJECT_new();
0f113f3e 556
6ddbb4cd
RS
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);
0f113f3e
MC
561 sk_X509_CRL_free(sk);
562 return NULL;
563 }
6ddbb4cd 564 X509_OBJECT_free(xobj);
c001ce33 565 CRYPTO_THREAD_write_lock(ctx->ctx->lock);
0f113f3e
MC
566 idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
567 if (idx < 0) {
c001ce33 568 CRYPTO_THREAD_unlock(ctx->ctx->lock);
0f113f3e
MC
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;
65cbf983 576 X509_CRL_up_ref(x);
0f113f3e 577 if (!sk_X509_CRL_push(sk, x)) {
c001ce33 578 CRYPTO_THREAD_unlock(ctx->ctx->lock);
0f113f3e
MC
579 X509_CRL_free(x);
580 sk_X509_CRL_pop_free(sk, X509_CRL_free);
581 return NULL;
582 }
583 }
c001ce33 584 CRYPTO_THREAD_unlock(ctx->ctx->lock);
0f113f3e
MC
585 return sk;
586}
587
588X509_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}
d02b48c6 614
1d97c843
TH
615/*-
616 * Try to get issuer certificate from store. Due to limitations
2f043896
DSH
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
a8397553 619 * matching certificates, so we can examine the cache for all
2f043896
DSH
620 * matches.
621 *
622 * Return values are:
623 * 1 lookup successful.
624 * 0 certificate not found.
625 * -1 some other error.
626 */
2f043896 627int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
0f113f3e
MC
628{
629 X509_NAME *xn;
6ddbb4cd 630 X509_OBJECT *obj = X509_OBJECT_new(), *pobj = NULL;
0f113f3e 631 int i, ok, idx, ret;
f0e0fd51 632
6ddbb4cd
RS
633 if (obj == NULL)
634 return -1;
0f113f3e
MC
635 *issuer = NULL;
636 xn = X509_get_issuer_name(x);
6ddbb4cd 637 ok = X509_STORE_CTX_get_by_subject(ctx, X509_LU_X509, xn, obj);
0f113f3e 638 if (ok != X509_LU_X509) {
6ddbb4cd 639 X509_OBJECT_free(obj);
0f113f3e 640 if (ok == X509_LU_RETRY) {
0f113f3e
MC
641 X509err(X509_F_X509_STORE_CTX_GET1_ISSUER, X509_R_SHOULD_RETRY);
642 return -1;
6ddbb4cd
RS
643 }
644 if (ok != X509_LU_FAIL) {
0f113f3e
MC
645 /* not good :-(, break anyway */
646 return -1;
647 }
648 return 0;
649 }
650 /* If certificate matches all OK */
6ddbb4cd
RS
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);
0f113f3e
MC
656 return 1;
657 }
658 }
6ddbb4cd 659 X509_OBJECT_free(obj);
0f113f3e
MC
660
661 /* Else find index of first cert accepted by 'check_issued' */
662 ret = 0;
c001ce33 663 CRYPTO_THREAD_write_lock(ctx->ctx->lock);
0f113f3e
MC
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
70dd3c65 685 if (x509_check_cert_time(ctx, *issuer, -1))
0f113f3e
MC
686 break;
687 }
688 }
689 }
c001ce33 690 CRYPTO_THREAD_unlock(ctx->ctx->lock);
0f113f3e 691 if (*issuer)
05f0fb9f 692 X509_up_ref(*issuer);
0f113f3e
MC
693 return ret;
694}
d02b48c6 695
5d7c222d 696int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
0f113f3e
MC
697{
698 return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
699}
5d7c222d
DSH
700
701int X509_STORE_set_depth(X509_STORE *ctx, int depth)
0f113f3e
MC
702{
703 X509_VERIFY_PARAM_set_depth(ctx->param, depth);
704 return 1;
705}
bdee69f7 706
926a56bf 707int X509_STORE_set_purpose(X509_STORE *ctx, int purpose)
0f113f3e
MC
708{
709 return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
710}
926a56bf
DSH
711
712int X509_STORE_set_trust(X509_STORE *ctx, int trust)
0f113f3e
MC
713{
714 return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
715}
5d7c222d
DSH
716
717int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param)
0f113f3e
MC
718{
719 return X509_VERIFY_PARAM_set1(ctx->param, param);
720}
926a56bf 721
f0c58c32
CH
722X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx)
723{
724 return ctx->param;
725}
726
1060a50b
RL
727void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify)
728{
729 ctx->verify = verify;
730}
731
732X509_STORE_CTX_verify_fn X509_STORE_get_verify(X509_STORE *ctx)
733{
734 return ctx->verify;
735}
736
a5b37fca 737void X509_STORE_set_verify_cb(X509_STORE *ctx,
1060a50b 738 X509_STORE_CTX_verify_cb verify_cb)
0f113f3e
MC
739{
740 ctx->verify_cb = verify_cb;
741}
a5b37fca 742
1060a50b 743X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(X509_STORE *ctx)
7cafbb4b 744{
1060a50b
RL
745 return ctx->verify_cb;
746}
747
748void 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
754X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(X509_STORE *ctx)
755{
756 return ctx->get_issuer;
757}
758
759void 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
765X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(X509_STORE *ctx)
766{
767 return ctx->check_issued;
768}
769
770void 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
776X509_STORE_CTX_check_revocation_fn X509_STORE_get_check_revocation(X509_STORE *ctx)
777{
778 return ctx->check_revocation;
779}
780
781void 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
787X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(X509_STORE *ctx)
788{
789 return ctx->get_crl;
790}
791
792void 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
798X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(X509_STORE *ctx)
799{
800 return ctx->check_crl;
801}
802
803void 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
809X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(X509_STORE *ctx)
810{
811 return ctx->cert_crl;
812}
813
0a5fe2eb
RL
814void 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
820X509_STORE_CTX_check_policy_fn X509_STORE_get_check_policy(X509_STORE *ctx)
821{
822 return ctx->check_policy;
823}
824
1060a50b
RL
825void 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
831X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(X509_STORE *ctx)
832{
833 return ctx->lookup_certs;
834}
835
836void 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
842X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(X509_STORE *ctx)
843{
844 return ctx->lookup_crls;
845}
846
847void X509_STORE_set_cleanup(X509_STORE *ctx,
848 X509_STORE_CTX_cleanup_fn ctx_cleanup)
849{
850 ctx->cleanup = ctx_cleanup;
7cafbb4b
MC
851}
852
1060a50b 853X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(X509_STORE *ctx)
0f113f3e 854{
1060a50b 855 return ctx->cleanup;
0f113f3e 856}
2c340864 857
3aec886e
KY
858int 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
863void *X509_STORE_get_ex_data(X509_STORE *ctx, int idx)
864{
865 return CRYPTO_get_ex_data(&ctx->ex_data, idx);
866}
867
2c340864 868X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx)
0f113f3e
MC
869{
870 return ctx->ctx;
871}