Coverage Report

Created: 2024-07-27 06:39

/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
42.3k
{
46
42.3k
    return CRYPTO_THREAD_write_lock(xs->lock);
47
42.3k
}
48
49
static int x509_store_read_lock(X509_STORE *xs)
50
39.4k
{
51
39.4k
    return CRYPTO_THREAD_read_lock(xs->lock);
52
39.4k
}
53
54
int X509_STORE_unlock(X509_STORE *xs)
55
81.8k
{
56
81.8k
    return CRYPTO_THREAD_unlock(xs->lock);
57
81.8k
}
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
15.1k
{
166
15.1k
    int ret;
167
168
15.1k
    ret = ((*a)->type - (*b)->type);
169
15.1k
    if (ret)
170
1.15k
        return ret;
171
13.9k
    switch ((*a)->type) {
172
13.9k
    case X509_LU_X509:
173
13.9k
        ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509);
174
13.9k
        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
13.9k
    }
182
13.9k
    return ret;
183
13.9k
}
184
185
X509_STORE *X509_STORE_new(void)
186
25.9k
{
187
25.9k
    X509_STORE *ret = OPENSSL_zalloc(sizeof(*ret));
188
189
25.9k
    if (ret == NULL) {
190
0
        ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
191
0
        return NULL;
192
0
    }
193
25.9k
    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
25.9k
    ret->cache = 1;
198
25.9k
    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
25.9k
    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
25.9k
    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
25.9k
    ret->lock = CRYPTO_THREAD_lock_new();
213
25.9k
    if (ret->lock == NULL) {
214
0
        ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
215
0
        goto err;
216
0
    }
217
25.9k
    ret->references = 1;
218
25.9k
    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
25.9k
}
227
228
void X509_STORE_free(X509_STORE *vfy)
229
489k
{
230
489k
    int i;
231
489k
    STACK_OF(X509_LOOKUP) *sk;
232
489k
    X509_LOOKUP *lu;
233
234
489k
    if (vfy == NULL)
235
407k
        return;
236
82.2k
    CRYPTO_DOWN_REF(&vfy->references, &i, vfy->lock);
237
82.2k
    REF_PRINT_COUNT("X509_STORE", vfy);
238
82.2k
    if (i > 0)
239
0
        return;
240
82.2k
    REF_ASSERT_ISNT(i < 0);
241
242
82.2k
    sk = vfy->get_cert_methods;
243
82.2k
    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
82.2k
    sk_X509_LOOKUP_free(sk);
249
82.2k
    sk_X509_OBJECT_pop_free(vfy->objs, X509_OBJECT_free);
250
251
82.2k
    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data);
252
82.2k
    X509_VERIFY_PARAM_free(vfy->param);
253
82.2k
    CRYPTO_THREAD_lock_free(vfy->lock);
254
82.2k
    OPENSSL_free(vfy);
255
82.2k
}
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
7.26k
{
318
7.26k
    X509_STORE *store = vs->store;
319
7.26k
    X509_LOOKUP *lu;
320
7.26k
    X509_OBJECT stmp, *tmp;
321
7.26k
    int i, j;
322
323
7.26k
    if (store == NULL)
324
0
        return 0;
325
326
7.26k
    stmp.type = X509_LU_NONE;
327
7.26k
    stmp.data.ptr = NULL;
328
329
7.26k
    if (!x509_store_read_lock(store))
330
0
        return 0;
331
    /* Should already be sorted...but just in case */
332
7.26k
    if (!sk_X509_OBJECT_is_sorted(store->objs)) {
333
4.86k
        X509_STORE_unlock(store);
334
        /* Take a write lock instead of a read lock */
335
4.86k
        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
4.86k
        sk_X509_OBJECT_sort(store->objs);
341
4.86k
    }
342
7.26k
    tmp = X509_OBJECT_retrieve_by_subject(store->objs, type, name);
343
7.26k
    X509_STORE_unlock(store);
344
345
7.26k
    if (tmp == NULL || type == X509_LU_CRL) {
346
6.98k
        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
6.98k
        if (tmp == NULL)
356
6.98k
            return 0;
357
6.98k
    }
358
359
285
    if (!X509_OBJECT_up_ref_count(tmp))
360
0
        return 0;
361
362
285
    ret->type = tmp->type;
363
285
    ret->data.ptr = tmp->data.ptr;
364
365
285
    return 1;
366
285
}
367
368
4.59k
static int x509_store_add(X509_STORE *store, void *x, int crl) {
369
4.59k
    X509_OBJECT *obj;
370
4.59k
    int ret = 0, added = 0;
371
372
4.59k
    if (x == NULL)
373
0
        return 0;
374
4.59k
    obj = X509_OBJECT_new();
375
4.59k
    if (obj == NULL)
376
0
        return 0;
377
378
4.59k
    if (crl) {
379
0
        obj->type = X509_LU_CRL;
380
0
        obj->data.crl = (X509_CRL *)x;
381
4.59k
    } else {
382
4.59k
        obj->type = X509_LU_X509;
383
4.59k
        obj->data.x509 = (X509 *)x;
384
4.59k
    }
385
4.59k
    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
4.59k
    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
4.59k
    if (X509_OBJECT_retrieve_match(store->objs, obj)) {
398
0
        ret = 1;
399
4.59k
    } else {
400
4.59k
        added = sk_X509_OBJECT_push(store->objs, obj);
401
4.59k
        ret = added != 0;
402
4.59k
    }
403
4.59k
    X509_STORE_unlock(store);
404
405
4.59k
    if (added == 0)             /* obj not pushed */
406
0
        X509_OBJECT_free(obj);
407
408
4.59k
    return ret;
409
4.59k
}
410
411
int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
412
4.59k
{
413
4.59k
    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
4.59k
    return 1;
418
4.59k
}
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
8.10k
{
431
8.10k
    switch (a->type) {
432
0
    case X509_LU_NONE:
433
0
        break;
434
8.10k
    case X509_LU_X509:
435
8.10k
        return X509_up_ref(a->data.x509);
436
0
    case X509_LU_CRL:
437
0
        return X509_CRL_up_ref(a->data.crl);
438
8.10k
    }
439
0
    return 1;
440
8.10k
}
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
52.0k
{
463
52.0k
    X509_OBJECT *ret = OPENSSL_zalloc(sizeof(*ret));
464
465
52.0k
    if (ret == NULL) {
466
0
        ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
467
0
        return NULL;
468
0
    }
469
52.0k
    ret->type = X509_LU_NONE;
470
52.0k
    return ret;
471
52.0k
}
472
473
static void x509_object_free_internal(X509_OBJECT *a)
474
52.0k
{
475
52.0k
    if (a == NULL)
476
0
        return;
477
52.0k
    switch (a->type) {
478
45.7k
    case X509_LU_NONE:
479
45.7k
        break;
480
6.27k
    case X509_LU_X509:
481
6.27k
        X509_free(a->data.x509);
482
6.27k
        break;
483
0
    case X509_LU_CRL:
484
0
        X509_CRL_free(a->data.crl);
485
0
        break;
486
52.0k
    }
487
52.0k
}
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
52.0k
{
513
52.0k
    x509_object_free_internal(a);
514
52.0k
    OPENSSL_free(a);
515
52.0k
}
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
17.5k
{
520
17.5k
    X509_OBJECT stmp;
521
17.5k
    X509 x509_s;
522
17.5k
    X509_CRL crl_s;
523
524
17.5k
    stmp.type = type;
525
17.5k
    switch (type) {
526
17.1k
    case X509_LU_X509:
527
17.1k
        stmp.data.x509 = &x509_s;
528
17.1k
        x509_s.cert_info.subject = (X509_NAME *)name; /* won't modify it */
529
17.1k
        break;
530
361
    case X509_LU_CRL:
531
361
        stmp.data.crl = &crl_s;
532
361
        crl_s.crl.issuer = (X509_NAME *)name; /* won't modify it */
533
361
        break;
534
0
    case X509_LU_NONE:
535
        /* abort(); */
536
0
        return -1;
537
17.5k
    }
538
539
    /* Assumes h is locked for read if applicable */
540
17.5k
    return sk_X509_OBJECT_find_all(h, &stmp, pnmatch);
541
17.5k
}
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
47.4k
{
547
47.4k
    return x509_object_idx_cnt(h, type, name, NULL);
548
47.4k
}
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
47.4k
{
555
47.4k
    int idx;
556
47.4k
    idx = X509_OBJECT_idx_by_subject(h, type, name);
557
47.4k
    if (idx == -1)
558
43.9k
        return NULL;
559
3.50k
    return sk_X509_OBJECT_value(h, idx);
560
47.4k
}
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
1.37k
{
603
1.37k
    int i, idx, cnt;
604
1.37k
    STACK_OF(X509) *sk = NULL;
605
1.37k
    X509 *x;
606
1.37k
    X509_OBJECT *obj;
607
1.37k
    X509_STORE *store = ctx->store;
608
609
1.37k
    if (store == NULL)
610
0
        return NULL;
611
612
1.37k
    if (!X509_STORE_lock(store))
613
0
        return NULL;
614
615
1.37k
    idx = x509_object_idx_cnt(store->objs, X509_LU_X509, nm, &cnt);
616
1.37k
    if (idx < 0) {
617
        /*
618
         * Nothing found in cache: do lookup to possibly add new objects to
619
         * cache
620
         */
621
540
        X509_OBJECT *xobj = X509_OBJECT_new();
622
623
540
        X509_STORE_unlock(store);
624
625
540
        if (xobj == NULL)
626
0
            return NULL;
627
540
        if (!X509_STORE_CTX_get_by_subject(ctx, X509_LU_X509, nm, xobj)) {
628
540
            X509_OBJECT_free(xobj);
629
540
            return NULL;
630
540
        }
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
832
    sk = sk_X509_new_null();
642
1.66k
    for (i = 0; i < cnt; i++, idx++) {
643
832
        obj = sk_X509_OBJECT_value(store->objs, idx);
644
832
        x = obj->data.x509;
645
832
        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
832
    }
651
832
    X509_STORE_unlock(store);
652
832
    return sk;
653
832
}
654
655
STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(const X509_STORE_CTX *ctx,
656
                                             const X509_NAME *nm)
657
361
{
658
361
    int i, idx, cnt;
659
361
    STACK_OF(X509_CRL) *sk = sk_X509_CRL_new_null();
660
361
    X509_CRL *x;
661
361
    X509_OBJECT *obj, *xobj = X509_OBJECT_new();
662
361
    X509_STORE *store = ctx->store;
663
664
    /* Always do lookup to possibly add new CRLs to cache */
665
361
    if (sk == NULL
666
361
            || xobj == NULL
667
361
            || store == NULL
668
361
            || !X509_STORE_CTX_get_by_subject(ctx, X509_LU_CRL, nm, xobj)) {
669
361
        X509_OBJECT_free(xobj);
670
361
        sk_X509_CRL_free(sk);
671
361
        return NULL;
672
361
    }
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
4.59k
{
707
4.59k
    int idx, i, num;
708
4.59k
    X509_OBJECT *obj;
709
710
4.59k
    idx = sk_X509_OBJECT_find(h, x);
711
4.59k
    if (idx < 0)
712
4.59k
        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
44.8k
{
743
44.8k
    const X509_NAME *xn;
744
44.8k
    X509_OBJECT *obj = X509_OBJECT_new(), *pobj = NULL;
745
44.8k
    X509_STORE *store = ctx->store;
746
44.8k
    int i, ok, idx, ret, nmatch = 0;
747
748
44.8k
    if (obj == NULL)
749
0
        return -1;
750
44.8k
    *issuer = NULL;
751
44.8k
    xn = X509_get_issuer_name(x);
752
44.8k
    ok = X509_STORE_CTX_get_by_subject(ctx, X509_LU_X509, xn, obj);
753
44.8k
    if (ok != 1) {
754
41.3k
        X509_OBJECT_free(obj);
755
41.3k
        return 0;
756
41.3k
    }
757
    /* If certificate matches and is currently valid all OK */
758
3.50k
    if (ctx->check_issued(ctx, x, obj->data.x509)) {
759
1.83k
        if (ossl_x509_check_cert_time(ctx, obj->data.x509, -1)) {
760
1.83k
            *issuer = obj->data.x509;
761
            /* |*issuer| has taken over the cert reference from |obj| */
762
1.83k
            obj->type = X509_LU_NONE;
763
1.83k
            X509_OBJECT_free(obj);
764
1.83k
            return 1;
765
1.83k
        }
766
1.83k
    }
767
1.67k
    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
1.67k
    if (store == NULL)
775
0
        return 0;
776
777
    /* Find index of first currently valid cert accepted by 'check_issued' */
778
1.67k
    ret = 0;
779
1.67k
    if (!X509_STORE_lock(store))
780
0
        return 0;
781
782
1.67k
    idx = x509_object_idx_cnt(store->objs, X509_LU_X509, xn, &nmatch);
783
1.67k
    if (idx != -1) { /* should be true as we've had at least one match */
784
        /* Look through all matching certs for suitable issuer */
785
3.34k
        for (i = idx; i < idx + nmatch; i++) {
786
1.67k
            pobj = sk_X509_OBJECT_value(store->objs, i);
787
            /* See if we've run past the matches */
788
1.67k
            if (pobj->type != X509_LU_X509)
789
0
                break;
790
1.67k
            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
1.67k
        }
807
1.67k
    }
808
1.67k
    if (*issuer != NULL && !X509_up_ref(*issuer)) {
809
0
        *issuer = NULL;
810
0
        ret = -1;
811
0
    }
812
1.67k
    X509_STORE_unlock(store);
813
1.67k
    return ret;
814
1.67k
}
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
4.59k
{
839
4.59k
    return X509_VERIFY_PARAM_set1(ctx->param, param);
840
4.59k
}
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
4.59k
{
860
4.59k
    ctx->verify_cb = verify_cb;
861
4.59k
}
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
}