Coverage Report

Created: 2025-06-13 06:58

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