Coverage Report

Created: 2026-08-14 07:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gnutls/lib/x509/verify-high.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2011-2016 Free Software Foundation, Inc.
3
 * Copyright (C) 2015-2016 Red Hat, Inc.
4
 *
5
 * Author: Nikos Mavrogiannopoulos
6
 *
7
 * This file is part of GnuTLS.
8
 *
9
 * The GnuTLS is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public License
11
 * as published by the Free Software Foundation; either version 2.1 of
12
 * the License, or (at your option) any later version.
13
 *
14
 * This library is distributed in the hope that it will be useful, but
15
 * WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
21
 *
22
 */
23
24
#include "gnutls_int.h"
25
#include "errors.h"
26
#include <libtasn1.h>
27
#include "global.h"
28
#include "num.h" /* MIN */
29
#include "tls-sig.h"
30
#include "str.h"
31
#include "datum.h"
32
#include "x509_int.h"
33
#include "common.h"
34
#include <gnutls/x509-ext.h>
35
#include "verify-high.h"
36
#include "intprops.h"
37
#include "gl_linkedhash_list.h"
38
#include "gl_list.h"
39
#include <hashcode-mem.h>
40
41
struct named_cert_st {
42
  gnutls_x509_crt_t cert;
43
  uint8_t name[MAX_SERVER_NAME_SIZE];
44
  unsigned int name_size;
45
};
46
47
struct node_st {
48
  /* The trusted certificates */
49
  gnutls_x509_crt_t *trusted_cas;
50
  unsigned int trusted_ca_size;
51
52
  struct named_cert_st *named_certs;
53
  unsigned int named_cert_size;
54
55
  /* The trusted CRLs */
56
  gnutls_x509_crl_t *crls;
57
  unsigned int crl_size;
58
};
59
60
struct gnutls_x509_trust_list_iter {
61
  unsigned int node_index;
62
  unsigned int ca_index;
63
64
#ifdef ENABLE_PKCS11
65
  gnutls_pkcs11_obj_t *pkcs11_list;
66
  unsigned int pkcs11_index;
67
  unsigned int pkcs11_size;
68
#endif
69
};
70
71
0
#define DEFAULT_SIZE 127
72
73
static bool cert_eq(const void *cert1, const void *cert2)
74
0
{
75
0
  const gnutls_x509_crt_t c1 = (const gnutls_x509_crt_t)cert1;
76
0
  const gnutls_x509_crt_t c2 = (const gnutls_x509_crt_t)cert2;
77
0
  return gnutls_x509_crt_equals(c1, c2);
78
0
}
79
80
static size_t cert_hashcode(const void *cert)
81
0
{
82
0
  const gnutls_x509_crt_t c = (const gnutls_x509_crt_t)cert;
83
0
  return hash_pjw_bare(c->raw_dn.data, c->raw_dn.size) %
84
0
         DEFAULT_MAX_VERIFY_DEPTH;
85
0
}
86
87
/**
88
 * gnutls_x509_trust_list_init:
89
 * @list: A pointer to the type to be initialized
90
 * @size: The size of the internal hash table. Use (0) for default size.
91
 *
92
 * This function will initialize an X.509 trust list structure.
93
 *
94
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
95
 *   negative error value.
96
 *
97
 * Since: 3.0.0
98
 **/
99
int gnutls_x509_trust_list_init(gnutls_x509_trust_list_t *list,
100
        unsigned int size)
101
0
{
102
0
  gnutls_x509_trust_list_t tmp;
103
104
0
  *list = NULL;
105
0
  FAIL_IF_LIB_ERROR;
106
107
0
  tmp = gnutls_calloc(1, sizeof(struct gnutls_x509_trust_list_st));
108
109
0
  if (!tmp)
110
0
    return GNUTLS_E_MEMORY_ERROR;
111
112
0
  if (size == 0)
113
0
    size = DEFAULT_SIZE;
114
0
  tmp->size = size;
115
116
0
  tmp->node = gnutls_calloc(1, tmp->size * sizeof(tmp->node[0]));
117
0
  if (tmp->node == NULL) {
118
0
    gnutls_assert();
119
0
    gnutls_free(tmp);
120
0
    return GNUTLS_E_MEMORY_ERROR;
121
0
  }
122
123
0
  *list = tmp;
124
125
0
  return 0; /* success */
126
0
}
127
128
/**
129
 * gnutls_x509_trust_list_deinit:
130
 * @list: The list to be deinitialized
131
 * @all: if non-zero it will deinitialize all the certificates and CRLs contained in the structure.
132
 *
133
 * This function will deinitialize a trust list. Note that the
134
 * @all flag should be typically non-zero unless you have specified
135
 * your certificates using gnutls_x509_trust_list_add_cas() and you
136
 * want to prevent them from being deinitialized by this function.
137
 *
138
 * Since: 3.0.0
139
 **/
140
void gnutls_x509_trust_list_deinit(gnutls_x509_trust_list_t list,
141
           unsigned int all)
142
0
{
143
0
  unsigned int i, j;
144
145
0
  if (!list)
146
0
    return;
147
148
0
  for (j = 0; j < list->distrusted_size; j++) {
149
0
    gnutls_x509_crt_deinit(list->distrusted[j]);
150
0
  }
151
0
  gnutls_free(list->distrusted);
152
153
0
  for (j = 0; j < list->keep_certs_size; j++) {
154
0
    gnutls_x509_crt_deinit(list->keep_certs[j]);
155
0
  }
156
0
  gnutls_free(list->keep_certs);
157
158
0
  for (i = 0; i < list->size; i++) {
159
0
    if (all) {
160
0
      for (j = 0; j < list->node[i].trusted_ca_size; j++) {
161
0
        gnutls_x509_crt_deinit(
162
0
          list->node[i].trusted_cas[j]);
163
0
      }
164
0
    }
165
0
    gnutls_free(list->node[i].trusted_cas);
166
167
0
    if (all) {
168
0
      for (j = 0; j < list->node[i].crl_size; j++) {
169
0
        gnutls_x509_crl_deinit(list->node[i].crls[j]);
170
0
      }
171
0
    }
172
0
    gnutls_free(list->node[i].crls);
173
174
0
    if (all) {
175
0
      for (j = 0; j < list->node[i].named_cert_size; j++) {
176
0
        gnutls_x509_crt_deinit(
177
0
          list->node[i].named_certs[j].cert);
178
0
      }
179
0
    }
180
0
    gnutls_free(list->node[i].named_certs);
181
0
  }
182
183
0
  gnutls_free(list->x509_rdn_sequence.data);
184
0
  gnutls_free(list->node);
185
0
  gnutls_free(list->pkcs11_token);
186
0
  gnutls_free(list);
187
0
}
188
189
static int add_new_ca_to_rdn_seq(gnutls_x509_trust_list_t list,
190
         gnutls_x509_crt_t ca)
191
0
{
192
0
  gnutls_datum_t tmp;
193
0
  size_t newsize;
194
0
  unsigned char *newdata, *p;
195
196
  /* Add DN of the last added CAs to the RDN sequence
197
   * This will be sent to clients when a certificate
198
   * request message is sent.
199
   */
200
0
  tmp.data = ca->raw_dn.data;
201
0
  tmp.size = ca->raw_dn.size;
202
203
0
  newsize = list->x509_rdn_sequence.size + 2 + tmp.size;
204
0
  if (newsize < list->x509_rdn_sequence.size) {
205
0
    gnutls_assert();
206
0
    return GNUTLS_E_SHORT_MEMORY_BUFFER;
207
0
  }
208
209
0
  newdata = gnutls_realloc_fast(list->x509_rdn_sequence.data, newsize);
210
0
  if (newdata == NULL) {
211
0
    gnutls_assert();
212
0
    return GNUTLS_E_MEMORY_ERROR;
213
0
  }
214
215
0
  p = newdata + list->x509_rdn_sequence.size;
216
0
  _gnutls_write_uint16(tmp.size, p);
217
0
  if (tmp.data != NULL)
218
0
    memcpy(p + 2, tmp.data, tmp.size);
219
220
0
  list->x509_rdn_sequence.size = newsize;
221
0
  list->x509_rdn_sequence.data = newdata;
222
223
0
  return 0;
224
0
}
225
226
#ifdef ENABLE_PKCS11
227
/* Keeps the provided certificate in a structure that will be
228
 * deallocated on deinit. This is to handle get_issuer() with
229
 * pkcs11 trust modules when the GNUTLS_TL_GET_COPY flag isn't
230
 * given. It is not thread safe. */
231
static int trust_list_add_compat(gnutls_x509_trust_list_t list,
232
         gnutls_x509_crt_t cert)
233
{
234
  if (unlikely(INT_ADD_OVERFLOW(list->keep_certs_size, 1))) {
235
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
236
  }
237
238
  list->keep_certs = _gnutls_reallocarray_fast(
239
    list->keep_certs, list->keep_certs_size + 1,
240
    sizeof(list->keep_certs[0]));
241
  if (list->keep_certs == NULL) {
242
    gnutls_assert();
243
    return GNUTLS_E_MEMORY_ERROR;
244
  }
245
246
  list->keep_certs[list->keep_certs_size] = cert;
247
  list->keep_certs_size++;
248
249
  return 0;
250
}
251
#endif
252
253
/**
254
 * gnutls_x509_trust_list_add_cas:
255
 * @list: The list
256
 * @clist: A list of CAs
257
 * @clist_size: The length of the CA list
258
 * @flags: flags from %gnutls_trust_list_flags_t
259
 *
260
 * This function will add the given certificate authorities
261
 * to the trusted list. The CAs in @clist must not be deinitialized
262
 * during the lifetime of @list.
263
 *
264
 * If the flag %GNUTLS_TL_NO_DUPLICATES is specified, then
265
 * this function will ensure that no duplicates will be
266
 * present in the final trust list.
267
 *
268
 * If the flag %GNUTLS_TL_NO_DUPLICATE_KEY is specified, then
269
 * this function will ensure that no certificates with the
270
 * same key are present in the final trust list.
271
 *
272
 * If either %GNUTLS_TL_NO_DUPLICATE_KEY or %GNUTLS_TL_NO_DUPLICATES
273
 * are given, gnutls_x509_trust_list_deinit() must be called with parameter
274
 * @all being 1.
275
 *
276
 * Returns: The number of added elements is returned; that includes
277
 *          duplicate entries.
278
 *
279
 * Since: 3.0.0
280
 **/
281
int gnutls_x509_trust_list_add_cas(gnutls_x509_trust_list_t list,
282
           const gnutls_x509_crt_t *clist,
283
           unsigned clist_size, unsigned int flags)
284
0
{
285
0
  unsigned i, j;
286
0
  size_t hash;
287
0
  int ret;
288
0
  unsigned exists;
289
290
0
  for (i = 0; i < clist_size; i++) {
291
0
    exists = 0;
292
0
    hash = hash_pjw_bare(clist[i]->raw_dn.data,
293
0
             clist[i]->raw_dn.size);
294
0
    hash %= list->size;
295
296
    /* avoid duplicates */
297
0
    if (flags & GNUTLS_TL_NO_DUPLICATES ||
298
0
        flags & GNUTLS_TL_NO_DUPLICATE_KEY) {
299
0
      for (j = 0; j < list->node[hash].trusted_ca_size; j++) {
300
0
        if (flags & GNUTLS_TL_NO_DUPLICATES)
301
0
          ret = gnutls_x509_crt_equals(
302
0
            list->node[hash].trusted_cas[j],
303
0
            clist[i]);
304
0
        else
305
0
          ret = _gnutls_check_if_same_key(
306
0
            list->node[hash].trusted_cas[j],
307
0
            clist[i], 1);
308
0
        if (ret != 0) {
309
0
          exists = 1;
310
0
          break;
311
0
        }
312
0
      }
313
314
0
      if (exists != 0) {
315
0
        gnutls_x509_crt_deinit(
316
0
          list->node[hash].trusted_cas[j]);
317
0
        list->node[hash].trusted_cas[j] = clist[i];
318
0
        continue;
319
0
      }
320
0
    }
321
322
0
    if (unlikely(INT_ADD_OVERFLOW(list->node[hash].trusted_ca_size,
323
0
                1))) {
324
0
      gnutls_assert();
325
0
      return i;
326
0
    }
327
328
0
    list->node[hash].trusted_cas = _gnutls_reallocarray_fast(
329
0
      list->node[hash].trusted_cas,
330
0
      list->node[hash].trusted_ca_size + 1,
331
0
      sizeof(list->node[hash].trusted_cas[0]));
332
0
    if (list->node[hash].trusted_cas == NULL) {
333
0
      gnutls_assert();
334
0
      return i;
335
0
    }
336
337
0
    if (gnutls_x509_crt_get_version(clist[i]) >= 3 &&
338
0
        gnutls_x509_crt_get_ca_status(clist[i], NULL) <= 0) {
339
0
      gnutls_datum_t dn;
340
0
      gnutls_assert();
341
0
      if (gnutls_x509_crt_get_dn2(clist[i], &dn) >= 0) {
342
0
        _gnutls_audit_log(
343
0
          NULL,
344
0
          "There was a non-CA certificate in the trusted list: %s.\n",
345
0
          dn.data);
346
0
        gnutls_free(dn.data);
347
0
      }
348
0
    }
349
350
0
    list->node[hash].trusted_cas[list->node[hash].trusted_ca_size] =
351
0
      clist[i];
352
0
    list->node[hash].trusted_ca_size++;
353
354
0
    if (flags & GNUTLS_TL_USE_IN_TLS) {
355
0
      ret = add_new_ca_to_rdn_seq(list, clist[i]);
356
0
      if (ret < 0) {
357
0
        gnutls_assert();
358
0
        return i + 1;
359
0
      }
360
0
    }
361
0
  }
362
363
0
  return i;
364
0
}
365
366
static int advance_iter(gnutls_x509_trust_list_t list,
367
      gnutls_x509_trust_list_iter_t iter)
368
0
{
369
0
  if (iter->node_index < list->size) {
370
0
    ++iter->ca_index;
371
372
    /* skip entries */
373
0
    while (iter->node_index < list->size &&
374
0
           iter->ca_index >=
375
0
             list->node[iter->node_index].trusted_ca_size) {
376
0
      ++iter->node_index;
377
0
      iter->ca_index = 0;
378
0
    }
379
380
0
    if (iter->node_index < list->size)
381
0
      return 0;
382
0
  }
383
384
#ifdef ENABLE_PKCS11
385
  if (list->pkcs11_token != NULL) {
386
    if (iter->pkcs11_list == NULL) {
387
      int ret = gnutls_pkcs11_obj_list_import_url2(
388
        &iter->pkcs11_list, &iter->pkcs11_size,
389
        list->pkcs11_token,
390
        (GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE |
391
         GNUTLS_PKCS11_OBJ_FLAG_CRT |
392
         GNUTLS_PKCS11_OBJ_FLAG_MARK_CA |
393
         GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED),
394
        0);
395
      if (ret < 0)
396
        return gnutls_assert_val(ret);
397
398
      if (iter->pkcs11_size > 0)
399
        return 0;
400
    } else if (iter->pkcs11_index < iter->pkcs11_size) {
401
      ++iter->pkcs11_index;
402
      if (iter->pkcs11_index < iter->pkcs11_size)
403
        return 0;
404
    }
405
  }
406
#endif
407
408
0
  return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
409
0
}
410
411
/**
412
 * gnutls_x509_trust_list_iter_get_ca:
413
 * @list: The list
414
 * @iter: A pointer to an iterator (initially the iterator should be %NULL)
415
 * @crt: where the certificate will be copied
416
 *
417
 * This function obtains a certificate in the trust list and advances the
418
 * iterator to the next certificate. The certificate returned in @crt must be
419
 * deallocated with gnutls_x509_crt_deinit().
420
 *
421
 * When past the last element is accessed %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
422
 * is returned and the iterator is reset.
423
 *
424
 * The iterator is deinitialized and reset to %NULL automatically by this
425
 * function after iterating through all elements until
426
 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned. If the iteration is
427
 * aborted early, it must be manually deinitialized using
428
 * gnutls_x509_trust_list_iter_deinit().
429
 *
430
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
431
 *   negative error value.
432
 *
433
 * Since: 3.4.0
434
 **/
435
int gnutls_x509_trust_list_iter_get_ca(gnutls_x509_trust_list_t list,
436
               gnutls_x509_trust_list_iter_t *iter,
437
               gnutls_x509_crt_t *crt)
438
0
{
439
0
  int ret;
440
441
  /* initialize iterator */
442
0
  if (*iter == NULL) {
443
0
    *iter = gnutls_malloc(
444
0
      sizeof(struct gnutls_x509_trust_list_iter));
445
0
    if (*iter == NULL)
446
0
      return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
447
448
0
    (*iter)->node_index = 0;
449
0
    (*iter)->ca_index = 0;
450
451
#ifdef ENABLE_PKCS11
452
    (*iter)->pkcs11_list = NULL;
453
    (*iter)->pkcs11_size = 0;
454
    (*iter)->pkcs11_index = 0;
455
#endif
456
457
    /* Advance iterator to the first valid entry */
458
0
    if (list->node[0].trusted_ca_size == 0) {
459
0
      ret = advance_iter(list, *iter);
460
0
      if (ret != 0) {
461
0
        gnutls_x509_trust_list_iter_deinit(*iter);
462
0
        *iter = NULL;
463
464
0
        *crt = NULL;
465
0
        return gnutls_assert_val(ret);
466
0
      }
467
0
    }
468
0
  }
469
470
  /* obtain the certificate at the current iterator position */
471
0
  if ((*iter)->node_index < list->size) {
472
0
    ret = gnutls_x509_crt_init(crt);
473
0
    if (ret < 0)
474
0
      return gnutls_assert_val(ret);
475
476
0
    ret = _gnutls_x509_crt_cpy(
477
0
      *crt, list->node[(*iter)->node_index]
478
0
              .trusted_cas[(*iter)->ca_index]);
479
0
    if (ret < 0) {
480
0
      gnutls_x509_crt_deinit(*crt);
481
0
      return gnutls_assert_val(ret);
482
0
    }
483
0
  }
484
#ifdef ENABLE_PKCS11
485
  else if ((*iter)->pkcs11_index < (*iter)->pkcs11_size) {
486
    ret = gnutls_x509_crt_init(crt);
487
    if (ret < 0)
488
      return gnutls_assert_val(ret);
489
490
    ret = gnutls_x509_crt_import_pkcs11(
491
      *crt, (*iter)->pkcs11_list[(*iter)->pkcs11_index]);
492
    if (ret < 0) {
493
      gnutls_x509_crt_deinit(*crt);
494
      return gnutls_assert_val(ret);
495
    }
496
  }
497
#endif
498
499
0
  else {
500
    /* iterator is at end */
501
0
    gnutls_x509_trust_list_iter_deinit(*iter);
502
0
    *iter = NULL;
503
504
0
    *crt = NULL;
505
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
506
0
  }
507
508
  /* Move iterator to the next position.
509
   * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned if the iterator
510
   * has been moved to the end position. That is okay, we return the
511
   * certificate that we read and when this function is called again we
512
   * report GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE to our caller. */
513
0
  ret = advance_iter(list, *iter);
514
0
  if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
515
0
    gnutls_x509_crt_deinit(*crt);
516
0
    *crt = NULL;
517
518
0
    return gnutls_assert_val(ret);
519
0
  }
520
521
0
  return 0;
522
0
}
523
524
/**
525
 * gnutls_x509_trust_list_iter_deinit:
526
 * @iter: The iterator structure to be deinitialized
527
 *
528
 * This function will deinitialize an iterator structure.
529
 *
530
 * Since: 3.4.0
531
 **/
532
void gnutls_x509_trust_list_iter_deinit(gnutls_x509_trust_list_iter_t iter)
533
0
{
534
0
  if (!iter)
535
0
    return;
536
537
#ifdef ENABLE_PKCS11
538
  if (iter->pkcs11_size > 0) {
539
    unsigned i;
540
    for (i = 0; i < iter->pkcs11_size; ++i)
541
      gnutls_pkcs11_obj_deinit(iter->pkcs11_list[i]);
542
    gnutls_free(iter->pkcs11_list);
543
  }
544
#endif
545
546
0
  gnutls_free(iter);
547
0
}
548
549
static gnutls_x509_crt_t crt_cpy(gnutls_x509_crt_t src)
550
0
{
551
0
  gnutls_x509_crt_t dst;
552
0
  int ret;
553
554
0
  ret = gnutls_x509_crt_init(&dst);
555
0
  if (ret < 0) {
556
0
    gnutls_assert();
557
0
    return NULL;
558
0
  }
559
560
0
  ret = _gnutls_x509_crt_cpy(dst, src);
561
0
  if (ret < 0) {
562
0
    gnutls_x509_crt_deinit(dst);
563
0
    gnutls_assert();
564
0
    return NULL;
565
0
  }
566
567
0
  return dst;
568
0
}
569
570
/**
571
 * gnutls_x509_trust_list_remove_cas:
572
 * @list: The list
573
 * @clist: A list of CAs
574
 * @clist_size: The length of the CA list
575
 *
576
 * This function will remove the given certificate authorities
577
 * from the trusted list.
578
 *
579
 * Note that this function can accept certificates and authorities
580
 * not yet known. In that case they will be kept in a separate
581
 * block list that will be used during certificate verification.
582
 * Unlike gnutls_x509_trust_list_add_cas() there is no deinitialization
583
 * restriction for  certificate list provided in this function.
584
 *
585
 * Returns: The number of removed elements is returned.
586
 *
587
 * Since: 3.1.10
588
 **/
589
int gnutls_x509_trust_list_remove_cas(gnutls_x509_trust_list_t list,
590
              const gnutls_x509_crt_t *clist,
591
              unsigned clist_size)
592
0
{
593
0
  int r = 0;
594
0
  unsigned j, i;
595
0
  size_t hash;
596
597
0
  for (i = 0; i < clist_size; i++) {
598
0
    hash = hash_pjw_bare(clist[i]->raw_dn.data,
599
0
             clist[i]->raw_dn.size);
600
0
    hash %= list->size;
601
602
0
    for (j = 0; j < list->node[hash].trusted_ca_size; j++) {
603
0
      if (gnutls_x509_crt_equals(
604
0
            clist[i],
605
0
            list->node[hash].trusted_cas[j]) != 0) {
606
0
        gnutls_x509_crt_deinit(
607
0
          list->node[hash].trusted_cas[j]);
608
0
        list->node[hash].trusted_cas[j] =
609
0
          list->node[hash].trusted_cas
610
0
            [list->node[hash]
611
0
               .trusted_ca_size -
612
0
             1];
613
0
        list->node[hash].trusted_ca_size--;
614
0
        r++;
615
0
        break;
616
0
      }
617
0
    }
618
619
0
    if (unlikely(INT_ADD_OVERFLOW(list->distrusted_size, 1))) {
620
0
      return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
621
0
    }
622
623
    /* Add the CA (or plain) certificate to the block list as well.
624
     * This will prevent a subordinate CA from being valid, and
625
     * ensure that a server certificate will also get rejected.
626
     */
627
0
    list->distrusted = _gnutls_reallocarray_fast(
628
0
      list->distrusted, list->distrusted_size + 1,
629
0
      sizeof(list->distrusted[0]));
630
0
    if (list->distrusted == NULL)
631
0
      return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
632
633
0
    list->distrusted[list->distrusted_size] = crt_cpy(clist[i]);
634
0
    if (list->distrusted[list->distrusted_size] != NULL)
635
0
      list->distrusted_size++;
636
0
  }
637
638
0
  return r;
639
0
}
640
641
/**
642
 * gnutls_x509_trust_list_add_named_crt:
643
 * @list: The list
644
 * @cert: A certificate
645
 * @name: An identifier for the certificate
646
 * @name_size: The size of the identifier
647
 * @flags: should be 0.
648
 *
649
 * This function will add the given certificate to the trusted
650
 * list and associate it with a name. The certificate will not be
651
 * be used for verification with gnutls_x509_trust_list_verify_crt()
652
 * but with gnutls_x509_trust_list_verify_named_crt() or
653
 * gnutls_x509_trust_list_verify_crt2() - the latter only since
654
 * GnuTLS 3.4.0 and if a hostname is provided.
655
 *
656
 * In principle this function can be used to set individual "server"
657
 * certificates that are trusted by the user for that specific server
658
 * but for no other purposes.
659
 *
660
 * The certificate @cert must not be deinitialized during the lifetime
661
 * of the @list.
662
 *
663
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
664
 *   negative error value.
665
 *
666
 * Since: 3.0.0
667
 **/
668
int gnutls_x509_trust_list_add_named_crt(gnutls_x509_trust_list_t list,
669
           gnutls_x509_crt_t cert,
670
           const void *name, size_t name_size,
671
           unsigned int flags)
672
0
{
673
0
  size_t hash;
674
675
0
  if (name_size >= MAX_SERVER_NAME_SIZE)
676
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
677
678
0
  hash = hash_pjw_bare(cert->raw_issuer_dn.data,
679
0
           cert->raw_issuer_dn.size);
680
0
  hash %= list->size;
681
682
0
  if (unlikely(INT_ADD_OVERFLOW(list->node[hash].named_cert_size, 1))) {
683
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
684
0
  }
685
686
0
  list->node[hash].named_certs = _gnutls_reallocarray_fast(
687
0
    list->node[hash].named_certs,
688
0
    list->node[hash].named_cert_size + 1,
689
0
    sizeof(list->node[hash].named_certs[0]));
690
0
  if (list->node[hash].named_certs == NULL)
691
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
692
693
0
  list->node[hash].named_certs[list->node[hash].named_cert_size].cert =
694
0
    cert;
695
0
  memcpy(list->node[hash]
696
0
           .named_certs[list->node[hash].named_cert_size]
697
0
           .name,
698
0
         name, name_size);
699
0
  list->node[hash]
700
0
    .named_certs[list->node[hash].named_cert_size]
701
0
    .name_size = name_size;
702
703
0
  list->node[hash].named_cert_size++;
704
705
0
  return 0;
706
0
}
707
708
/**
709
 * gnutls_x509_trust_list_add_crls:
710
 * @list: The list
711
 * @crl_list: A list of CRLs
712
 * @crl_size: The length of the CRL list
713
 * @flags: flags from %gnutls_trust_list_flags_t
714
 * @verification_flags: gnutls_certificate_verify_flags if flags specifies GNUTLS_TL_VERIFY_CRL
715
 *
716
 * This function will add the given certificate revocation lists
717
 * to the trusted list. The CRLs in @crl_list must not be deinitialized
718
 * during the lifetime of @list.
719
 *
720
 * This function must be called after gnutls_x509_trust_list_add_cas()
721
 * to allow verifying the CRLs for validity. If the flag %GNUTLS_TL_NO_DUPLICATES
722
 * is given, then the final CRL list will not contain duplicate entries.
723
 *
724
 * If the flag %GNUTLS_TL_NO_DUPLICATES is given, gnutls_x509_trust_list_deinit() must be
725
 * called with parameter @all being 1.
726
 *
727
 * If flag %GNUTLS_TL_VERIFY_CRL is given the CRLs will be verified before being added,
728
 * and if verification fails, they will be skipped.
729
 *
730
 * Returns: The number of added elements is returned; that includes
731
 *          duplicate entries.
732
 *
733
 * Since: 3.0
734
 **/
735
int gnutls_x509_trust_list_add_crls(gnutls_x509_trust_list_t list,
736
            const gnutls_x509_crl_t *crl_list,
737
            unsigned crl_size, unsigned int flags,
738
            unsigned int verification_flags)
739
0
{
740
0
  int ret;
741
0
  unsigned x, i, j = 0;
742
0
  unsigned int vret = 0;
743
0
  size_t hash;
744
0
  gnutls_x509_crl_t *tmp;
745
746
  /* Probably we can optimize things such as removing duplicates
747
   * etc.
748
   */
749
0
  if (crl_size == 0 || crl_list == NULL)
750
0
    return 0;
751
752
0
  for (i = 0; i < crl_size; i++) {
753
0
    hash = hash_pjw_bare(crl_list[i]->raw_issuer_dn.data,
754
0
             crl_list[i]->raw_issuer_dn.size);
755
0
    hash %= list->size;
756
757
0
    if (flags & GNUTLS_TL_VERIFY_CRL) {
758
0
      ret = gnutls_x509_crl_verify(
759
0
        crl_list[i], list->node[hash].trusted_cas,
760
0
        list->node[hash].trusted_ca_size,
761
0
        verification_flags, &vret);
762
0
      if (ret < 0 || vret != 0) {
763
0
        _gnutls_debug_log(
764
0
          "CRL verification failed, not adding it\n");
765
0
        if (flags & GNUTLS_TL_NO_DUPLICATES)
766
0
          gnutls_x509_crl_deinit(crl_list[i]);
767
0
        if (flags & GNUTLS_TL_FAIL_ON_INVALID_CRL)
768
0
          return gnutls_assert_val(
769
0
            GNUTLS_E_CRL_VERIFICATION_ERROR);
770
0
        continue;
771
0
      }
772
0
    }
773
774
    /* If the CRL added overrides a previous one, then overwrite
775
     * the old one */
776
0
    if (flags & GNUTLS_TL_NO_DUPLICATES) {
777
0
      for (x = 0; x < list->node[hash].crl_size; x++) {
778
0
        if (crl_list[i]->raw_issuer_dn.size ==
779
0
              list->node[hash]
780
0
                .crls[x]
781
0
                ->raw_issuer_dn.size &&
782
0
            memeq(crl_list[i]->raw_issuer_dn.data,
783
0
            list->node[hash]
784
0
              .crls[x]
785
0
              ->raw_issuer_dn.data,
786
0
            crl_list[i]->raw_issuer_dn.size)) {
787
0
          if (gnutls_x509_crl_get_this_update(
788
0
                crl_list[i]) >=
789
0
              gnutls_x509_crl_get_this_update(
790
0
                list->node[hash].crls[x])) {
791
0
            gnutls_x509_crl_deinit(
792
0
              list->node[hash]
793
0
                .crls[x]);
794
0
            list->node[hash].crls[x] =
795
0
              crl_list[i];
796
0
            goto next;
797
0
          } else {
798
            /* The new is older, discard it */
799
0
            gnutls_x509_crl_deinit(
800
0
              crl_list[i]);
801
0
            goto next;
802
0
          }
803
0
        }
804
0
      }
805
0
    }
806
807
0
    if (unlikely(INT_ADD_OVERFLOW(list->node[hash].crl_size, 1))) {
808
0
      gnutls_assert();
809
0
      goto error;
810
0
    }
811
812
0
    tmp = _gnutls_reallocarray(list->node[hash].crls,
813
0
             list->node[hash].crl_size + 1,
814
0
             sizeof(list->node[hash].crls[0]));
815
0
    if (tmp == NULL) {
816
0
      gnutls_assert();
817
0
      goto error;
818
0
    }
819
0
    list->node[hash].crls = tmp;
820
821
0
    list->node[hash].crls[list->node[hash].crl_size] = crl_list[i];
822
0
    list->node[hash].crl_size++;
823
824
0
  next:
825
0
    j++;
826
0
  }
827
828
0
  return j;
829
830
0
error:
831
0
  ret = i;
832
0
  if (flags & GNUTLS_TL_NO_DUPLICATES)
833
0
    while (i < crl_size)
834
0
      gnutls_x509_crl_deinit(crl_list[i++]);
835
0
  return ret;
836
0
}
837
838
/* Takes a certificate list and shortens it if there are
839
 * intermedia certificates already trusted by us.
840
 *
841
 * Returns the new size of the list or a negative number on error.
842
 */
843
static int shorten_clist(gnutls_x509_trust_list_t list,
844
       gnutls_x509_crt_t *certificate_list,
845
       unsigned int clist_size)
846
0
{
847
0
  unsigned int j, i;
848
0
  size_t hash;
849
850
0
  if (clist_size > 1) {
851
    /* Check if the last certificate in the path is self signed.
852
     * In that case ignore it (a certificate is trusted only if it
853
     * leads to a trusted party by us, not the server's).
854
     *
855
     * This prevents from verifying self signed certificates against
856
     * themselves. This (although not bad) caused verification
857
     * failures on some root self signed certificates that use the
858
     * MD2 algorithm.
859
     */
860
0
    if (gnutls_x509_crt_check_issuer(
861
0
          certificate_list[clist_size - 1],
862
0
          certificate_list[clist_size - 1]) != 0) {
863
0
      clist_size--;
864
0
    }
865
0
  }
866
867
  /* We want to shorten the chain by removing the cert that matches
868
   * one of the certs we trust and all the certs after that i.e. if
869
   * cert chain is A signed-by B signed-by C signed-by D (signed-by
870
   * self-signed E but already removed above), and we trust B, remove
871
   * B, C and D. */
872
0
  for (i = 1; i < clist_size; i++) {
873
0
    hash = hash_pjw_bare(certificate_list[i]->raw_issuer_dn.data,
874
0
             certificate_list[i]->raw_issuer_dn.size);
875
0
    hash %= list->size;
876
877
0
    for (j = 0; j < list->node[hash].trusted_ca_size; j++) {
878
0
      if (gnutls_x509_crt_equals(
879
0
            certificate_list[i],
880
0
            list->node[hash].trusted_cas[j]) != 0) {
881
        /* cut the list at the point of first the trusted certificate */
882
0
        clist_size = i + 1;
883
0
        break;
884
0
      }
885
0
    }
886
    /* clist_size may have been changed which gets out of loop */
887
0
  }
888
889
0
  return clist_size;
890
0
}
891
892
/* Takes a subject certificate, retrieves a chain from its issuers in
893
 * @certificate_list, using the issuer callback set for @list.
894
 *
895
 * Returns the new size of the list or a negative number on error.
896
 */
897
static int retrieve_issuers(gnutls_x509_trust_list_t list,
898
          gnutls_x509_crt_t subject,
899
          gnutls_x509_crt_t *certificate_list,
900
          unsigned int clist_size_max)
901
0
{
902
0
  gnutls_x509_crt_t *issuers;
903
0
  unsigned int issuers_size;
904
0
  unsigned int i;
905
0
  int ret;
906
907
0
  if (!list->issuer_callback) {
908
0
    return 0;
909
0
  }
910
911
0
  _gnutls_cert_log("calling issuer callback on", subject);
912
913
0
  ret = list->issuer_callback(list, subject, &issuers, &issuers_size);
914
0
  if (ret < 0) {
915
0
    return gnutls_assert_val(ret);
916
0
  }
917
918
  /* Ignore empty list */
919
0
  if (!issuers_size) {
920
0
    ret = 0;
921
0
    goto cleanup;
922
0
  }
923
924
0
  if (issuers_size > clist_size_max) {
925
0
    _gnutls_debug_log("too many issuers returned; skipping\n");
926
0
    ret = 0;
927
0
    goto cleanup;
928
0
  }
929
930
0
  for (i = 0; i < issuers_size; i++) {
931
0
    if (!gnutls_x509_crt_check_issuer(subject, issuers[i])) {
932
0
      _gnutls_cert_log("unrelated certificate; skipping",
933
0
           issuers[i]);
934
0
      break;
935
0
    }
936
0
    subject = issuers[i];
937
0
  }
938
939
0
  ret = i;
940
941
0
  memcpy(certificate_list, issuers, ret * sizeof(gnutls_x509_crt_t));
942
943
0
cleanup:
944
0
  for (i = ret; i < issuers_size; i++) {
945
0
    gnutls_x509_crt_deinit(issuers[i]);
946
0
  }
947
0
  gnutls_free(issuers);
948
949
0
  return ret;
950
0
}
951
952
int _gnutls_trust_list_get_issuer(gnutls_x509_trust_list_t list,
953
          gnutls_x509_crt_t cert,
954
          gnutls_x509_crt_t *issuer, unsigned int flags)
955
0
{
956
0
  int ret;
957
0
  unsigned int i;
958
0
  size_t hash;
959
960
0
  hash = hash_pjw_bare(cert->raw_issuer_dn.data,
961
0
           cert->raw_issuer_dn.size);
962
0
  hash %= list->size;
963
964
0
  for (i = 0; i < list->node[hash].trusted_ca_size; i++) {
965
0
    ret = gnutls_x509_crt_check_issuer(
966
0
      cert, list->node[hash].trusted_cas[i]);
967
0
    if (ret != 0) {
968
0
      if (flags & GNUTLS_TL_GET_COPY) {
969
0
        *issuer = crt_cpy(
970
0
          list->node[hash].trusted_cas[i]);
971
0
      } else {
972
0
        *issuer = list->node[hash].trusted_cas[i];
973
0
      }
974
0
      return 0;
975
0
    }
976
0
  }
977
978
0
  return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
979
0
}
980
981
static int trust_list_get_issuer_by_dn(gnutls_x509_trust_list_t list,
982
               const gnutls_datum_t *dn,
983
               const gnutls_datum_t *spki,
984
               gnutls_x509_crt_t *issuer,
985
               unsigned int flags)
986
0
{
987
0
  int ret;
988
0
  unsigned int i, j;
989
0
  size_t hash;
990
0
  uint8_t tmp[256];
991
0
  size_t tmp_size;
992
993
0
  if (dn) {
994
0
    hash = hash_pjw_bare(dn->data, dn->size);
995
0
    hash %= list->size;
996
997
0
    for (i = 0; i < list->node[hash].trusted_ca_size; i++) {
998
0
      ret = _gnutls_x509_compare_raw_dn(
999
0
        dn, &list->node[hash].trusted_cas[i]->raw_dn);
1000
0
      if (ret != 0) {
1001
0
        if (spki && spki->size > 0) {
1002
0
          tmp_size = sizeof(tmp);
1003
1004
0
          ret = gnutls_x509_crt_get_subject_key_id(
1005
0
            list->node[hash].trusted_cas[i],
1006
0
            tmp, &tmp_size, NULL);
1007
0
          if (ret < 0)
1008
0
            continue;
1009
0
          if (spki->size != tmp_size ||
1010
0
              !memeq(spki->data, tmp, spki->size))
1011
0
            continue;
1012
0
        }
1013
0
        *issuer = crt_cpy(
1014
0
          list->node[hash].trusted_cas[i]);
1015
0
        return 0;
1016
0
      }
1017
0
    }
1018
0
  } else if (spki) {
1019
    /* search everything! */
1020
0
    for (i = 0; i < list->size; i++) {
1021
0
      for (j = 0; j < list->node[i].trusted_ca_size; j++) {
1022
0
        tmp_size = sizeof(tmp);
1023
1024
0
        ret = gnutls_x509_crt_get_subject_key_id(
1025
0
          list->node[i].trusted_cas[j], tmp,
1026
0
          &tmp_size, NULL);
1027
0
        if (ret < 0)
1028
0
          continue;
1029
1030
0
        if (spki->size != tmp_size ||
1031
0
            !memeq(spki->data, tmp, spki->size))
1032
0
          continue;
1033
1034
0
        *issuer = crt_cpy(list->node[i].trusted_cas[j]);
1035
0
        return 0;
1036
0
      }
1037
0
    }
1038
0
  }
1039
1040
0
  return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1041
0
}
1042
1043
/**
1044
 * gnutls_x509_trust_list_get_issuer:
1045
 * @list: The list
1046
 * @cert: is the certificate to find issuer for
1047
 * @issuer: Will hold the issuer if any. Should be treated as constant
1048
 *   unless %GNUTLS_TL_GET_COPY is set in @flags.
1049
 * @flags: flags from %gnutls_trust_list_flags_t (%GNUTLS_TL_GET_COPY is applicable)
1050
 *
1051
 * This function will find the issuer of the given certificate.
1052
 * If the flag %GNUTLS_TL_GET_COPY is specified a copy of the issuer
1053
 * will be returned which must be freed using gnutls_x509_crt_deinit().
1054
 * In that case the provided @issuer must not be initialized.
1055
 *
1056
 * Note that the flag %GNUTLS_TL_GET_COPY is required for this function
1057
 * to work with PKCS#11 trust lists in a thread-safe way.
1058
 *
1059
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1060
 *   negative error value.
1061
 *
1062
 * Since: 3.0
1063
 **/
1064
int gnutls_x509_trust_list_get_issuer(gnutls_x509_trust_list_t list,
1065
              gnutls_x509_crt_t cert,
1066
              gnutls_x509_crt_t *issuer,
1067
              unsigned int flags)
1068
0
{
1069
0
  int ret;
1070
1071
0
  ret = _gnutls_trust_list_get_issuer(list, cert, issuer, flags);
1072
0
  if (ret == 0) {
1073
0
    return 0;
1074
0
  }
1075
1076
#ifdef ENABLE_PKCS11
1077
  if (ret < 0 && list->pkcs11_token) {
1078
    gnutls_x509_crt_t crt;
1079
    gnutls_datum_t der = { NULL, 0 };
1080
    /* use the token for verification */
1081
    ret = gnutls_pkcs11_get_raw_issuer(
1082
      list->pkcs11_token, cert, &der, GNUTLS_X509_FMT_DER,
1083
      GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE);
1084
    if (ret < 0) {
1085
      gnutls_assert();
1086
      return ret;
1087
    }
1088
1089
    ret = gnutls_x509_crt_init(&crt);
1090
    if (ret < 0) {
1091
      gnutls_free(der.data);
1092
      return gnutls_assert_val(ret);
1093
    }
1094
1095
    ret = gnutls_x509_crt_import(crt, &der, GNUTLS_X509_FMT_DER);
1096
    gnutls_free(der.data);
1097
    if (ret < 0) {
1098
      gnutls_x509_crt_deinit(crt);
1099
      return gnutls_assert_val(ret);
1100
    }
1101
1102
    if (flags & GNUTLS_TL_GET_COPY) {
1103
      *issuer = crt;
1104
      return 0;
1105
    } else {
1106
      /* we add this CA to the keep_cert list in order to make it
1107
       * persistent. It will be deallocated when the trust list is.
1108
       */
1109
      ret = trust_list_add_compat(list, crt);
1110
      if (ret < 0) {
1111
        gnutls_x509_crt_deinit(crt);
1112
        return gnutls_assert_val(ret);
1113
      }
1114
      *issuer = crt;
1115
      return ret;
1116
    }
1117
  }
1118
#endif
1119
0
  return ret;
1120
0
}
1121
1122
/**
1123
 * gnutls_x509_trust_list_get_issuer_by_dn:
1124
 * @list: The list
1125
 * @dn: is the issuer's DN
1126
 * @issuer: Will hold the issuer if any. Should be deallocated after use.
1127
 * @flags: Use zero
1128
 *
1129
 * This function will find the issuer with the given name, and
1130
 * return a copy of the issuer, which must be freed using gnutls_x509_crt_deinit().
1131
 *
1132
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1133
 *   negative error value.
1134
 *
1135
 * Since: 3.4.0
1136
 **/
1137
int gnutls_x509_trust_list_get_issuer_by_dn(gnutls_x509_trust_list_t list,
1138
              const gnutls_datum_t *dn,
1139
              gnutls_x509_crt_t *issuer,
1140
              unsigned int flags)
1141
0
{
1142
0
  int ret;
1143
1144
0
  ret = trust_list_get_issuer_by_dn(list, dn, NULL, issuer, flags);
1145
0
  if (ret == 0) {
1146
0
    return 0;
1147
0
  }
1148
1149
#ifdef ENABLE_PKCS11
1150
  if (ret < 0 && list->pkcs11_token) {
1151
    gnutls_x509_crt_t crt;
1152
    gnutls_datum_t der = { NULL, 0 };
1153
    /* use the token for verification */
1154
    ret = gnutls_pkcs11_get_raw_issuer_by_dn(
1155
      list->pkcs11_token, dn, &der, GNUTLS_X509_FMT_DER,
1156
      GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE);
1157
    if (ret < 0) {
1158
      gnutls_assert();
1159
      return ret;
1160
    }
1161
1162
    ret = gnutls_x509_crt_init(&crt);
1163
    if (ret < 0) {
1164
      gnutls_free(der.data);
1165
      return gnutls_assert_val(ret);
1166
    }
1167
1168
    ret = gnutls_x509_crt_import(crt, &der, GNUTLS_X509_FMT_DER);
1169
    gnutls_free(der.data);
1170
    if (ret < 0) {
1171
      gnutls_x509_crt_deinit(crt);
1172
      return gnutls_assert_val(ret);
1173
    }
1174
1175
    *issuer = crt;
1176
    return 0;
1177
  }
1178
#endif
1179
0
  return ret;
1180
0
}
1181
1182
/**
1183
 * gnutls_x509_trust_list_get_issuer_by_subject_key_id:
1184
 * @list: The list
1185
 * @dn: is the issuer's DN (may be %NULL)
1186
 * @spki: is the subject key ID
1187
 * @issuer: Will hold the issuer if any. Should be deallocated after use.
1188
 * @flags: Use zero
1189
 *
1190
 * This function will find the issuer with the given name and subject key ID, and
1191
 * return a copy of the issuer, which must be freed using gnutls_x509_crt_deinit().
1192
 *
1193
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1194
 *   negative error value.
1195
 *
1196
 * Since: 3.4.2
1197
 **/
1198
int gnutls_x509_trust_list_get_issuer_by_subject_key_id(
1199
  gnutls_x509_trust_list_t list, const gnutls_datum_t *dn,
1200
  const gnutls_datum_t *spki, gnutls_x509_crt_t *issuer,
1201
  unsigned int flags)
1202
0
{
1203
0
  int ret;
1204
1205
0
  ret = trust_list_get_issuer_by_dn(list, dn, spki, issuer, flags);
1206
0
  if (ret == 0) {
1207
0
    return 0;
1208
0
  }
1209
1210
#ifdef ENABLE_PKCS11
1211
  if (ret < 0 && list->pkcs11_token) {
1212
    gnutls_x509_crt_t crt;
1213
    gnutls_datum_t der = { NULL, 0 };
1214
    /* use the token for verification */
1215
    ret = gnutls_pkcs11_get_raw_issuer_by_subject_key_id(
1216
      list->pkcs11_token, dn, spki, &der, GNUTLS_X509_FMT_DER,
1217
      GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE);
1218
    if (ret < 0) {
1219
      gnutls_assert();
1220
      return ret;
1221
    }
1222
1223
    ret = gnutls_x509_crt_init(&crt);
1224
    if (ret < 0) {
1225
      gnutls_free(der.data);
1226
      return gnutls_assert_val(ret);
1227
    }
1228
1229
    ret = gnutls_x509_crt_import(crt, &der, GNUTLS_X509_FMT_DER);
1230
    gnutls_free(der.data);
1231
    if (ret < 0) {
1232
      gnutls_x509_crt_deinit(crt);
1233
      return gnutls_assert_val(ret);
1234
    }
1235
1236
    *issuer = crt;
1237
    return 0;
1238
  }
1239
#endif
1240
0
  return ret;
1241
0
}
1242
1243
static int check_if_in_blocklist(gnutls_x509_crt_t *cert_list,
1244
         unsigned int cert_list_size,
1245
         gnutls_x509_crt_t *blocklist,
1246
         unsigned int blocklist_size)
1247
0
{
1248
0
  unsigned i, j;
1249
1250
0
  if (blocklist_size == 0)
1251
0
    return 0;
1252
1253
0
  for (i = 0; i < cert_list_size; i++) {
1254
0
    for (j = 0; j < blocklist_size; j++) {
1255
0
      if (gnutls_x509_crt_equals(cert_list[i],
1256
0
               blocklist[j]) != 0) {
1257
0
        return 1;
1258
0
      }
1259
0
    }
1260
0
  }
1261
1262
0
  return 0;
1263
0
}
1264
1265
/**
1266
 * gnutls_x509_trust_list_verify_crt:
1267
 * @list: The list
1268
 * @cert_list: is the certificate list to be verified
1269
 * @cert_list_size: is the certificate list size
1270
 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
1271
 * @voutput: will hold the certificate verification output.
1272
 * @func: If non-null will be called on each chain element verification with the output.
1273
 *
1274
 * This function will try to verify the given certificate and return
1275
 * its status. The @voutput parameter will hold an OR'ed sequence of
1276
 * %gnutls_certificate_status_t flags.
1277
 *
1278
 * The details of the verification are the same as in gnutls_x509_trust_list_verify_crt2().
1279
 *
1280
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1281
 *   negative error value.
1282
 *
1283
 * Since: 3.0
1284
 **/
1285
int gnutls_x509_trust_list_verify_crt(gnutls_x509_trust_list_t list,
1286
              gnutls_x509_crt_t *cert_list,
1287
              unsigned int cert_list_size,
1288
              unsigned int flags, unsigned int *voutput,
1289
              gnutls_verify_output_function func)
1290
0
{
1291
0
  return gnutls_x509_trust_list_verify_crt2(
1292
0
    list, cert_list, cert_list_size, NULL, 0, flags, voutput, func);
1293
0
}
1294
1295
0
#define LAST_DN cert_list[cert_list_size - 1]->raw_dn
1296
0
#define LAST_IDN cert_list[cert_list_size - 1]->raw_issuer_dn
1297
/* This macro is introduced to detect a verification output which
1298
 * indicates an unknown signer, a signer which uses an insecure
1299
 * algorithm (e.g., sha1), a signer has expired, or something that
1300
 * indicates a superseded signer */
1301
#define SIGNER_OLD_OR_UNKNOWN(output)               \
1302
0
  ((output & GNUTLS_CERT_SIGNER_NOT_FOUND) || \
1303
0
   (output & GNUTLS_CERT_EXPIRED) ||          \
1304
0
   (output & GNUTLS_CERT_INSECURE_ALGORITHM))
1305
0
#define SIGNER_WAS_KNOWN(output) (!(output & GNUTLS_CERT_SIGNER_NOT_FOUND))
1306
1307
/**
1308
 * gnutls_x509_trust_list_verify_crt2:
1309
 * @list: The list
1310
 * @cert_list: is the certificate list to be verified
1311
 * @cert_list_size: is the certificate list size
1312
 * @data: an array of typed data
1313
 * @elements: the number of data elements
1314
 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
1315
 * @voutput: will hold the certificate verification output.
1316
 * @func: If non-null will be called on each chain element verification with the output.
1317
 *
1318
 * This function will attempt to verify the given certificate chain and return
1319
 * its status. The @voutput parameter will hold an OR'ed sequence of
1320
 * %gnutls_certificate_status_t flags.
1321
 *
1322
 * When a certificate chain of @cert_list_size with more than one certificates is
1323
 * provided, the verification status will apply to the first certificate in the chain
1324
 * that failed verification. The verification process starts from the end of the chain
1325
 * (from CA to end certificate). The first certificate in the chain must be the end-certificate
1326
 * while the rest of the members may be sorted or not.
1327
 *
1328
 * Additionally a certificate verification profile can be specified
1329
 * from the ones in %gnutls_certificate_verification_profiles_t by
1330
 * ORing the result of GNUTLS_PROFILE_TO_VFLAGS() to the verification
1331
 * flags.
1332
 *
1333
 * Additional verification parameters are possible via the @data types; the
1334
 * acceptable types are %GNUTLS_DT_DNS_HOSTNAME, %GNUTLS_DT_IP_ADDRESS and %GNUTLS_DT_KEY_PURPOSE_OID.
1335
 * The former accepts as data a null-terminated hostname, and the latter a null-terminated
1336
 * object identifier (e.g., %GNUTLS_KP_TLS_WWW_SERVER).
1337
 * If a DNS hostname is provided then this function will compare
1338
 * the hostname in the end certificate against the given. If names do not match the
1339
 * %GNUTLS_CERT_UNEXPECTED_OWNER status flag will be set. In addition it
1340
 * will consider certificates provided with gnutls_x509_trust_list_add_named_crt().
1341
 *
1342
 * If a key purpose OID is provided and the end-certificate contains the extended key
1343
 * usage PKIX extension, it will be required to match the provided OID
1344
 * or be marked for any purpose, otherwise verification will fail with 
1345
 * %GNUTLS_CERT_PURPOSE_MISMATCH status.
1346
 *
1347
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1348
 *   negative error value. Note that verification failure will not result to an
1349
 *   error code, only @voutput will be updated.
1350
 *
1351
 * Since: 3.3.8
1352
 **/
1353
int gnutls_x509_trust_list_verify_crt2(
1354
  gnutls_x509_trust_list_t list, gnutls_x509_crt_t *cert_list,
1355
  unsigned int cert_list_size, gnutls_typed_vdata_st *data,
1356
  unsigned int elements, unsigned int flags, unsigned int *voutput,
1357
  gnutls_verify_output_function func)
1358
0
{
1359
0
  int ret = 0;
1360
0
  unsigned int i;
1361
0
  size_t hash;
1362
0
  gnutls_x509_crt_t *cert_list_copy = NULL;
1363
0
  unsigned int cert_list_max_size = 0;
1364
0
  gnutls_x509_crt_t retrieved[DEFAULT_MAX_VERIFY_DEPTH];
1365
0
  unsigned int retrieved_size = 0;
1366
0
  const char *hostname = NULL, *purpose = NULL, *email = NULL;
1367
0
  unsigned hostname_size = 0;
1368
0
  unsigned have_set_name = 0;
1369
0
  unsigned saved_output;
1370
0
  gnutls_datum_t ip = { NULL, 0 };
1371
0
  gl_list_t records;
1372
1373
0
  if (cert_list == NULL || cert_list_size < 1)
1374
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1375
1376
0
  for (i = 0; i < elements; i++) {
1377
0
    if (data[i].type == GNUTLS_DT_DNS_HOSTNAME) {
1378
0
      hostname = (void *)data[i].data;
1379
0
      if (data[i].size > 0) {
1380
0
        hostname_size = data[i].size;
1381
0
      }
1382
1383
0
      if (have_set_name != 0)
1384
0
        return gnutls_assert_val(
1385
0
          GNUTLS_E_INVALID_REQUEST);
1386
0
      have_set_name = 1;
1387
0
    } else if (data[i].type == GNUTLS_DT_IP_ADDRESS) {
1388
0
      if (data[i].size > 0) {
1389
0
        ip.data = data[i].data;
1390
0
        ip.size = data[i].size;
1391
0
      }
1392
1393
0
      if (have_set_name != 0)
1394
0
        return gnutls_assert_val(
1395
0
          GNUTLS_E_INVALID_REQUEST);
1396
0
      have_set_name = 1;
1397
0
    } else if (data[i].type == GNUTLS_DT_RFC822NAME) {
1398
0
      email = (void *)data[i].data;
1399
1400
0
      if (have_set_name != 0)
1401
0
        return gnutls_assert_val(
1402
0
          GNUTLS_E_INVALID_REQUEST);
1403
0
      have_set_name = 1;
1404
0
    } else if (data[i].type == GNUTLS_DT_KEY_PURPOSE_OID) {
1405
0
      purpose = (void *)data[i].data;
1406
0
    }
1407
0
  }
1408
1409
0
  if (hostname) { /* shortcut using the named certs - if any */
1410
0
    unsigned vtmp = 0;
1411
0
    if (hostname_size == 0)
1412
0
      hostname_size = strlen(hostname);
1413
1414
0
    ret = gnutls_x509_trust_list_verify_named_crt(
1415
0
      list, cert_list[0], hostname, hostname_size, flags,
1416
0
      &vtmp, func);
1417
0
    if (ret == 0 && vtmp == 0) {
1418
0
      *voutput = vtmp;
1419
0
      return 0;
1420
0
    }
1421
0
  }
1422
1423
  /* Allocate extra for retrieved certificates. */
1424
0
  if (!INT_ADD_OK(cert_list_size, DEFAULT_MAX_VERIFY_DEPTH,
1425
0
      &cert_list_max_size))
1426
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1427
1428
0
  cert_list_copy = _gnutls_reallocarray(NULL, cert_list_max_size,
1429
0
                sizeof(gnutls_x509_crt_t));
1430
0
  if (!cert_list_copy)
1431
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1432
1433
0
  memcpy(cert_list_copy, cert_list,
1434
0
         cert_list_size * sizeof(gnutls_x509_crt_t));
1435
0
  cert_list = cert_list_copy;
1436
1437
0
  records = gl_list_nx_create_empty(GL_LINKEDHASH_LIST, cert_eq,
1438
0
            cert_hashcode, NULL, false);
1439
0
  if (records == NULL) {
1440
0
    ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1441
0
    goto cleanup;
1442
0
  }
1443
1444
0
  for (i = 0; i < cert_list_size;) {
1445
0
    unsigned int sorted_size = 1;
1446
0
    unsigned int j, k;
1447
0
    gnutls_x509_crt_t issuer;
1448
1449
0
    if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_UNSORTED_CHAIN)) {
1450
0
      sorted_size = _gnutls_sort_clist(&cert_list[i],
1451
0
               cert_list_size - i);
1452
0
    }
1453
1454
0
    assert(sorted_size > 0);
1455
1456
    /* Remove duplicates. */
1457
0
    for (j = 0; j < sorted_size; j++) {
1458
0
      if (gl_list_search(records, cert_list[i + j])) {
1459
0
        if (i + j < cert_list_size - 1) {
1460
0
          memmove(&cert_list[i + j],
1461
0
            &cert_list[i + j + 1],
1462
0
            sizeof(cert_list[i]));
1463
0
        }
1464
0
        cert_list_size--;
1465
0
        break;
1466
0
      }
1467
0
    }
1468
    /* Found a duplicate, try again with the same index. */
1469
0
    if (j < sorted_size) {
1470
0
      continue;
1471
0
    }
1472
1473
    /* Record the certificates seen. */
1474
0
    for (k = 0; k < sorted_size; k++, i++) {
1475
0
      if (!gl_list_nx_add_last(records, cert_list[i])) {
1476
0
        ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1477
0
        goto cleanup;
1478
0
      }
1479
0
    }
1480
1481
    /* Pacify GCC analyzer: the condition always holds
1482
     * true as sorted_size > 0 is checked above, and the
1483
     * following loop should iterate at least once so i++
1484
     * is called.
1485
     */
1486
0
    assert(i > 0);
1487
1488
    /* If the issuer of the certificate is known, no need
1489
     * for further processing. */
1490
0
    if (gnutls_x509_trust_list_get_issuer(
1491
0
          list, cert_list[i - 1], &issuer,
1492
0
          GNUTLS_TL_GET_COPY) == 0) {
1493
0
      gnutls_x509_crt_deinit(issuer);
1494
0
      cert_list_size = i;
1495
0
      break;
1496
0
    }
1497
1498
    /* If there is no gap between this and the next certificate,
1499
     * proceed with the next certificate. */
1500
0
    if (i < cert_list_size &&
1501
0
        gnutls_x509_crt_check_issuer(cert_list[i - 1],
1502
0
             cert_list[i])) {
1503
0
      continue;
1504
0
    }
1505
1506
0
    ret = retrieve_issuers(
1507
0
      list, cert_list[i - 1], &retrieved[retrieved_size],
1508
0
      MIN(DEFAULT_MAX_VERIFY_DEPTH - retrieved_size,
1509
0
          cert_list_max_size - cert_list_size));
1510
0
    if (ret < 0) {
1511
0
      break;
1512
0
    } else if (ret > 0) {
1513
0
      assert((unsigned int)ret <=
1514
0
             DEFAULT_MAX_VERIFY_DEPTH - retrieved_size);
1515
0
      assert((unsigned int)ret <=
1516
0
             cert_list_max_size - cert_list_size);
1517
0
      memmove(&cert_list[i + ret], &cert_list[i],
1518
0
        (cert_list_size - i) *
1519
0
          sizeof(gnutls_x509_crt_t));
1520
0
      memcpy(&cert_list[i], &retrieved[retrieved_size],
1521
0
             ret * sizeof(gnutls_x509_crt_t));
1522
0
      retrieved_size += ret;
1523
0
      cert_list_size += ret;
1524
1525
      /* Start again from the end of the previous segment. */
1526
0
      i--;
1527
0
      gl_list_remove(records, cert_list[i]);
1528
0
    }
1529
0
  }
1530
1531
0
  cert_list_size = shorten_clist(list, cert_list, cert_list_size);
1532
0
  if (cert_list_size <= 0) {
1533
0
    ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1534
0
    goto cleanup;
1535
0
  }
1536
1537
0
  hash = hash_pjw_bare(cert_list[cert_list_size - 1]->raw_issuer_dn.data,
1538
0
           cert_list[cert_list_size - 1]->raw_issuer_dn.size);
1539
0
  hash %= list->size;
1540
1541
0
  ret = check_if_in_blocklist(cert_list, cert_list_size, list->distrusted,
1542
0
            list->distrusted_size);
1543
0
  if (ret != 0) {
1544
0
    *voutput = 0;
1545
0
    *voutput |= GNUTLS_CERT_REVOKED;
1546
0
    *voutput |= GNUTLS_CERT_INVALID;
1547
0
    ret = 0;
1548
0
    goto cleanup;
1549
0
  }
1550
1551
0
  *voutput = _gnutls_verify_crt_status(list, cert_list, cert_list_size,
1552
0
               list->node[hash].trusted_cas,
1553
0
               list->node[hash].trusted_ca_size,
1554
0
               flags, purpose, func);
1555
0
  saved_output = *voutput;
1556
1557
0
  if (SIGNER_OLD_OR_UNKNOWN(*voutput) &&
1558
0
      (LAST_DN.size != LAST_IDN.size ||
1559
0
       !memeq(LAST_DN.data, LAST_IDN.data, LAST_IDN.size))) {
1560
    /* if we couldn't find the issuer, try to see if the last
1561
     * certificate is in the trusted list and try to verify against
1562
     * (if it is not self signed) */
1563
0
    hash = hash_pjw_bare(
1564
0
      cert_list[cert_list_size - 1]->raw_dn.data,
1565
0
      cert_list[cert_list_size - 1]->raw_dn.size);
1566
0
    hash %= list->size;
1567
1568
0
    _gnutls_debug_log(
1569
0
      "issuer in verification was not found or insecure; trying against trust list\n");
1570
1571
0
    *voutput = _gnutls_verify_crt_status(
1572
0
      list, cert_list, cert_list_size,
1573
0
      list->node[hash].trusted_cas,
1574
0
      list->node[hash].trusted_ca_size, flags, purpose, func);
1575
0
    if (*voutput != 0) {
1576
0
      if (SIGNER_WAS_KNOWN(saved_output))
1577
0
        *voutput = saved_output;
1578
0
      gnutls_assert();
1579
0
    }
1580
0
  }
1581
1582
0
  saved_output = *voutput;
1583
1584
#ifdef ENABLE_PKCS11
1585
  if (SIGNER_OLD_OR_UNKNOWN(*voutput) && list->pkcs11_token) {
1586
    /* use the token for verification */
1587
1588
    *voutput = _gnutls_pkcs11_verify_crt_status(
1589
      list, list->pkcs11_token, cert_list, cert_list_size,
1590
      purpose, flags, func);
1591
    if (*voutput != 0) {
1592
      if (SIGNER_WAS_KNOWN(saved_output))
1593
        *voutput = saved_output;
1594
      gnutls_assert();
1595
    }
1596
  }
1597
#endif
1598
1599
  /* End-certificate, key purpose and hostname checks. */
1600
0
  if (purpose) {
1601
0
    ret = _gnutls_check_key_purpose(cert_list[0], purpose, 0);
1602
0
    if (ret != 1) {
1603
0
      gnutls_assert();
1604
0
      *voutput |= GNUTLS_CERT_PURPOSE_MISMATCH |
1605
0
            GNUTLS_CERT_INVALID;
1606
0
    }
1607
0
  }
1608
1609
0
  if (hostname) {
1610
0
    ret = gnutls_x509_crt_check_hostname2(cert_list[0], hostname,
1611
0
                  flags);
1612
0
    if (ret == 0) {
1613
0
      gnutls_assert();
1614
0
      *voutput |= GNUTLS_CERT_UNEXPECTED_OWNER |
1615
0
            GNUTLS_CERT_INVALID;
1616
0
    }
1617
0
  }
1618
1619
0
  if (ip.data) {
1620
0
    ret = gnutls_x509_crt_check_ip(cert_list[0], ip.data, ip.size,
1621
0
                 flags);
1622
0
    if (ret == 0) {
1623
0
      gnutls_assert();
1624
0
      *voutput |= GNUTLS_CERT_UNEXPECTED_OWNER |
1625
0
            GNUTLS_CERT_INVALID;
1626
0
    }
1627
0
  }
1628
1629
0
  if (email) {
1630
0
    ret = gnutls_x509_crt_check_email(cert_list[0], email, 0);
1631
0
    if (ret == 0) {
1632
0
      gnutls_assert();
1633
0
      *voutput |= GNUTLS_CERT_UNEXPECTED_OWNER |
1634
0
            GNUTLS_CERT_INVALID;
1635
0
    }
1636
0
  }
1637
1638
  /* CRL checks follow */
1639
1640
0
  if (*voutput != 0 || (flags & GNUTLS_VERIFY_DISABLE_CRL_CHECKS)) {
1641
0
    ret = 0;
1642
0
    goto cleanup;
1643
0
  }
1644
1645
  /* Check revocation of individual certificates.
1646
   * start with the last one that we already have its hash
1647
   */
1648
0
  ret = _gnutls_x509_crt_check_revocation(cert_list[cert_list_size - 1],
1649
0
            list->node[hash].crls,
1650
0
            list->node[hash].crl_size,
1651
0
            func);
1652
0
  if (ret == 1) { /* revoked */
1653
0
    *voutput |= GNUTLS_CERT_REVOKED;
1654
0
    *voutput |= GNUTLS_CERT_INVALID;
1655
0
    ret = 0;
1656
0
    goto cleanup;
1657
0
  }
1658
1659
0
  for (i = 0; i < cert_list_size - 1; i++) {
1660
0
    hash = hash_pjw_bare(cert_list[i]->raw_issuer_dn.data,
1661
0
             cert_list[i]->raw_issuer_dn.size);
1662
0
    hash %= list->size;
1663
1664
0
    ret = _gnutls_x509_crt_check_revocation(
1665
0
      cert_list[i], list->node[hash].crls,
1666
0
      list->node[hash].crl_size, func);
1667
0
    if (ret < 0) {
1668
0
      gnutls_assert();
1669
0
    } else if (ret == 1) { /* revoked */
1670
0
      *voutput |= GNUTLS_CERT_REVOKED;
1671
0
      *voutput |= GNUTLS_CERT_INVALID;
1672
0
      ret = 0;
1673
0
      goto cleanup;
1674
0
    }
1675
0
  }
1676
1677
0
cleanup:
1678
0
  gnutls_free(cert_list_copy);
1679
0
  for (i = 0; i < retrieved_size; i++) {
1680
0
    gnutls_x509_crt_deinit(retrieved[i]);
1681
0
  }
1682
0
  if (records) {
1683
0
    gl_list_free(records);
1684
0
  }
1685
0
  return ret;
1686
0
}
1687
1688
/**
1689
 * gnutls_x509_trust_list_verify_named_crt:
1690
 * @list: The list
1691
 * @cert: is the certificate to be verified
1692
 * @name: is the certificate's name
1693
 * @name_size: is the certificate's name size
1694
 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
1695
 * @voutput: will hold the certificate verification output.
1696
 * @func: If non-null will be called on each chain element verification with the output.
1697
 *
1698
 * This function will try to find a certificate that is associated with the provided
1699
 * name --see gnutls_x509_trust_list_add_named_crt(). If a match is found the
1700
 * certificate is considered valid. In addition to that this function will also 
1701
 * check CRLs. The @voutput parameter will hold an OR'ed sequence of 
1702
 * %gnutls_certificate_status_t flags.
1703
 *
1704
 * Additionally a certificate verification profile can be specified
1705
 * from the ones in %gnutls_certificate_verification_profiles_t by
1706
 * ORing the result of GNUTLS_PROFILE_TO_VFLAGS() to the verification
1707
 * flags.
1708
 *
1709
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1710
 *   negative error value.
1711
 *
1712
 * Since: 3.0.0
1713
 **/
1714
int gnutls_x509_trust_list_verify_named_crt(gnutls_x509_trust_list_t list,
1715
              gnutls_x509_crt_t cert,
1716
              const void *name, size_t name_size,
1717
              unsigned int flags,
1718
              unsigned int *voutput,
1719
              gnutls_verify_output_function func)
1720
0
{
1721
0
  int ret;
1722
0
  unsigned int i;
1723
0
  size_t hash;
1724
1725
0
  hash = hash_pjw_bare(cert->raw_issuer_dn.data,
1726
0
           cert->raw_issuer_dn.size);
1727
0
  hash %= list->size;
1728
1729
0
  ret = check_if_in_blocklist(&cert, 1, list->distrusted,
1730
0
            list->distrusted_size);
1731
0
  if (ret != 0) {
1732
0
    *voutput = 0;
1733
0
    *voutput |= GNUTLS_CERT_REVOKED;
1734
0
    *voutput |= GNUTLS_CERT_INVALID;
1735
0
    return 0;
1736
0
  }
1737
1738
0
  *voutput = GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNER_NOT_FOUND;
1739
1740
0
  for (i = 0; i < list->node[hash].named_cert_size; i++) {
1741
0
    if (gnutls_x509_crt_equals(
1742
0
          cert, list->node[hash].named_certs[i].cert) !=
1743
0
        0) { /* check if name matches */
1744
0
      if (list->node[hash].named_certs[i].name_size ==
1745
0
            name_size &&
1746
0
          memeq(list->node[hash].named_certs[i].name, name,
1747
0
          name_size)) {
1748
0
        *voutput = 0;
1749
0
        break;
1750
0
      }
1751
0
    }
1752
0
  }
1753
1754
0
  if (*voutput != 0 || (flags & GNUTLS_VERIFY_DISABLE_CRL_CHECKS))
1755
0
    return 0;
1756
1757
  /* Check revocation of individual certificates.
1758
   * start with the last one that we already have its hash
1759
   */
1760
0
  ret = _gnutls_x509_crt_check_revocation(
1761
0
    cert, list->node[hash].crls, list->node[hash].crl_size, func);
1762
0
  if (ret == 1) { /* revoked */
1763
0
    *voutput |= GNUTLS_CERT_REVOKED;
1764
0
    *voutput |= GNUTLS_CERT_INVALID;
1765
0
    return 0;
1766
0
  }
1767
1768
0
  return 0;
1769
0
}
1770
1771
/* return 1 if @cert is in @list, 0 if not */
1772
int _gnutls_trustlist_inlist(gnutls_x509_trust_list_t list,
1773
           gnutls_x509_crt_t cert)
1774
0
{
1775
0
  int ret;
1776
0
  unsigned int i;
1777
0
  size_t hash;
1778
1779
0
  hash = hash_pjw_bare(cert->raw_dn.data, cert->raw_dn.size);
1780
0
  hash %= list->size;
1781
1782
0
  for (i = 0; i < list->node[hash].trusted_ca_size; i++) {
1783
0
    ret = gnutls_x509_crt_equals(cert,
1784
0
               list->node[hash].trusted_cas[i]);
1785
0
    if (ret != 0)
1786
0
      return 1;
1787
0
  }
1788
1789
0
  return 0;
1790
0
}