Coverage Report

Created: 2025-06-13 06:58

/src/openssl31/crypto/x509/x509_lu.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License 2.0 (the "License").  You may not use
5
 * this file except in compliance with the License.  You can obtain a copy
6
 * in the file LICENSE in the source distribution or at
7
 * https://www.openssl.org/source/license.html
8
 */
9
10
#include <stdio.h>
11
#include "internal/cryptlib.h"
12
#include "internal/refcount.h"
13
#include <openssl/x509.h>
14
#include "crypto/x509.h"
15
#include <openssl/x509v3.h>
16
#include "x509_local.h"
17
18
X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method)
19
0
{
20
0
    X509_LOOKUP *ret = OPENSSL_zalloc(sizeof(*ret));
21
22
0
    if (ret == NULL) {
23
0
        ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
24
0
        return NULL;
25
0
    }
26
27
0
    ret->method = method;
28
0
    if (method->new_item != NULL && method->new_item(ret) == 0) {
29
0
        OPENSSL_free(ret);
30
0
        return NULL;
31
0
    }
32
0
    return ret;
33
0
}
34
35
void X509_LOOKUP_free(X509_LOOKUP *ctx)
36
0
{
37
0
    if (ctx == NULL)
38
0
        return;
39
0
    if ((ctx->method != NULL) && (ctx->method->free != NULL))
40
0
        (*ctx->method->free) (ctx);
41
0
    OPENSSL_free(ctx);
42
0
}
43
44
int X509_STORE_lock(X509_STORE *xs)
45
50.4k
{
46
50.4k
    return CRYPTO_THREAD_write_lock(xs->lock);
47
50.4k
}
48
49
static int x509_store_read_lock(X509_STORE *xs)
50
44.4k
{
51
44.4k
    return CRYPTO_THREAD_read_lock(xs->lock);
52
44.4k
}
53
54
int X509_STORE_unlock(X509_STORE *xs)
55
94.9k
{
56
94.9k
    return CRYPTO_THREAD_unlock(xs->lock);
57
94.9k
}
58
59
int X509_LOOKUP_init(X509_LOOKUP *ctx)
60
0
{
61
0
    if (ctx->method == NULL)
62
0
        return 0;
63
0
    if (ctx->method->init != NULL)
64
0
        return ctx->method->init(ctx);
65
0
    else
66
0
        return 1;
67
0
}
68
69
int X509_LOOKUP_shutdown(X509_LOOKUP *ctx)
70
0
{
71
0
    if (ctx->method == NULL)
72
0
        return 0;
73
0
    if (ctx->method->shutdown != NULL)
74
0
        return ctx->method->shutdown(ctx);
75
0
    else
76
0
        return 1;
77
0
}
78
79
int X509_LOOKUP_ctrl_ex(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
80
                        char **ret, OSSL_LIB_CTX *libctx, const char *propq)
81
0
{
82
0
    if (ctx->method == NULL)
83
0
        return -1;
84
0
    if (ctx->method->ctrl_ex != NULL)
85
0
        return ctx->method->ctrl_ex(ctx, cmd, argc, argl, ret, libctx, propq);
86
0
    if (ctx->method->ctrl != NULL)
87
0
        return ctx->method->ctrl(ctx, cmd, argc, argl, ret);
88
0
    return 1;
89
0
}
90
91
int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
92
                     char **ret)
93
0
{
94
0
    return X509_LOOKUP_ctrl_ex(ctx, cmd, argc, argl, ret, NULL, NULL);
95
0
}
96
97
int X509_LOOKUP_by_subject_ex(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
98
                              const X509_NAME *name, X509_OBJECT *ret,
99
                              OSSL_LIB_CTX *libctx, const char *propq)
100
0
{
101
0
    if (ctx->skip
102
0
        || ctx->method == NULL
103
0
        || (ctx->method->get_by_subject == NULL
104
0
            && ctx->method->get_by_subject_ex == NULL))
105
0
        return 0;
106
0
    if (ctx->method->get_by_subject_ex != NULL)
107
0
        return ctx->method->get_by_subject_ex(ctx, type, name, ret, libctx,
108
0
                                              propq);
109
0
    else
110
0
        return ctx->method->get_by_subject(ctx, type, name, ret);
111
0
}
112
113
int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
114
                           const X509_NAME *name, X509_OBJECT *ret)
115
0
{
116
0
    return X509_LOOKUP_by_subject_ex(ctx, type, name, ret, NULL, NULL);
117
0
}
118
119
int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
120
                                 const X509_NAME *name,
121
                                 const ASN1_INTEGER *serial,
122
                                 X509_OBJECT *ret)
123
0
{
124
0
    if ((ctx->method == NULL) || (ctx->method->get_by_issuer_serial == NULL))
125
0
        return 0;
126
0
    return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret);
127
0
}
128
129
int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
130
                               const unsigned char *bytes, int len,
131
                               X509_OBJECT *ret)
132
0
{
133
0
    if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL))
134
0
        return 0;
135
0
    return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret);
136
0
}
137
138
int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
139
                         const char *str, int len, X509_OBJECT *ret)
140
0
{
141
0
    if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL))
142
0
        return 0;
143
0
    return ctx->method->get_by_alias(ctx, type, str, len, ret);
144
0
}
145
146
int X509_LOOKUP_set_method_data(X509_LOOKUP *ctx, void *data)
147
0
{
148
0
    ctx->method_data = data;
149
0
    return 1;
150
0
}
151
152
void *X509_LOOKUP_get_method_data(const X509_LOOKUP *ctx)
153
0
{
154
0
    return ctx->method_data;
155
0
}
156
157
X509_STORE *X509_LOOKUP_get_store(const X509_LOOKUP *ctx)
158
0
{
159
0
    return ctx->store_ctx;
160
0
}
161
162
163
static int x509_object_cmp(const X509_OBJECT *const *a,
164
                           const X509_OBJECT *const *b)
165
23.1k
{
166
23.1k
    int ret;
167
168
23.1k
    ret = ((*a)->type - (*b)->type);
169
23.1k
    if (ret)
170
1.64k
        return ret;
171
21.4k
    switch ((*a)->type) {
172
21.4k
    case X509_LU_X509:
173
21.4k
        ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509);
174
21.4k
        break;
175
0
    case X509_LU_CRL:
176
0
        ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl);
177
0
        break;
178
0
    case X509_LU_NONE:
179
        /* abort(); */
180
0
        return 0;
181
21.4k
    }
182
21.4k
    return ret;
183
21.4k
}
184
185
X509_STORE *X509_STORE_new(void)
186
28.1k
{
187
28.1k
    X509_STORE *ret = OPENSSL_zalloc(sizeof(*ret));
188
189
28.1k
    if (ret == NULL) {
190
0
        ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
191
0
        return NULL;
192
0
    }
193
28.1k
    if ((ret->objs = sk_X509_OBJECT_new(x509_object_cmp)) == NULL) {
194
0
        ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
195
0
        goto err;
196
0
    }
197
28.1k
    ret->cache = 1;
198
28.1k
    if ((ret->get_cert_methods = sk_X509_LOOKUP_new_null()) == NULL) {
199
0
        ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
200
0
        goto err;
201
0
    }
202
203
28.1k
    if ((ret->param = X509_VERIFY_PARAM_new()) == NULL) {
204
0
        ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
205
0
        goto err;
206
0
    }
207
28.1k
    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data)) {
208
0
        ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
209
0
        goto err;
210
0
    }
211
212
28.1k
    ret->lock = CRYPTO_THREAD_lock_new();
213
28.1k
    if (ret->lock == NULL) {
214
0
        ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
215
0
        goto err;
216
0
    }
217
28.1k
    ret->references = 1;
218
28.1k
    return ret;
219
220
0
err:
221
0
    X509_VERIFY_PARAM_free(ret->param);
222
0
    sk_X509_OBJECT_free(ret->objs);
223
0
    sk_X509_LOOKUP_free(ret->get_cert_methods);
224
0
    OPENSSL_free(ret);
225
0
    return NULL;
226
28.1k
}
227
228
void X509_STORE_free(X509_STORE *vfy)
229
504k
{
230
504k
    int i;
231
504k
    STACK_OF(X509_LOOKUP) *sk;
232
504k
    X509_LOOKUP *lu;
233
234
504k
    if (vfy == NULL)
235
418k
        return;
236
85.9k
    CRYPTO_DOWN_REF(&vfy->references, &i, vfy->lock);
237
85.9k
    REF_PRINT_COUNT("X509_STORE", vfy);
238
85.9k
    if (i > 0)
239
0
        return;
240
85.9k
    REF_ASSERT_ISNT(i < 0);
241
242
85.9k
    sk = vfy->get_cert_methods;
243
85.9k
    for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
244
0
        lu = sk_X509_LOOKUP_value(sk, i);
245
0
        X509_LOOKUP_shutdown(lu);
246
0
        X509_LOOKUP_free(lu);
247
0
    }
248
85.9k
    sk_X509_LOOKUP_free(sk);
249
85.9k
    sk_X509_OBJECT_pop_free(vfy->objs, X509_OBJECT_free);
250
251
85.9k
    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data);
252
85.9k
    X509_VERIFY_PARAM_free(vfy->param);
253
85.9k
    CRYPTO_THREAD_lock_free(vfy->lock);
254
85.9k
    OPENSSL_free(vfy);
255
85.9k
}
256
257
int X509_STORE_up_ref(X509_STORE *vfy)
258
0
{
259
0
    int i;
260
261
0
    if (CRYPTO_UP_REF(&vfy->references, &i, vfy->lock) <= 0)
262
0
        return 0;
263
264
0
    REF_PRINT_COUNT("X509_STORE", vfy);
265
0
    REF_ASSERT_ISNT(i < 2);
266
0
    return ((i > 1) ? 1 : 0);
267
0
}
268
269
X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m)
270
0
{
271
0
    int i;
272
0
    STACK_OF(X509_LOOKUP) *sk;
273
0
    X509_LOOKUP *lu;
274
275
0
    sk = v->get_cert_methods;
276
0
    for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
277
0
        lu = sk_X509_LOOKUP_value(sk, i);
278
0
        if (m == lu->method) {
279
0
            return lu;
280
0
        }
281
0
    }
282
    /* a new one */
283
0
    lu = X509_LOOKUP_new(m);
284
0
    if (lu == NULL) {
285
0
        ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
286
0
        return NULL;
287
0
    }
288
289
0
    lu->store_ctx = v;
290
0
    if (sk_X509_LOOKUP_push(v->get_cert_methods, lu))
291
0
        return lu;
292
    /* malloc failed */
293
0
    ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
294
0
    X509_LOOKUP_free(lu);
295
0
    return NULL;
296
0
}
297
298
X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs,
299
                                               X509_LOOKUP_TYPE type,
300
                                               const X509_NAME *name)
301
0
{
302
0
    X509_OBJECT *ret = X509_OBJECT_new();
303
304
0
    if (ret == NULL)
305
0
        return NULL;
306
0
    if (!X509_STORE_CTX_get_by_subject(vs, type, name, ret)) {
307
0
        X509_OBJECT_free(ret);
308
0
        return NULL;
309
0
    }
310
0
    return ret;
311
0
}
312
313
/* Also fill the cache with all matching certificates */
314
int X509_STORE_CTX_get_by_subject(const X509_STORE_CTX *vs,
315
                                  X509_LOOKUP_TYPE type,
316
                                  const X509_NAME *name, X509_OBJECT *ret)
317
9.98k
{
318
9.98k
    X509_STORE *store = vs->store;
319
9.98k
    X509_LOOKUP *lu;
320
9.98k
    X509_OBJECT stmp, *tmp;
321
9.98k
    int i, j;
322
323
9.98k
    if (store == NULL)
324
0
        return 0;
325
326
9.98k
    stmp.type = X509_LU_NONE;
327
9.98k
    stmp.data.ptr = NULL;
328
329
9.98k
    if (!x509_store_read_lock(store))
330
0
        return 0;
331
    /* Should already be sorted...but just in case */
332
9.98k
    if (!sk_X509_OBJECT_is_sorted(store->objs)) {
333
6.54k
        X509_STORE_unlock(store);
334
        /* Take a write lock instead of a read lock */
335
6.54k
        X509_STORE_lock(store);
336
        /*
337
         * Another thread might have sorted it in the meantime. But if so,
338
         * sk_X509_OBJECT_sort() exits early.
339
         */
340
6.54k
        sk_X509_OBJECT_sort(store->objs);
341
6.54k
    }
342
9.98k
    tmp = X509_OBJECT_retrieve_by_subject(store->objs, type, name);
343
9.98k
    X509_STORE_unlock(store);
344
345
9.98k
    if (tmp == NULL || type == X509_LU_CRL) {
346
8.62k
        for (i = 0; i < sk_X509_LOOKUP_num(store->get_cert_methods); i++) {
347
0
            lu = sk_X509_LOOKUP_value(store->get_cert_methods, i);
348
0
            j = X509_LOOKUP_by_subject_ex(lu, type, name, &stmp, vs->libctx,
349
0
                                          vs->propq);
350
0
            if (j) {
351
0
                tmp = &stmp;
352
0
                break;
353
0
            }
354
0
        }
355
8.62k
        if (tmp == NULL)
356
8.62k
            return 0;
357
8.62k
    }
358
359
1.35k
    if (!X509_OBJECT_up_ref_count(tmp))
360
0
        return 0;
361
362
1.35k
    ret->type = tmp->type;
363
1.35k
    ret->data.ptr = tmp->data.ptr;
364
365
1.35k
    return 1;
366
1.35k
}
367
368
6.58k
static int x509_store_add(X509_STORE *store, void *x, int crl) {
369
6.58k
    X509_OBJECT *obj;
370
6.58k
    int ret = 0, added = 0;
371
372
6.58k
    if (x == NULL)
373
0
        return 0;
374
6.58k
    obj = X509_OBJECT_new();
375
6.58k
    if (obj == NULL)
376
0
        return 0;
377
378
6.58k
    if (crl) {
379
0
        obj->type = X509_LU_CRL;
380
0
        obj->data.crl = (X509_CRL *)x;
381
6.58k
    } else {
382
6.58k
        obj->type = X509_LU_X509;
383
6.58k
        obj->data.x509 = (X509 *)x;
384
6.58k
    }
385
6.58k
    if (!X509_OBJECT_up_ref_count(obj)) {
386
0
        obj->type = X509_LU_NONE;
387
0
        X509_OBJECT_free(obj);
388
0
        return 0;
389
0
    }
390
391
6.58k
    if (!X509_STORE_lock(store)) {
392
0
        obj->type = X509_LU_NONE;
393
0
        X509_OBJECT_free(obj);
394
0
        return 0;
395
0
    }
396
397
6.58k
    if (X509_OBJECT_retrieve_match(store->objs, obj)) {
398
0
        ret = 1;
399
6.58k
    } else {
400
6.58k
        added = sk_X509_OBJECT_push(store->objs, obj);
401
6.58k
        ret = added != 0;
402
6.58k
    }
403
6.58k
    X509_STORE_unlock(store);
404
405
6.58k
    if (added == 0)             /* obj not pushed */
406
0
        X509_OBJECT_free(obj);
407
408
6.58k
    return ret;
409
6.58k
}
410
411
int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
412
6.58k
{
413
6.58k
    if (!x509_store_add(ctx, x, 0)) {
414
0
        ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
415
0
        return 0;
416
0
    }
417
6.58k
    return 1;
418
6.58k
}
419
420
int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
421
0
{
422
0
    if (!x509_store_add(ctx, x, 1)) {
423
0
        ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
424
0
        return 0;
425
0
    }
426
0
    return 1;
427
0
}
428
429
int X509_OBJECT_up_ref_count(X509_OBJECT *a)
430
11.5k
{
431
11.5k
    switch (a->type) {
432
0
    case X509_LU_NONE:
433
0
        break;
434
11.5k
    case X509_LU_X509:
435
11.5k
        return X509_up_ref(a->data.x509);
436
0
    case X509_LU_CRL:
437
0
        return X509_CRL_up_ref(a->data.crl);
438
11.5k
    }
439
0
    return 1;
440
11.5k
}
441
442
X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a)
443
0
{
444
0
    if (a == NULL || a->type != X509_LU_X509)
445
0
        return NULL;
446
0
    return a->data.x509;
447
0
}
448
449
X509_CRL *X509_OBJECT_get0_X509_CRL(const X509_OBJECT *a)
450
0
{
451
0
    if (a == NULL || a->type != X509_LU_CRL)
452
0
        return NULL;
453
0
    return a->data.crl;
454
0
}
455
456
X509_LOOKUP_TYPE X509_OBJECT_get_type(const X509_OBJECT *a)
457
0
{
458
0
    return a->type;
459
0
}
460
461
X509_OBJECT *X509_OBJECT_new(void)
462
58.4k
{
463
58.4k
    X509_OBJECT *ret = OPENSSL_zalloc(sizeof(*ret));
464
465
58.4k
    if (ret == NULL) {
466
0
        ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
467
0
        return NULL;
468
0
    }
469
58.4k
    ret->type = X509_LU_NONE;
470
58.4k
    return ret;
471
58.4k
}
472
473
static void x509_object_free_internal(X509_OBJECT *a)
474
58.4k
{
475
58.4k
    if (a == NULL)
476
0
        return;
477
58.4k
    switch (a->type) {
478
49.1k
    case X509_LU_NONE:
479
49.1k
        break;
480
9.30k
    case X509_LU_X509:
481
9.30k
        X509_free(a->data.x509);
482
9.30k
        break;
483
0
    case X509_LU_CRL:
484
0
        X509_CRL_free(a->data.crl);
485
0
        break;
486
58.4k
    }
487
58.4k
}
488
489
int X509_OBJECT_set1_X509(X509_OBJECT *a, X509 *obj)
490
0
{
491
0
    if (a == NULL || !X509_up_ref(obj))
492
0
        return 0;
493
494
0
    x509_object_free_internal(a);
495
0
    a->type = X509_LU_X509;
496
0
    a->data.x509 = obj;
497
0
    return 1;
498
0
}
499
500
int X509_OBJECT_set1_X509_CRL(X509_OBJECT *a, X509_CRL *obj)
501
0
{
502
0
    if (a == NULL || !X509_CRL_up_ref(obj))
503
0
        return 0;
504
505
0
    x509_object_free_internal(a);
506
0
    a->type = X509_LU_CRL;
507
0
    a->data.crl = obj;
508
0
    return 1;
509
0
}
510
511
void X509_OBJECT_free(X509_OBJECT *a)
512
58.4k
{
513
58.4k
    x509_object_free_internal(a);
514
58.4k
    OPENSSL_free(a);
515
58.4k
}
516
517
static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
518
                               const X509_NAME *name, int *pnmatch)
519
22.6k
{
520
22.6k
    X509_OBJECT stmp;
521
22.6k
    X509 x509_s;
522
22.6k
    X509_CRL crl_s;
523
524
22.6k
    stmp.type = type;
525
22.6k
    switch (type) {
526
21.8k
    case X509_LU_X509:
527
21.8k
        stmp.data.x509 = &x509_s;
528
21.8k
        x509_s.cert_info.subject = (X509_NAME *)name; /* won't modify it */
529
21.8k
        break;
530
799
    case X509_LU_CRL:
531
799
        stmp.data.crl = &crl_s;
532
799
        crl_s.crl.issuer = (X509_NAME *)name; /* won't modify it */
533
799
        break;
534
0
    case X509_LU_NONE:
535
        /* abort(); */
536
0
        return -1;
537
22.6k
    }
538
539
    /* Assumes h is locked for read if applicable */
540
22.6k
    return sk_X509_OBJECT_find_all(h, &stmp, pnmatch);
541
22.6k
}
542
543
/* Assumes h is locked for read if applicable */
544
int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
545
                               const X509_NAME *name)
546
52.7k
{
547
52.7k
    return x509_object_idx_cnt(h, type, name, NULL);
548
52.7k
}
549
550
/* Assumes h is locked for read if applicable */
551
X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
552
                                             X509_LOOKUP_TYPE type,
553
                                             const X509_NAME *name)
554
52.7k
{
555
52.7k
    int idx;
556
52.7k
    idx = X509_OBJECT_idx_by_subject(h, type, name);
557
52.7k
    if (idx == -1)
558
47.7k
        return NULL;
559
4.96k
    return sk_X509_OBJECT_value(h, idx);
560
52.7k
}
561
562
STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(const X509_STORE *v)
563
0
{
564
0
    return v->objs;
565
0
}
566
567
STACK_OF(X509) *X509_STORE_get1_all_certs(X509_STORE *store)
568
0
{
569
0
    STACK_OF(X509) *sk;
570
0
    STACK_OF(X509_OBJECT) *objs;
571
0
    int i;
572
573
0
    if (store == NULL) {
574
0
        ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
575
0
        return NULL;
576
0
    }
577
0
    if ((sk = sk_X509_new_null()) == NULL)
578
0
        return NULL;
579
0
    if (!X509_STORE_lock(store))
580
0
        goto out_free;
581
582
0
    objs = X509_STORE_get0_objects(store);
583
0
    for (i = 0; i < sk_X509_OBJECT_num(objs); i++) {
584
0
        X509 *cert = X509_OBJECT_get0_X509(sk_X509_OBJECT_value(objs, i));
585
586
0
        if (cert != NULL
587
0
            && !X509_add_cert(sk, cert, X509_ADD_FLAG_UP_REF))
588
0
            goto err;
589
0
    }
590
0
    X509_STORE_unlock(store);
591
0
    return sk;
592
593
0
 err:
594
0
    X509_STORE_unlock(store);
595
0
 out_free:
596
0
    sk_X509_pop_free(sk, X509_free);
597
0
    return NULL;
598
0
}
599
600
STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx,
601
                                          const X509_NAME *nm)
602
2.79k
{
603
2.79k
    int i, idx, cnt;
604
2.79k
    STACK_OF(X509) *sk = NULL;
605
2.79k
    X509 *x;
606
2.79k
    X509_OBJECT *obj;
607
2.79k
    X509_STORE *store = ctx->store;
608
609
2.79k
    if (store == NULL)
610
0
        return NULL;
611
612
2.79k
    if (!X509_STORE_lock(store))
613
0
        return NULL;
614
615
2.79k
    idx = x509_object_idx_cnt(store->objs, X509_LU_X509, nm, &cnt);
616
2.79k
    if (idx < 0) {
617
        /*
618
         * Nothing found in cache: do lookup to possibly add new objects to
619
         * cache
620
         */
621
1.25k
        X509_OBJECT *xobj = X509_OBJECT_new();
622
623
1.25k
        X509_STORE_unlock(store);
624
625
1.25k
        if (xobj == NULL)
626
0
            return NULL;
627
1.25k
        if (!X509_STORE_CTX_get_by_subject(ctx, X509_LU_X509, nm, xobj)) {
628
1.25k
            X509_OBJECT_free(xobj);
629
1.25k
            return NULL;
630
1.25k
        }
631
0
        X509_OBJECT_free(xobj);
632
0
        if (!X509_STORE_lock(store))
633
0
            return NULL;
634
0
        idx = x509_object_idx_cnt(store->objs, X509_LU_X509, nm, &cnt);
635
0
        if (idx < 0) {
636
0
            X509_STORE_unlock(store);
637
0
            return NULL;
638
0
        }
639
0
    }
640
641
1.54k
    sk = sk_X509_new_null();
642
3.09k
    for (i = 0; i < cnt; i++, idx++) {
643
1.54k
        obj = sk_X509_OBJECT_value(store->objs, idx);
644
1.54k
        x = obj->data.x509;
645
1.54k
        if (!X509_add_cert(sk, x, X509_ADD_FLAG_UP_REF)) {
646
0
            X509_STORE_unlock(store);
647
0
            sk_X509_pop_free(sk, X509_free);
648
0
            return NULL;
649
0
        }
650
1.54k
    }
651
1.54k
    X509_STORE_unlock(store);
652
1.54k
    return sk;
653
1.54k
}
654
655
STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(const X509_STORE_CTX *ctx,
656
                                             const X509_NAME *nm)
657
799
{
658
799
    int i, idx, cnt;
659
799
    STACK_OF(X509_CRL) *sk = sk_X509_CRL_new_null();
660
799
    X509_CRL *x;
661
799
    X509_OBJECT *obj, *xobj = X509_OBJECT_new();
662
799
    X509_STORE *store = ctx->store;
663
664
    /* Always do lookup to possibly add new CRLs to cache */
665
799
    if (sk == NULL
666
799
            || xobj == NULL
667
799
            || store == NULL
668
799
            || !X509_STORE_CTX_get_by_subject(ctx, X509_LU_CRL, nm, xobj)) {
669
799
        X509_OBJECT_free(xobj);
670
799
        sk_X509_CRL_free(sk);
671
799
        return NULL;
672
799
    }
673
0
    X509_OBJECT_free(xobj);
674
0
    if (!X509_STORE_lock(store)) {
675
0
        sk_X509_CRL_free(sk);
676
0
        return NULL;
677
0
    }
678
0
    idx = x509_object_idx_cnt(store->objs, X509_LU_CRL, nm, &cnt);
679
0
    if (idx < 0) {
680
0
        X509_STORE_unlock(store);
681
0
        sk_X509_CRL_free(sk);
682
0
        return NULL;
683
0
    }
684
685
0
    for (i = 0; i < cnt; i++, idx++) {
686
0
        obj = sk_X509_OBJECT_value(store->objs, idx);
687
0
        x = obj->data.crl;
688
0
        if (!X509_CRL_up_ref(x)) {
689
0
            X509_STORE_unlock(store);
690
0
            sk_X509_CRL_pop_free(sk, X509_CRL_free);
691
0
            return NULL;
692
0
        }
693
0
        if (!sk_X509_CRL_push(sk, x)) {
694
0
            X509_STORE_unlock(store);
695
0
            X509_CRL_free(x);
696
0
            sk_X509_CRL_pop_free(sk, X509_CRL_free);
697
0
            return NULL;
698
0
        }
699
0
    }
700
0
    X509_STORE_unlock(store);
701
0
    return sk;
702
0
}
703
704
X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
705
                                        X509_OBJECT *x)
706
6.58k
{
707
6.58k
    int idx, i, num;
708
6.58k
    X509_OBJECT *obj;
709
710
6.58k
    idx = sk_X509_OBJECT_find(h, x);
711
6.58k
    if (idx < 0)
712
6.58k
        return NULL;
713
0
    if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
714
0
        return sk_X509_OBJECT_value(h, idx);
715
0
    for (i = idx, num = sk_X509_OBJECT_num(h); i < num; i++) {
716
0
        obj = sk_X509_OBJECT_value(h, i);
717
0
        if (x509_object_cmp((const X509_OBJECT **)&obj,
718
0
                            (const X509_OBJECT **)&x))
719
0
            return NULL;
720
0
        if (x->type == X509_LU_X509) {
721
0
            if (!X509_cmp(obj->data.x509, x->data.x509))
722
0
                return obj;
723
0
        } else if (x->type == X509_LU_CRL) {
724
0
            if (X509_CRL_match(obj->data.crl, x->data.crl) == 0)
725
0
                return obj;
726
0
        } else
727
0
            return obj;
728
0
    }
729
0
    return NULL;
730
0
}
731
732
/*-
733
 * Try to get issuer cert from |ctx->store| matching the subject name of |x|.
734
 * Prefer the first non-expired one, else take the most recently expired one.
735
 *
736
 * Return values are:
737
 *  1 lookup successful.
738
 *  0 certificate not found.
739
 * -1 some other error.
740
 */
741
int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
742
31.7k
{
743
31.7k
    const X509_NAME *xn;
744
31.7k
    X509_OBJECT *obj = X509_OBJECT_new(), *pobj = NULL;
745
31.7k
    X509_STORE *store = ctx->store;
746
31.7k
    int i, ok, idx, ret, nmatch = 0;
747
748
31.7k
    if (obj == NULL)
749
0
        return -1;
750
31.7k
    *issuer = NULL;
751
31.7k
    xn = X509_get_issuer_name(x);
752
31.7k
    ok = X509_STORE_CTX_get_by_subject(ctx, X509_LU_X509, xn, obj);
753
31.7k
    if (ok != 1) {
754
27.8k
        X509_OBJECT_free(obj);
755
27.8k
        return 0;
756
27.8k
    }
757
    /* If certificate matches and is currently valid all OK */
758
3.83k
    if (ctx->check_issued(ctx, x, obj->data.x509)) {
759
1.61k
        if (ossl_x509_check_cert_time(ctx, obj->data.x509, -1)) {
760
1.61k
            *issuer = obj->data.x509;
761
            /* |*issuer| has taken over the cert reference from |obj| */
762
1.61k
            obj->type = X509_LU_NONE;
763
1.61k
            X509_OBJECT_free(obj);
764
1.61k
            return 1;
765
1.61k
        }
766
1.61k
    }
767
2.22k
    X509_OBJECT_free(obj);
768
769
    /*
770
     * Due to limitations of the API this can only retrieve a single cert.
771
     * However it will fill the cache with all matching certificates,
772
     * so we can examine the cache for all matches.
773
     */
774
2.22k
    if (store == NULL)
775
0
        return 0;
776
777
    /* Find index of first currently valid cert accepted by 'check_issued' */
778
2.22k
    ret = 0;
779
2.22k
    if (!X509_STORE_lock(store))
780
0
        return 0;
781
782
2.22k
    idx = x509_object_idx_cnt(store->objs, X509_LU_X509, xn, &nmatch);
783
2.22k
    if (idx != -1) { /* should be true as we've had at least one match */
784
        /* Look through all matching certs for suitable issuer */
785
4.45k
        for (i = idx; i < idx + nmatch; i++) {
786
2.22k
            pobj = sk_X509_OBJECT_value(store->objs, i);
787
            /* See if we've run past the matches */
788
2.22k
            if (pobj->type != X509_LU_X509)
789
0
                break;
790
2.22k
            if (ctx->check_issued(ctx, x, pobj->data.x509)) {
791
0
                ret = 1;
792
                /* If times check fine, exit with match, else keep looking. */
793
0
                if (ossl_x509_check_cert_time(ctx, pobj->data.x509, -1)) {
794
0
                    *issuer = pobj->data.x509;
795
0
                    break;
796
0
                }
797
                /*
798
                 * Leave the so far most recently expired match in *issuer
799
                 * so we return nearest match if no certificate time is OK.
800
                 */
801
0
                if (*issuer == NULL
802
0
                    || ASN1_TIME_compare(X509_get0_notAfter(pobj->data.x509),
803
0
                                         X509_get0_notAfter(*issuer)) > 0)
804
0
                    *issuer = pobj->data.x509;
805
0
            }
806
2.22k
        }
807
2.22k
    }
808
2.22k
    if (*issuer != NULL && !X509_up_ref(*issuer)) {
809
0
        *issuer = NULL;
810
0
        ret = -1;
811
0
    }
812
2.22k
    X509_STORE_unlock(store);
813
2.22k
    return ret;
814
2.22k
}
815
816
int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
817
0
{
818
0
    return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
819
0
}
820
821
int X509_STORE_set_depth(X509_STORE *ctx, int depth)
822
0
{
823
0
    X509_VERIFY_PARAM_set_depth(ctx->param, depth);
824
0
    return 1;
825
0
}
826
827
int X509_STORE_set_purpose(X509_STORE *ctx, int purpose)
828
0
{
829
0
    return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
830
0
}
831
832
int X509_STORE_set_trust(X509_STORE *ctx, int trust)
833
0
{
834
0
    return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
835
0
}
836
837
int X509_STORE_set1_param(X509_STORE *ctx, const X509_VERIFY_PARAM *param)
838
6.58k
{
839
6.58k
    return X509_VERIFY_PARAM_set1(ctx->param, param);
840
6.58k
}
841
842
X509_VERIFY_PARAM *X509_STORE_get0_param(const X509_STORE *ctx)
843
0
{
844
0
    return ctx->param;
845
0
}
846
847
void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify)
848
0
{
849
0
    ctx->verify = verify;
850
0
}
851
852
X509_STORE_CTX_verify_fn X509_STORE_get_verify(const X509_STORE *ctx)
853
0
{
854
0
    return ctx->verify;
855
0
}
856
857
void X509_STORE_set_verify_cb(X509_STORE *ctx,
858
                              X509_STORE_CTX_verify_cb verify_cb)
859
6.58k
{
860
6.58k
    ctx->verify_cb = verify_cb;
861
6.58k
}
862
863
X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(const X509_STORE *ctx)
864
0
{
865
0
    return ctx->verify_cb;
866
0
}
867
868
void X509_STORE_set_get_issuer(X509_STORE *ctx,
869
                               X509_STORE_CTX_get_issuer_fn get_issuer)
870
0
{
871
0
    ctx->get_issuer = get_issuer;
872
0
}
873
874
X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(const X509_STORE *ctx)
875
0
{
876
0
    return ctx->get_issuer;
877
0
}
878
879
void X509_STORE_set_check_issued(X509_STORE *ctx,
880
                                 X509_STORE_CTX_check_issued_fn check_issued)
881
0
{
882
0
    ctx->check_issued = check_issued;
883
0
}
884
885
X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(const X509_STORE *ctx)
886
0
{
887
0
    return ctx->check_issued;
888
0
}
889
890
void X509_STORE_set_check_revocation(X509_STORE *ctx,
891
                                     X509_STORE_CTX_check_revocation_fn check_revocation)
892
0
{
893
0
    ctx->check_revocation = check_revocation;
894
0
}
895
896
X509_STORE_CTX_check_revocation_fn X509_STORE_get_check_revocation(const X509_STORE *ctx)
897
0
{
898
0
    return ctx->check_revocation;
899
0
}
900
901
void X509_STORE_set_get_crl(X509_STORE *ctx,
902
                            X509_STORE_CTX_get_crl_fn get_crl)
903
0
{
904
0
    ctx->get_crl = get_crl;
905
0
}
906
907
X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(const X509_STORE *ctx)
908
0
{
909
0
    return ctx->get_crl;
910
0
}
911
912
void X509_STORE_set_check_crl(X509_STORE *ctx,
913
                              X509_STORE_CTX_check_crl_fn check_crl)
914
0
{
915
0
    ctx->check_crl = check_crl;
916
0
}
917
918
X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(const X509_STORE *ctx)
919
0
{
920
0
    return ctx->check_crl;
921
0
}
922
923
void X509_STORE_set_cert_crl(X509_STORE *ctx,
924
                             X509_STORE_CTX_cert_crl_fn cert_crl)
925
0
{
926
0
    ctx->cert_crl = cert_crl;
927
0
}
928
929
X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(const X509_STORE *ctx)
930
0
{
931
0
    return ctx->cert_crl;
932
0
}
933
934
void X509_STORE_set_check_policy(X509_STORE *ctx,
935
                                 X509_STORE_CTX_check_policy_fn check_policy)
936
0
{
937
0
    ctx->check_policy = check_policy;
938
0
}
939
940
X509_STORE_CTX_check_policy_fn X509_STORE_get_check_policy(const X509_STORE *ctx)
941
0
{
942
0
    return ctx->check_policy;
943
0
}
944
945
void X509_STORE_set_lookup_certs(X509_STORE *ctx,
946
                                 X509_STORE_CTX_lookup_certs_fn lookup_certs)
947
0
{
948
0
    ctx->lookup_certs = lookup_certs;
949
0
}
950
951
X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(const X509_STORE *ctx)
952
0
{
953
0
    return ctx->lookup_certs;
954
0
}
955
956
void X509_STORE_set_lookup_crls(X509_STORE *ctx,
957
                                X509_STORE_CTX_lookup_crls_fn lookup_crls)
958
0
{
959
0
    ctx->lookup_crls = lookup_crls;
960
0
}
961
962
X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(const X509_STORE *ctx)
963
0
{
964
0
    return ctx->lookup_crls;
965
0
}
966
967
void X509_STORE_set_cleanup(X509_STORE *ctx,
968
                            X509_STORE_CTX_cleanup_fn ctx_cleanup)
969
0
{
970
0
    ctx->cleanup = ctx_cleanup;
971
0
}
972
973
X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(const X509_STORE *ctx)
974
0
{
975
0
    return ctx->cleanup;
976
0
}
977
978
int X509_STORE_set_ex_data(X509_STORE *ctx, int idx, void *data)
979
0
{
980
0
    return CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
981
0
}
982
983
void *X509_STORE_get_ex_data(const X509_STORE *ctx, int idx)
984
0
{
985
0
    return CRYPTO_get_ex_data(&ctx->ex_data, idx);
986
0
}
987
988
X509_STORE *X509_STORE_CTX_get0_store(const X509_STORE_CTX *ctx)
989
0
{
990
0
    return ctx->store;
991
0
}