Coverage Report

Created: 2022-08-24 06:30

/src/libressl/crypto/x509/x509_lu.c
Line
Count
Source (jump to first uncovered line)
1
/* $OpenBSD: x509_lu.c,v 1.55 2022/01/14 07:53:45 tb Exp $ */
2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 *
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 *
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 *
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 *
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 *
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
#include <stdio.h>
60
#include <string.h>
61
62
#include <openssl/err.h>
63
#include <openssl/lhash.h>
64
#include <openssl/x509.h>
65
#include <openssl/x509v3.h>
66
#include "x509_lcl.h"
67
68
X509_LOOKUP *
69
X509_LOOKUP_new(X509_LOOKUP_METHOD *method)
70
0
{
71
0
  X509_LOOKUP *lu;
72
73
0
  if ((lu = calloc(1, sizeof(*lu))) == NULL) {
74
0
    X509error(ERR_R_MALLOC_FAILURE);
75
0
    return NULL;
76
0
  }
77
78
0
  lu->method = method;
79
80
0
  if (method->new_item != NULL && !method->new_item(lu)) {
81
0
    free(lu);
82
0
    return NULL;
83
0
  }
84
85
0
  return lu;
86
0
}
87
88
void
89
X509_LOOKUP_free(X509_LOOKUP *ctx)
90
0
{
91
0
  if (ctx == NULL)
92
0
    return;
93
0
  if (ctx->method != NULL && ctx->method->free != NULL)
94
0
    ctx->method->free(ctx);
95
0
  free(ctx);
96
0
}
97
98
int
99
X509_LOOKUP_init(X509_LOOKUP *ctx)
100
0
{
101
0
  if (ctx->method == NULL)
102
0
    return 0;
103
0
  if (ctx->method->init == NULL)
104
0
    return 1;
105
0
  return ctx->method->init(ctx);
106
0
}
107
108
int
109
X509_LOOKUP_shutdown(X509_LOOKUP *ctx)
110
0
{
111
0
  if (ctx->method == NULL)
112
0
    return 0;
113
0
  if (ctx->method->shutdown == NULL)
114
0
    return 1;
115
0
  return ctx->method->shutdown(ctx);
116
0
}
117
118
int
119
X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
120
    char **ret)
121
0
{
122
0
  if (ctx->method == NULL)
123
0
    return -1;
124
0
  if (ctx->method->ctrl == NULL)
125
0
    return 1;
126
0
  return ctx->method->ctrl(ctx, cmd, argc, argl, ret);
127
0
}
128
129
int
130
X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, X509_NAME *name,
131
    X509_OBJECT *ret)
132
0
{
133
0
  if (ctx->method == NULL || ctx->method->get_by_subject == NULL)
134
0
    return 0;
135
0
  return ctx->method->get_by_subject(ctx, type, name, ret);
136
0
}
137
138
int
139
X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
140
    X509_NAME *name, ASN1_INTEGER *serial, X509_OBJECT *ret)
141
0
{
142
0
  if (ctx->method == NULL || ctx->method->get_by_issuer_serial == NULL)
143
0
    return 0;
144
0
  return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret);
145
0
}
146
147
int
148
X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
149
    const unsigned char *bytes, int len, X509_OBJECT *ret)
150
0
{
151
0
  if (ctx->method == NULL || ctx->method->get_by_fingerprint == NULL)
152
0
    return 0;
153
0
  return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret);
154
0
}
155
156
int
157
X509_LOOKUP_by_alias(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, const char *str,
158
    int len, X509_OBJECT *ret)
159
0
{
160
0
  if (ctx->method == NULL || ctx->method->get_by_alias == NULL)
161
0
    return 0;
162
0
  return ctx->method->get_by_alias(ctx, type, str, len, ret);
163
0
}
164
165
static int
166
x509_object_cmp(const X509_OBJECT * const *a, const X509_OBJECT * const *b)
167
0
{
168
0
  int ret;
169
170
0
  if ((ret = (*a)->type - (*b)->type) != 0)
171
0
    return ret;
172
173
0
  switch ((*a)->type) {
174
0
  case X509_LU_X509:
175
0
    return X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509);
176
0
  case X509_LU_CRL:
177
0
    return X509_CRL_cmp((*a)->data.crl, (*b)->data.crl);
178
0
  }
179
0
  return 0;
180
0
}
181
182
X509_STORE *
183
X509_STORE_new(void)
184
0
{
185
0
  X509_STORE *store;
186
187
0
  if ((store = calloc(1, sizeof(*store))) == NULL)
188
0
    goto err;
189
190
0
  if ((store->objs = sk_X509_OBJECT_new(x509_object_cmp)) == NULL)
191
0
    goto err;
192
0
  if ((store->get_cert_methods = sk_X509_LOOKUP_new_null()) == NULL)
193
0
    goto err;
194
0
  if ((store->param = X509_VERIFY_PARAM_new()) == NULL)
195
0
    goto err;
196
197
0
  if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, store,
198
0
      &store->ex_data))
199
0
    goto err;
200
201
0
  store->references = 1;
202
203
0
  return store;
204
205
0
 err:
206
0
  X509error(ERR_R_MALLOC_FAILURE);
207
0
  X509_STORE_free(store);
208
209
0
  return NULL;
210
0
}
211
212
X509_OBJECT *
213
X509_OBJECT_new(void)
214
0
{
215
0
  X509_OBJECT *obj;
216
217
0
  if ((obj = calloc(1, sizeof(*obj))) == NULL) {
218
0
    X509error(ERR_R_MALLOC_FAILURE);
219
0
    return NULL;
220
0
  }
221
222
0
  obj->type = X509_LU_NONE;
223
224
0
  return obj;
225
0
}
226
227
void
228
X509_OBJECT_free(X509_OBJECT *a)
229
0
{
230
0
  if (a == NULL)
231
0
    return;
232
233
0
  switch (a->type) {
234
0
  case X509_LU_X509:
235
0
    X509_free(a->data.x509);
236
0
    break;
237
0
  case X509_LU_CRL:
238
0
    X509_CRL_free(a->data.crl);
239
0
    break;
240
0
  }
241
242
0
  free(a);
243
0
}
244
245
void
246
X509_STORE_free(X509_STORE *store)
247
0
{
248
0
  STACK_OF(X509_LOOKUP) *sk;
249
0
  X509_LOOKUP *lu;
250
0
  int i;
251
252
0
  if (store == NULL)
253
0
    return;
254
255
0
  if (CRYPTO_add(&store->references, -1, CRYPTO_LOCK_X509_STORE) > 0)
256
0
    return;
257
258
0
  sk = store->get_cert_methods;
259
0
  for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
260
0
    lu = sk_X509_LOOKUP_value(sk, i);
261
0
    X509_LOOKUP_shutdown(lu);
262
0
    X509_LOOKUP_free(lu);
263
0
  }
264
0
  sk_X509_LOOKUP_free(sk);
265
0
  sk_X509_OBJECT_pop_free(store->objs, X509_OBJECT_free);
266
267
0
  CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, store, &store->ex_data);
268
0
  X509_VERIFY_PARAM_free(store->param);
269
0
  free(store);
270
0
}
271
272
int
273
X509_STORE_up_ref(X509_STORE *store)
274
0
{
275
0
  return CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE) > 1;
276
0
}
277
278
X509_LOOKUP *
279
X509_STORE_add_lookup(X509_STORE *store, X509_LOOKUP_METHOD *method)
280
0
{
281
0
  STACK_OF(X509_LOOKUP) *sk;
282
0
  X509_LOOKUP *lu;
283
0
  int i;
284
285
0
  sk = store->get_cert_methods;
286
0
  for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
287
0
    lu = sk_X509_LOOKUP_value(sk, i);
288
0
    if (method == lu->method) {
289
0
      return lu;
290
0
    }
291
0
  }
292
293
0
  if ((lu = X509_LOOKUP_new(method)) == NULL)
294
0
    return NULL;
295
296
0
  lu->store_ctx = store;
297
0
  if (sk_X509_LOOKUP_push(store->get_cert_methods, lu) <= 0) {
298
0
    X509error(ERR_R_MALLOC_FAILURE);
299
0
    X509_LOOKUP_free(lu);
300
0
    return NULL;
301
0
  }
302
303
0
  return lu;
304
0
}
305
306
X509_OBJECT *
307
X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type,
308
    X509_NAME *name)
309
0
{
310
0
  X509_OBJECT *obj;
311
312
0
  if ((obj = X509_OBJECT_new()) == NULL)
313
0
    return NULL;
314
0
  if (!X509_STORE_CTX_get_by_subject(vs, type, name, obj)) {
315
0
    X509_OBJECT_free(obj);
316
0
    return NULL;
317
0
  }
318
319
0
  return obj;
320
0
}
321
322
int
323
X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type,
324
    X509_NAME *name, X509_OBJECT *ret)
325
0
{
326
0
  X509_STORE *ctx = vs->store;
327
0
  X509_LOOKUP *lu;
328
0
  X509_OBJECT stmp, *tmp;
329
0
  int i;
330
331
0
  if (ctx == NULL)
332
0
    return 0;
333
334
0
  memset(&stmp, 0, sizeof(stmp));
335
336
0
  CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
337
0
  tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name);
338
0
  CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
339
340
0
  if (tmp == NULL || type == X509_LU_CRL) {
341
0
    for (i = 0; i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) {
342
0
      lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i);
343
0
      if (X509_LOOKUP_by_subject(lu, type, name, &stmp) != 0) {
344
0
        tmp = &stmp;
345
0
        break;
346
0
      }
347
0
    }
348
0
    if (tmp == NULL)
349
0
      return 0;
350
0
  }
351
352
0
  if (!X509_OBJECT_up_ref_count(tmp))
353
0
    return 0;
354
355
0
  *ret = *tmp;
356
357
0
  return 1;
358
0
}
359
360
/* Add obj to the store. Takes ownership of obj. */
361
static int
362
X509_STORE_add_object(X509_STORE *store, X509_OBJECT *obj)
363
0
{
364
0
  int ret = 0;
365
366
0
  CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
367
368
0
  if (X509_OBJECT_retrieve_match(store->objs, obj) != NULL) {
369
    /* Object is already present in the store. That's fine. */
370
0
    ret = 1;
371
0
    goto out;
372
0
  }
373
374
0
  if (sk_X509_OBJECT_push(store->objs, obj) <= 0) {
375
0
    X509error(ERR_R_MALLOC_FAILURE);
376
0
    goto out;
377
0
  }
378
379
0
  obj = NULL;
380
0
  ret = 1;
381
382
0
 out:
383
0
  CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
384
0
  X509_OBJECT_free(obj);
385
386
0
  return ret;
387
0
}
388
389
int
390
X509_STORE_add_cert(X509_STORE *store, X509 *x)
391
0
{
392
0
  X509_OBJECT *obj;
393
394
0
  if (x == NULL)
395
0
    return 0;
396
397
0
  if ((obj = X509_OBJECT_new()) == NULL)
398
0
    return 0;
399
400
0
  if (!X509_up_ref(x)) {
401
0
    X509_OBJECT_free(obj);
402
0
    return 0;
403
0
  }
404
405
0
  obj->type = X509_LU_X509;
406
0
  obj->data.x509 = x;
407
408
0
  return X509_STORE_add_object(store, obj);
409
0
}
410
411
int
412
X509_STORE_add_crl(X509_STORE *store, X509_CRL *x)
413
0
{
414
0
  X509_OBJECT *obj;
415
416
0
  if (x == NULL)
417
0
    return 0;
418
419
0
  if ((obj = X509_OBJECT_new()) == NULL)
420
0
    return 0;
421
422
0
  if (!X509_CRL_up_ref(x)) {
423
0
    X509_OBJECT_free(obj);
424
0
    return 0;
425
0
  }
426
427
0
  obj->type = X509_LU_CRL;
428
0
  obj->data.crl = x;
429
430
0
  return X509_STORE_add_object(store, obj);
431
0
}
432
433
int
434
X509_OBJECT_up_ref_count(X509_OBJECT *a)
435
0
{
436
0
  switch (a->type) {
437
0
  case X509_LU_X509:
438
0
    return X509_up_ref(a->data.x509);
439
0
  case X509_LU_CRL:
440
0
    return X509_CRL_up_ref(a->data.crl);
441
0
  }
442
0
  return 1;
443
0
}
444
445
X509_LOOKUP_TYPE
446
X509_OBJECT_get_type(const X509_OBJECT *a)
447
0
{
448
0
  return a->type;
449
0
}
450
451
static int
452
x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
453
    X509_NAME *name, int *pnmatch)
454
0
{
455
0
  X509_OBJECT stmp;
456
0
  X509 x509_s;
457
0
  X509_CINF cinf_s;
458
0
  X509_CRL crl_s;
459
0
  X509_CRL_INFO crl_info_s;
460
0
  int idx;
461
462
0
  stmp.type = type;
463
0
  switch (type) {
464
0
  case X509_LU_X509:
465
0
    stmp.data.x509 = &x509_s;
466
0
    x509_s.cert_info = &cinf_s;
467
0
    cinf_s.subject = name;
468
0
    break;
469
0
  case X509_LU_CRL:
470
0
    stmp.data.crl = &crl_s;
471
0
    crl_s.crl = &crl_info_s;
472
0
    crl_info_s.issuer = name;
473
0
    break;
474
0
  default:
475
0
    return -1;
476
0
  }
477
478
0
  idx = sk_X509_OBJECT_find(h, &stmp);
479
0
  if (idx >= 0 && pnmatch) {
480
0
    int tidx;
481
0
    const X509_OBJECT *tobj, *pstmp;
482
483
0
    *pnmatch = 1;
484
0
    pstmp = &stmp;
485
0
    for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++) {
486
0
      tobj = sk_X509_OBJECT_value(h, tidx);
487
0
      if (x509_object_cmp(&tobj, &pstmp))
488
0
        break;
489
0
      (*pnmatch)++;
490
0
    }
491
0
  }
492
0
  return idx;
493
0
}
494
495
int
496
X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
497
    X509_NAME *name)
498
0
{
499
0
  return x509_object_idx_cnt(h, type, name, NULL);
500
0
}
501
502
X509_OBJECT *
503
X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
504
    X509_NAME *name)
505
0
{
506
0
  int idx;
507
508
0
  idx = X509_OBJECT_idx_by_subject(h, type, name);
509
0
  if (idx == -1)
510
0
    return NULL;
511
0
  return sk_X509_OBJECT_value(h, idx);
512
0
}
513
514
X509 *
515
X509_OBJECT_get0_X509(const X509_OBJECT *xo)
516
0
{
517
0
  if (xo != NULL && xo->type == X509_LU_X509)
518
0
    return xo->data.x509;
519
0
  return NULL;
520
0
}
521
522
X509_CRL *
523
X509_OBJECT_get0_X509_CRL(X509_OBJECT *xo)
524
0
{
525
0
  if (xo != NULL && xo->type == X509_LU_CRL)
526
0
    return xo->data.crl;
527
0
  return NULL;
528
0
}
529
530
static STACK_OF(X509) *
531
X509_get1_certs_from_cache(X509_STORE *store, X509_NAME *name)
532
0
{
533
0
  STACK_OF(X509) *sk = NULL;
534
0
  X509 *x = NULL;
535
0
  X509_OBJECT *obj;
536
0
  int i, idx, cnt;
537
538
0
  CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
539
540
0
  idx = x509_object_idx_cnt(store->objs, X509_LU_X509, name, &cnt);
541
0
  if (idx < 0)
542
0
    goto err;
543
544
0
  if ((sk = sk_X509_new_null()) == NULL)
545
0
    goto err;
546
547
0
  for (i = 0; i < cnt; i++, idx++) {
548
0
    obj = sk_X509_OBJECT_value(store->objs, idx);
549
550
0
    x = obj->data.x509;
551
0
    if (!X509_up_ref(x)) {
552
0
      x = NULL;
553
0
      goto err;
554
0
    }
555
0
    if (!sk_X509_push(sk, x))
556
0
      goto err;
557
0
  }
558
559
0
  CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
560
561
0
  return sk;
562
563
0
 err:
564
0
  CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
565
0
  sk_X509_pop_free(sk, X509_free);
566
0
  X509_free(x);
567
568
0
  return NULL;
569
0
}
570
571
STACK_OF(X509) *
572
X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *name)
573
0
{
574
0
  X509_STORE *store = ctx->store;
575
0
  STACK_OF(X509) *sk;
576
0
  X509_OBJECT *obj;
577
578
0
  if (store == NULL)
579
0
    return NULL;
580
581
0
  if ((sk = X509_get1_certs_from_cache(store, name)) != NULL)
582
0
    return sk;
583
584
  /* Nothing found: do lookup to possibly add new objects to cache. */
585
0
  obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_X509, name);
586
0
  if (obj == NULL)
587
0
    return NULL;
588
0
  X509_OBJECT_free(obj);
589
590
0
  return X509_get1_certs_from_cache(store, name);
591
0
}
592
593
STACK_OF(X509_CRL) *
594
X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *name)
595
0
{
596
0
  X509_STORE *store = ctx->store;
597
0
  STACK_OF(X509_CRL) *sk = NULL;
598
0
  X509_CRL *x = NULL;
599
0
  X509_OBJECT *obj = NULL;
600
0
  int i, idx, cnt;
601
602
0
  if (store == NULL)
603
0
    return NULL;
604
605
  /* Always do lookup to possibly add new CRLs to cache */
606
0
  obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_CRL, name);
607
0
  if (obj == NULL)
608
0
    return NULL;
609
610
0
  X509_OBJECT_free(obj);
611
0
  obj = NULL;
612
613
0
  CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
614
0
  idx = x509_object_idx_cnt(store->objs, X509_LU_CRL, name, &cnt);
615
0
  if (idx < 0)
616
0
    goto err;
617
618
0
  if ((sk = sk_X509_CRL_new_null()) == NULL)
619
0
    goto err;
620
621
0
  for (i = 0; i < cnt; i++, idx++) {
622
0
    obj = sk_X509_OBJECT_value(store->objs, idx);
623
624
0
    x = obj->data.crl;
625
0
    if (!X509_CRL_up_ref(x)) {
626
0
      x = NULL;
627
0
      goto err;
628
0
    }
629
0
    if (!sk_X509_CRL_push(sk, x))
630
0
      goto err;
631
0
  }
632
633
0
  CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
634
0
  return sk;
635
636
0
 err:
637
0
  CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
638
0
  X509_CRL_free(x);
639
0
  sk_X509_CRL_pop_free(sk, X509_CRL_free);
640
0
  return NULL;
641
0
}
642
643
X509_OBJECT *
644
X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x)
645
0
{
646
0
  int idx, i;
647
0
  X509_OBJECT *obj;
648
649
0
  idx = sk_X509_OBJECT_find(h, x);
650
0
  if (idx == -1)
651
0
    return NULL;
652
0
  if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
653
0
    return sk_X509_OBJECT_value(h, idx);
654
0
  for (i = idx; i < sk_X509_OBJECT_num(h); i++) {
655
0
    obj = sk_X509_OBJECT_value(h, i);
656
0
    if (x509_object_cmp((const X509_OBJECT **)&obj,
657
0
        (const X509_OBJECT **)&x))
658
0
      return NULL;
659
0
    if (x->type == X509_LU_X509) {
660
0
      if (!X509_cmp(obj->data.x509, x->data.x509))
661
0
        return obj;
662
0
    } else if (x->type == X509_LU_CRL) {
663
0
      if (!X509_CRL_match(obj->data.crl, x->data.crl))
664
0
        return obj;
665
0
    } else
666
0
      return obj;
667
0
  }
668
0
  return NULL;
669
0
}
670
671
/* Try to get issuer certificate from store. Due to limitations
672
 * of the API this can only retrieve a single certificate matching
673
 * a given subject name. However it will fill the cache with all
674
 * matching certificates, so we can examine the cache for all
675
 * matches.
676
 *
677
 * Return values are:
678
 *  1 lookup successful.
679
 *  0 certificate not found.
680
 * -1 some other error.
681
 */
682
int
683
X509_STORE_CTX_get1_issuer(X509 **out_issuer, X509_STORE_CTX *ctx, X509 *x)
684
0
{
685
0
  X509_NAME *xn;
686
0
  X509_OBJECT *obj, *pobj;
687
0
  X509 *issuer = NULL;
688
0
  int i, idx, ret;
689
690
0
  *out_issuer = NULL;
691
692
0
  xn = X509_get_issuer_name(x);
693
0
  obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_X509, xn);
694
0
  if (obj == NULL)
695
0
    return 0;
696
697
0
  if ((issuer = X509_OBJECT_get0_X509(obj)) == NULL) {
698
0
    X509_OBJECT_free(obj);
699
0
    return 0;
700
0
  }
701
0
  if (!X509_up_ref(issuer)) {
702
0
    X509_OBJECT_free(obj);
703
0
    return -1;
704
0
  }
705
706
  /* If certificate matches all OK */
707
0
  if (ctx->check_issued(ctx, x, issuer)) {
708
0
    if (x509_check_cert_time(ctx, issuer, -1)) {
709
0
      *out_issuer = issuer;
710
0
      X509_OBJECT_free(obj);
711
0
      return 1;
712
0
    }
713
0
  }
714
0
  X509_free(issuer);
715
0
  issuer = NULL;
716
0
  X509_OBJECT_free(obj);
717
0
  obj = NULL;
718
719
0
  if (ctx->store == NULL)
720
0
    return 0;
721
722
  /* Else find index of first cert accepted by 'check_issued' */
723
0
  CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
724
0
  idx = X509_OBJECT_idx_by_subject(ctx->store->objs, X509_LU_X509, xn);
725
0
  if (idx != -1) /* should be true as we've had at least one match */ {
726
    /* Look through all matching certs for suitable issuer */
727
0
    for (i = idx; i < sk_X509_OBJECT_num(ctx->store->objs); i++) {
728
0
      pobj = sk_X509_OBJECT_value(ctx->store->objs, i);
729
      /* See if we've run past the matches */
730
0
      if (pobj->type != X509_LU_X509)
731
0
        break;
732
0
      if (X509_NAME_cmp(xn,
733
0
          X509_get_subject_name(pobj->data.x509)))
734
0
        break;
735
0
      if (ctx->check_issued(ctx, x, pobj->data.x509)) {
736
0
        issuer = pobj->data.x509;
737
        /*
738
         * If times check, exit with match,
739
         * otherwise keep looking. Leave last
740
         * match in issuer so we return nearest
741
         * match if no certificate time is OK.
742
         */
743
0
        if (x509_check_cert_time(ctx, issuer, -1))
744
0
          break;
745
0
      }
746
0
    }
747
0
  }
748
0
  ret = 0;
749
0
  if (issuer != NULL) {
750
0
    if (!X509_up_ref(issuer)) {
751
0
      ret = -1;
752
0
    } else {
753
0
      *out_issuer = issuer;
754
0
      ret = 1;
755
0
    }
756
0
  }
757
0
  CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
758
0
  return ret;
759
0
}
760
761
STACK_OF(X509_OBJECT) *
762
X509_STORE_get0_objects(X509_STORE *xs)
763
0
{
764
0
  return xs->objs;
765
0
}
766
767
void *
768
X509_STORE_get_ex_data(X509_STORE *xs, int idx)
769
0
{
770
0
  return CRYPTO_get_ex_data(&xs->ex_data, idx);
771
0
}
772
773
int
774
X509_STORE_set_ex_data(X509_STORE *xs, int idx, void *data)
775
0
{
776
0
  return CRYPTO_set_ex_data(&xs->ex_data, idx, data);
777
0
}
778
779
int
780
X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
781
0
{
782
0
  return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
783
0
}
784
785
int
786
X509_STORE_set_depth(X509_STORE *ctx, int depth)
787
0
{
788
0
  X509_VERIFY_PARAM_set_depth(ctx->param, depth);
789
0
  return 1;
790
0
}
791
792
int
793
X509_STORE_set_purpose(X509_STORE *ctx, int purpose)
794
0
{
795
0
  return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
796
0
}
797
798
int
799
X509_STORE_set_trust(X509_STORE *ctx, int trust)
800
0
{
801
0
  return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
802
0
}
803
804
int
805
X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param)
806
0
{
807
0
  return X509_VERIFY_PARAM_set1(ctx->param, param);
808
0
}
809
810
X509_VERIFY_PARAM *
811
X509_STORE_get0_param(X509_STORE *ctx)
812
0
{
813
0
  return ctx->param;
814
0
}
815
816
void
817
X509_STORE_set_verify(X509_STORE *store, X509_STORE_CTX_verify_fn verify)
818
0
{
819
0
  store->verify = verify;
820
0
}
821
822
X509_STORE_CTX_verify_fn
823
X509_STORE_get_verify(X509_STORE *store)
824
0
{
825
0
  return store->verify;
826
0
}
827
828
void
829
X509_STORE_set_verify_cb(X509_STORE *store, X509_STORE_CTX_verify_cb verify_cb)
830
0
{
831
0
  store->verify_cb = verify_cb;
832
0
}
833
834
X509_STORE_CTX_verify_cb
835
X509_STORE_get_verify_cb(X509_STORE *store)
836
0
{
837
0
  return store->verify_cb;
838
0
}