Coverage Report

Created: 2025-03-18 06:55

/src/gnutls/lib/x509/verify-high.c
Line
Count
Source (jump to first uncovered line)
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 <hash-pjw-bare.h>
33
#include "x509_int.h"
34
#include "common.h"
35
#include <gnutls/x509-ext.h>
36
#include "verify-high.h"
37
#include "intprops.h"
38
#include "gl_linkedhash_list.h"
39
#include "gl_list.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
            memcmp(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
              0) {
788
0
          if (gnutls_x509_crl_get_this_update(
789
0
                crl_list[i]) >=
790
0
              gnutls_x509_crl_get_this_update(
791
0
                list->node[hash].crls[x])) {
792
0
            gnutls_x509_crl_deinit(
793
0
              list->node[hash]
794
0
                .crls[x]);
795
0
            list->node[hash].crls[x] =
796
0
              crl_list[i];
797
0
            goto next;
798
0
          } else {
799
            /* The new is older, discard it */
800
0
            gnutls_x509_crl_deinit(
801
0
              crl_list[i]);
802
0
            goto next;
803
0
          }
804
0
        }
805
0
      }
806
0
    }
807
808
0
    if (unlikely(INT_ADD_OVERFLOW(list->node[hash].crl_size, 1))) {
809
0
      gnutls_assert();
810
0
      goto error;
811
0
    }
812
813
0
    tmp = _gnutls_reallocarray(list->node[hash].crls,
814
0
             list->node[hash].crl_size + 1,
815
0
             sizeof(list->node[hash].crls[0]));
816
0
    if (tmp == NULL) {
817
0
      gnutls_assert();
818
0
      goto error;
819
0
    }
820
0
    list->node[hash].crls = tmp;
821
822
0
    list->node[hash].crls[list->node[hash].crl_size] = crl_list[i];
823
0
    list->node[hash].crl_size++;
824
825
0
  next:
826
0
    j++;
827
0
  }
828
829
0
  return j;
830
831
0
error:
832
0
  ret = i;
833
0
  if (flags & GNUTLS_TL_NO_DUPLICATES)
834
0
    while (i < crl_size)
835
0
      gnutls_x509_crl_deinit(crl_list[i++]);
836
0
  return ret;
837
0
}
838
839
/* Takes a certificate list and shortens it if there are
840
 * intermedia certificates already trusted by us.
841
 *
842
 * Returns the new size of the list or a negative number on error.
843
 */
844
static int shorten_clist(gnutls_x509_trust_list_t list,
845
       gnutls_x509_crt_t *certificate_list,
846
       unsigned int clist_size)
847
0
{
848
0
  unsigned int j, i;
849
0
  size_t hash;
850
851
0
  if (clist_size > 1) {
852
    /* Check if the last certificate in the path is self signed.
853
     * In that case ignore it (a certificate is trusted only if it
854
     * leads to a trusted party by us, not the server's).
855
     *
856
     * This prevents from verifying self signed certificates against
857
     * themselves. This (although not bad) caused verification
858
     * failures on some root self signed certificates that use the
859
     * MD2 algorithm.
860
     */
861
0
    if (gnutls_x509_crt_check_issuer(
862
0
          certificate_list[clist_size - 1],
863
0
          certificate_list[clist_size - 1]) != 0) {
864
0
      clist_size--;
865
0
    }
866
0
  }
867
868
  /* We want to shorten the chain by removing the cert that matches
869
   * one of the certs we trust and all the certs after that i.e. if
870
   * cert chain is A signed-by B signed-by C signed-by D (signed-by
871
   * self-signed E but already removed above), and we trust B, remove
872
   * B, C and D. */
873
0
  for (i = 1; i < clist_size; i++) {
874
0
    hash = hash_pjw_bare(certificate_list[i]->raw_issuer_dn.data,
875
0
             certificate_list[i]->raw_issuer_dn.size);
876
0
    hash %= list->size;
877
878
0
    for (j = 0; j < list->node[hash].trusted_ca_size; j++) {
879
0
      if (gnutls_x509_crt_equals(
880
0
            certificate_list[i],
881
0
            list->node[hash].trusted_cas[j]) != 0) {
882
        /* cut the list at the point of first the trusted certificate */
883
0
        clist_size = i + 1;
884
0
        break;
885
0
      }
886
0
    }
887
    /* clist_size may have been changed which gets out of loop */
888
0
  }
889
890
0
  return clist_size;
891
0
}
892
893
/* Takes a subject certificate, retrieves a chain from its issuers in
894
 * @certificate_list, using the issuer callback set for @list.
895
 *
896
 * Returns the new size of the list or a negative number on error.
897
 */
898
static int retrieve_issuers(gnutls_x509_trust_list_t list,
899
          gnutls_x509_crt_t subject,
900
          gnutls_x509_crt_t *certificate_list,
901
          unsigned int clist_size_max)
902
0
{
903
0
  gnutls_x509_crt_t *issuers;
904
0
  unsigned int issuers_size;
905
0
  unsigned int i;
906
0
  int ret;
907
908
0
  if (!list->issuer_callback) {
909
0
    return 0;
910
0
  }
911
912
0
  _gnutls_cert_log("calling issuer callback on", subject);
913
914
0
  ret = list->issuer_callback(list, subject, &issuers, &issuers_size);
915
0
  if (ret < 0) {
916
0
    return gnutls_assert_val(ret);
917
0
  }
918
919
  /* Ignore empty list */
920
0
  if (!issuers_size) {
921
0
    ret = 0;
922
0
    goto cleanup;
923
0
  }
924
925
0
  if (issuers_size > clist_size_max) {
926
0
    _gnutls_debug_log("too many issuers returned; skipping\n");
927
0
    ret = 0;
928
0
    goto cleanup;
929
0
  }
930
931
0
  for (i = 0; i < issuers_size; i++) {
932
0
    if (!gnutls_x509_crt_check_issuer(subject, issuers[i])) {
933
0
      _gnutls_cert_log("unrelated certificate; skipping",
934
0
           issuers[i]);
935
0
      break;
936
0
    }
937
0
    subject = issuers[i];
938
0
  }
939
940
0
  ret = i;
941
942
0
  memcpy(certificate_list, issuers, ret * sizeof(gnutls_x509_crt_t));
943
944
0
cleanup:
945
0
  for (i = ret; i < issuers_size; i++) {
946
0
    gnutls_x509_crt_deinit(issuers[i]);
947
0
  }
948
0
  gnutls_free(issuers);
949
950
0
  return ret;
951
0
}
952
953
int _gnutls_trust_list_get_issuer(gnutls_x509_trust_list_t list,
954
          gnutls_x509_crt_t cert,
955
          gnutls_x509_crt_t *issuer, unsigned int flags)
956
0
{
957
0
  int ret;
958
0
  unsigned int i;
959
0
  size_t hash;
960
961
0
  hash = hash_pjw_bare(cert->raw_issuer_dn.data,
962
0
           cert->raw_issuer_dn.size);
963
0
  hash %= list->size;
964
965
0
  for (i = 0; i < list->node[hash].trusted_ca_size; i++) {
966
0
    ret = gnutls_x509_crt_check_issuer(
967
0
      cert, list->node[hash].trusted_cas[i]);
968
0
    if (ret != 0) {
969
0
      if (flags & GNUTLS_TL_GET_COPY) {
970
0
        *issuer = crt_cpy(
971
0
          list->node[hash].trusted_cas[i]);
972
0
      } else {
973
0
        *issuer = list->node[hash].trusted_cas[i];
974
0
      }
975
0
      return 0;
976
0
    }
977
0
  }
978
979
0
  return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
980
0
}
981
982
static int trust_list_get_issuer_by_dn(gnutls_x509_trust_list_t list,
983
               const gnutls_datum_t *dn,
984
               const gnutls_datum_t *spki,
985
               gnutls_x509_crt_t *issuer,
986
               unsigned int flags)
987
0
{
988
0
  int ret;
989
0
  unsigned int i, j;
990
0
  size_t hash;
991
0
  uint8_t tmp[256];
992
0
  size_t tmp_size;
993
994
0
  if (dn) {
995
0
    hash = hash_pjw_bare(dn->data, dn->size);
996
0
    hash %= list->size;
997
998
0
    for (i = 0; i < list->node[hash].trusted_ca_size; i++) {
999
0
      ret = _gnutls_x509_compare_raw_dn(
1000
0
        dn, &list->node[hash].trusted_cas[i]->raw_dn);
1001
0
      if (ret != 0) {
1002
0
        if (spki && spki->size > 0) {
1003
0
          tmp_size = sizeof(tmp);
1004
1005
0
          ret = gnutls_x509_crt_get_subject_key_id(
1006
0
            list->node[hash].trusted_cas[i],
1007
0
            tmp, &tmp_size, NULL);
1008
0
          if (ret < 0)
1009
0
            continue;
1010
0
          if (spki->size != tmp_size ||
1011
0
              memcmp(spki->data, tmp,
1012
0
               spki->size) != 0)
1013
0
            continue;
1014
0
        }
1015
0
        *issuer = crt_cpy(
1016
0
          list->node[hash].trusted_cas[i]);
1017
0
        return 0;
1018
0
      }
1019
0
    }
1020
0
  } else if (spki) {
1021
    /* search everything! */
1022
0
    for (i = 0; i < list->size; i++) {
1023
0
      for (j = 0; j < list->node[i].trusted_ca_size; j++) {
1024
0
        tmp_size = sizeof(tmp);
1025
1026
0
        ret = gnutls_x509_crt_get_subject_key_id(
1027
0
          list->node[i].trusted_cas[j], tmp,
1028
0
          &tmp_size, NULL);
1029
0
        if (ret < 0)
1030
0
          continue;
1031
1032
0
        if (spki->size != tmp_size ||
1033
0
            memcmp(spki->data, tmp, spki->size) != 0)
1034
0
          continue;
1035
1036
0
        *issuer = crt_cpy(list->node[i].trusted_cas[j]);
1037
0
        return 0;
1038
0
      }
1039
0
    }
1040
0
  }
1041
1042
0
  return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1043
0
}
1044
1045
/**
1046
 * gnutls_x509_trust_list_get_issuer:
1047
 * @list: The list
1048
 * @cert: is the certificate to find issuer for
1049
 * @issuer: Will hold the issuer if any. Should be treated as constant
1050
 *   unless %GNUTLS_TL_GET_COPY is set in @flags.
1051
 * @flags: flags from %gnutls_trust_list_flags_t (%GNUTLS_TL_GET_COPY is applicable)
1052
 *
1053
 * This function will find the issuer of the given certificate.
1054
 * If the flag %GNUTLS_TL_GET_COPY is specified a copy of the issuer
1055
 * will be returned which must be freed using gnutls_x509_crt_deinit().
1056
 * In that case the provided @issuer must not be initialized.
1057
 *
1058
 * Note that the flag %GNUTLS_TL_GET_COPY is required for this function
1059
 * to work with PKCS#11 trust lists in a thread-safe way.
1060
 *
1061
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1062
 *   negative error value.
1063
 *
1064
 * Since: 3.0
1065
 **/
1066
int gnutls_x509_trust_list_get_issuer(gnutls_x509_trust_list_t list,
1067
              gnutls_x509_crt_t cert,
1068
              gnutls_x509_crt_t *issuer,
1069
              unsigned int flags)
1070
0
{
1071
0
  int ret;
1072
1073
0
  ret = _gnutls_trust_list_get_issuer(list, cert, issuer, flags);
1074
0
  if (ret == 0) {
1075
0
    return 0;
1076
0
  }
1077
1078
#ifdef ENABLE_PKCS11
1079
  if (ret < 0 && list->pkcs11_token) {
1080
    gnutls_x509_crt_t crt;
1081
    gnutls_datum_t der = { NULL, 0 };
1082
    /* use the token for verification */
1083
    ret = gnutls_pkcs11_get_raw_issuer(
1084
      list->pkcs11_token, cert, &der, GNUTLS_X509_FMT_DER,
1085
      GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE);
1086
    if (ret < 0) {
1087
      gnutls_assert();
1088
      return ret;
1089
    }
1090
1091
    ret = gnutls_x509_crt_init(&crt);
1092
    if (ret < 0) {
1093
      gnutls_free(der.data);
1094
      return gnutls_assert_val(ret);
1095
    }
1096
1097
    ret = gnutls_x509_crt_import(crt, &der, GNUTLS_X509_FMT_DER);
1098
    gnutls_free(der.data);
1099
    if (ret < 0) {
1100
      gnutls_x509_crt_deinit(crt);
1101
      return gnutls_assert_val(ret);
1102
    }
1103
1104
    if (flags & GNUTLS_TL_GET_COPY) {
1105
      *issuer = crt;
1106
      return 0;
1107
    } else {
1108
      /* we add this CA to the keep_cert list in order to make it
1109
       * persistent. It will be deallocated when the trust list is.
1110
       */
1111
      ret = trust_list_add_compat(list, crt);
1112
      if (ret < 0) {
1113
        gnutls_x509_crt_deinit(crt);
1114
        return gnutls_assert_val(ret);
1115
      }
1116
      *issuer = crt;
1117
      return ret;
1118
    }
1119
  }
1120
#endif
1121
0
  return ret;
1122
0
}
1123
1124
/**
1125
 * gnutls_x509_trust_list_get_issuer_by_dn:
1126
 * @list: The list
1127
 * @dn: is the issuer's DN
1128
 * @issuer: Will hold the issuer if any. Should be deallocated after use.
1129
 * @flags: Use zero
1130
 *
1131
 * This function will find the issuer with the given name, and
1132
 * return a copy of the issuer, which must be freed using gnutls_x509_crt_deinit().
1133
 *
1134
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1135
 *   negative error value.
1136
 *
1137
 * Since: 3.4.0
1138
 **/
1139
int gnutls_x509_trust_list_get_issuer_by_dn(gnutls_x509_trust_list_t list,
1140
              const gnutls_datum_t *dn,
1141
              gnutls_x509_crt_t *issuer,
1142
              unsigned int flags)
1143
0
{
1144
0
  int ret;
1145
1146
0
  ret = trust_list_get_issuer_by_dn(list, dn, NULL, issuer, flags);
1147
0
  if (ret == 0) {
1148
0
    return 0;
1149
0
  }
1150
1151
#ifdef ENABLE_PKCS11
1152
  if (ret < 0 && list->pkcs11_token) {
1153
    gnutls_x509_crt_t crt;
1154
    gnutls_datum_t der = { NULL, 0 };
1155
    /* use the token for verification */
1156
    ret = gnutls_pkcs11_get_raw_issuer_by_dn(
1157
      list->pkcs11_token, dn, &der, GNUTLS_X509_FMT_DER,
1158
      GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE);
1159
    if (ret < 0) {
1160
      gnutls_assert();
1161
      return ret;
1162
    }
1163
1164
    ret = gnutls_x509_crt_init(&crt);
1165
    if (ret < 0) {
1166
      gnutls_free(der.data);
1167
      return gnutls_assert_val(ret);
1168
    }
1169
1170
    ret = gnutls_x509_crt_import(crt, &der, GNUTLS_X509_FMT_DER);
1171
    gnutls_free(der.data);
1172
    if (ret < 0) {
1173
      gnutls_x509_crt_deinit(crt);
1174
      return gnutls_assert_val(ret);
1175
    }
1176
1177
    *issuer = crt;
1178
    return 0;
1179
  }
1180
#endif
1181
0
  return ret;
1182
0
}
1183
1184
/**
1185
 * gnutls_x509_trust_list_get_issuer_by_subject_key_id:
1186
 * @list: The list
1187
 * @dn: is the issuer's DN (may be %NULL)
1188
 * @spki: is the subject key ID
1189
 * @issuer: Will hold the issuer if any. Should be deallocated after use.
1190
 * @flags: Use zero
1191
 *
1192
 * This function will find the issuer with the given name and subject key ID, and
1193
 * return a copy of the issuer, which must be freed using gnutls_x509_crt_deinit().
1194
 *
1195
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1196
 *   negative error value.
1197
 *
1198
 * Since: 3.4.2
1199
 **/
1200
int gnutls_x509_trust_list_get_issuer_by_subject_key_id(
1201
  gnutls_x509_trust_list_t list, const gnutls_datum_t *dn,
1202
  const gnutls_datum_t *spki, gnutls_x509_crt_t *issuer,
1203
  unsigned int flags)
1204
0
{
1205
0
  int ret;
1206
1207
0
  ret = trust_list_get_issuer_by_dn(list, dn, spki, issuer, flags);
1208
0
  if (ret == 0) {
1209
0
    return 0;
1210
0
  }
1211
1212
#ifdef ENABLE_PKCS11
1213
  if (ret < 0 && list->pkcs11_token) {
1214
    gnutls_x509_crt_t crt;
1215
    gnutls_datum_t der = { NULL, 0 };
1216
    /* use the token for verification */
1217
    ret = gnutls_pkcs11_get_raw_issuer_by_subject_key_id(
1218
      list->pkcs11_token, dn, spki, &der, GNUTLS_X509_FMT_DER,
1219
      GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE);
1220
    if (ret < 0) {
1221
      gnutls_assert();
1222
      return ret;
1223
    }
1224
1225
    ret = gnutls_x509_crt_init(&crt);
1226
    if (ret < 0) {
1227
      gnutls_free(der.data);
1228
      return gnutls_assert_val(ret);
1229
    }
1230
1231
    ret = gnutls_x509_crt_import(crt, &der, GNUTLS_X509_FMT_DER);
1232
    gnutls_free(der.data);
1233
    if (ret < 0) {
1234
      gnutls_x509_crt_deinit(crt);
1235
      return gnutls_assert_val(ret);
1236
    }
1237
1238
    *issuer = crt;
1239
    return 0;
1240
  }
1241
#endif
1242
0
  return ret;
1243
0
}
1244
1245
static int check_if_in_blocklist(gnutls_x509_crt_t *cert_list,
1246
         unsigned int cert_list_size,
1247
         gnutls_x509_crt_t *blocklist,
1248
         unsigned int blocklist_size)
1249
0
{
1250
0
  unsigned i, j;
1251
1252
0
  if (blocklist_size == 0)
1253
0
    return 0;
1254
1255
0
  for (i = 0; i < cert_list_size; i++) {
1256
0
    for (j = 0; j < blocklist_size; j++) {
1257
0
      if (gnutls_x509_crt_equals(cert_list[i],
1258
0
               blocklist[j]) != 0) {
1259
0
        return 1;
1260
0
      }
1261
0
    }
1262
0
  }
1263
1264
0
  return 0;
1265
0
}
1266
1267
/**
1268
 * gnutls_x509_trust_list_verify_crt:
1269
 * @list: The list
1270
 * @cert_list: is the certificate list to be verified
1271
 * @cert_list_size: is the certificate list size
1272
 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
1273
 * @voutput: will hold the certificate verification output.
1274
 * @func: If non-null will be called on each chain element verification with the output.
1275
 *
1276
 * This function will try to verify the given certificate and return
1277
 * its status. The @voutput parameter will hold an OR'ed sequence of
1278
 * %gnutls_certificate_status_t flags.
1279
 *
1280
 * The details of the verification are the same as in gnutls_x509_trust_list_verify_crt2().
1281
 *
1282
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1283
 *   negative error value.
1284
 *
1285
 * Since: 3.0
1286
 **/
1287
int gnutls_x509_trust_list_verify_crt(gnutls_x509_trust_list_t list,
1288
              gnutls_x509_crt_t *cert_list,
1289
              unsigned int cert_list_size,
1290
              unsigned int flags, unsigned int *voutput,
1291
              gnutls_verify_output_function func)
1292
0
{
1293
0
  return gnutls_x509_trust_list_verify_crt2(
1294
0
    list, cert_list, cert_list_size, NULL, 0, flags, voutput, func);
1295
0
}
1296
1297
0
#define LAST_DN cert_list[cert_list_size - 1]->raw_dn
1298
0
#define LAST_IDN cert_list[cert_list_size - 1]->raw_issuer_dn
1299
/* This macro is introduced to detect a verification output which
1300
 * indicates an unknown signer, a signer which uses an insecure
1301
 * algorithm (e.g., sha1), a signer has expired, or something that
1302
 * indicates a superseded signer */
1303
#define SIGNER_OLD_OR_UNKNOWN(output)               \
1304
0
  ((output & GNUTLS_CERT_SIGNER_NOT_FOUND) || \
1305
0
   (output & GNUTLS_CERT_EXPIRED) ||          \
1306
0
   (output & GNUTLS_CERT_INSECURE_ALGORITHM))
1307
0
#define SIGNER_WAS_KNOWN(output) (!(output & GNUTLS_CERT_SIGNER_NOT_FOUND))
1308
1309
/**
1310
 * gnutls_x509_trust_list_verify_crt2:
1311
 * @list: The list
1312
 * @cert_list: is the certificate list to be verified
1313
 * @cert_list_size: is the certificate list size
1314
 * @data: an array of typed data
1315
 * @elements: the number of data elements
1316
 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
1317
 * @voutput: will hold the certificate verification output.
1318
 * @func: If non-null will be called on each chain element verification with the output.
1319
 *
1320
 * This function will attempt to verify the given certificate chain and return
1321
 * its status. The @voutput parameter will hold an OR'ed sequence of
1322
 * %gnutls_certificate_status_t flags.
1323
 *
1324
 * When a certificate chain of @cert_list_size with more than one certificates is
1325
 * provided, the verification status will apply to the first certificate in the chain
1326
 * that failed verification. The verification process starts from the end of the chain
1327
 * (from CA to end certificate). The first certificate in the chain must be the end-certificate
1328
 * while the rest of the members may be sorted or not.
1329
 *
1330
 * Additionally a certificate verification profile can be specified
1331
 * from the ones in %gnutls_certificate_verification_profiles_t by
1332
 * ORing the result of GNUTLS_PROFILE_TO_VFLAGS() to the verification
1333
 * flags.
1334
 *
1335
 * Additional verification parameters are possible via the @data types; the
1336
 * acceptable types are %GNUTLS_DT_DNS_HOSTNAME, %GNUTLS_DT_IP_ADDRESS and %GNUTLS_DT_KEY_PURPOSE_OID.
1337
 * The former accepts as data a null-terminated hostname, and the latter a null-terminated
1338
 * object identifier (e.g., %GNUTLS_KP_TLS_WWW_SERVER).
1339
 * If a DNS hostname is provided then this function will compare
1340
 * the hostname in the end certificate against the given. If names do not match the
1341
 * %GNUTLS_CERT_UNEXPECTED_OWNER status flag will be set. In addition it
1342
 * will consider certificates provided with gnutls_x509_trust_list_add_named_crt().
1343
 *
1344
 * If a key purpose OID is provided and the end-certificate contains the extended key
1345
 * usage PKIX extension, it will be required to match the provided OID
1346
 * or be marked for any purpose, otherwise verification will fail with 
1347
 * %GNUTLS_CERT_PURPOSE_MISMATCH status.
1348
 *
1349
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1350
 *   negative error value. Note that verification failure will not result to an
1351
 *   error code, only @voutput will be updated.
1352
 *
1353
 * Since: 3.3.8
1354
 **/
1355
int gnutls_x509_trust_list_verify_crt2(
1356
  gnutls_x509_trust_list_t list, gnutls_x509_crt_t *cert_list,
1357
  unsigned int cert_list_size, gnutls_typed_vdata_st *data,
1358
  unsigned int elements, unsigned int flags, unsigned int *voutput,
1359
  gnutls_verify_output_function func)
1360
0
{
1361
0
  int ret = 0;
1362
0
  unsigned int i;
1363
0
  size_t hash;
1364
0
  gnutls_x509_crt_t *cert_list_copy = NULL;
1365
0
  unsigned int cert_list_max_size = 0;
1366
0
  gnutls_x509_crt_t retrieved[DEFAULT_MAX_VERIFY_DEPTH];
1367
0
  unsigned int retrieved_size = 0;
1368
0
  const char *hostname = NULL, *purpose = NULL, *email = NULL;
1369
0
  unsigned hostname_size = 0;
1370
0
  unsigned have_set_name = 0;
1371
0
  unsigned saved_output;
1372
0
  gnutls_datum_t ip = { NULL, 0 };
1373
0
  gl_list_t records;
1374
1375
0
  if (cert_list == NULL || cert_list_size < 1)
1376
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1377
1378
0
  for (i = 0; i < elements; i++) {
1379
0
    if (data[i].type == GNUTLS_DT_DNS_HOSTNAME) {
1380
0
      hostname = (void *)data[i].data;
1381
0
      if (data[i].size > 0) {
1382
0
        hostname_size = data[i].size;
1383
0
      }
1384
1385
0
      if (have_set_name != 0)
1386
0
        return gnutls_assert_val(
1387
0
          GNUTLS_E_INVALID_REQUEST);
1388
0
      have_set_name = 1;
1389
0
    } else if (data[i].type == GNUTLS_DT_IP_ADDRESS) {
1390
0
      if (data[i].size > 0) {
1391
0
        ip.data = data[i].data;
1392
0
        ip.size = data[i].size;
1393
0
      }
1394
1395
0
      if (have_set_name != 0)
1396
0
        return gnutls_assert_val(
1397
0
          GNUTLS_E_INVALID_REQUEST);
1398
0
      have_set_name = 1;
1399
0
    } else if (data[i].type == GNUTLS_DT_RFC822NAME) {
1400
0
      email = (void *)data[i].data;
1401
1402
0
      if (have_set_name != 0)
1403
0
        return gnutls_assert_val(
1404
0
          GNUTLS_E_INVALID_REQUEST);
1405
0
      have_set_name = 1;
1406
0
    } else if (data[i].type == GNUTLS_DT_KEY_PURPOSE_OID) {
1407
0
      purpose = (void *)data[i].data;
1408
0
    }
1409
0
  }
1410
1411
0
  if (hostname) { /* shortcut using the named certs - if any */
1412
0
    unsigned vtmp = 0;
1413
0
    if (hostname_size == 0)
1414
0
      hostname_size = strlen(hostname);
1415
1416
0
    ret = gnutls_x509_trust_list_verify_named_crt(
1417
0
      list, cert_list[0], hostname, hostname_size, flags,
1418
0
      &vtmp, func);
1419
0
    if (ret == 0 && vtmp == 0) {
1420
0
      *voutput = vtmp;
1421
0
      return 0;
1422
0
    }
1423
0
  }
1424
1425
  /* Allocate extra for retrieved certificates. */
1426
0
  if (!INT_ADD_OK(cert_list_size, DEFAULT_MAX_VERIFY_DEPTH,
1427
0
      &cert_list_max_size))
1428
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1429
1430
0
  cert_list_copy = _gnutls_reallocarray(NULL, cert_list_max_size,
1431
0
                sizeof(gnutls_x509_crt_t));
1432
0
  if (!cert_list_copy)
1433
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1434
1435
0
  memcpy(cert_list_copy, cert_list,
1436
0
         cert_list_size * sizeof(gnutls_x509_crt_t));
1437
0
  cert_list = cert_list_copy;
1438
1439
0
  records = gl_list_nx_create_empty(GL_LINKEDHASH_LIST, cert_eq,
1440
0
            cert_hashcode, NULL, false);
1441
0
  if (records == NULL) {
1442
0
    ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1443
0
    goto cleanup;
1444
0
  }
1445
1446
0
  for (i = 0; i < cert_list_size;) {
1447
0
    unsigned int sorted_size = 1;
1448
0
    unsigned int j, k;
1449
0
    gnutls_x509_crt_t issuer;
1450
1451
0
    if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_UNSORTED_CHAIN)) {
1452
0
      sorted_size = _gnutls_sort_clist(&cert_list[i],
1453
0
               cert_list_size - i);
1454
0
    }
1455
1456
0
    assert(sorted_size > 0);
1457
1458
    /* Remove duplicates. */
1459
0
    for (j = 0; j < sorted_size; j++) {
1460
0
      if (gl_list_search(records, cert_list[i + j])) {
1461
0
        if (i + j < cert_list_size - 1) {
1462
0
          memmove(&cert_list[i + j],
1463
0
            &cert_list[i + j + 1],
1464
0
            sizeof(cert_list[i]));
1465
0
        }
1466
0
        cert_list_size--;
1467
0
        break;
1468
0
      }
1469
0
    }
1470
    /* Found a duplicate, try again with the same index. */
1471
0
    if (j < sorted_size) {
1472
0
      continue;
1473
0
    }
1474
1475
    /* Record the certificates seen. */
1476
0
    for (k = 0; k < sorted_size; k++, i++) {
1477
0
      if (!gl_list_nx_add_last(records, cert_list[i])) {
1478
0
        ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1479
0
        goto cleanup;
1480
0
      }
1481
0
    }
1482
1483
    /* Pacify GCC analyzer: the condition always holds
1484
     * true as sorted_size > 0 is checked above, and the
1485
     * following loop should iterate at least once so i++
1486
     * is called.
1487
     */
1488
0
    assert(i > 0);
1489
1490
    /* If the issuer of the certificate is known, no need
1491
     * for further processing. */
1492
0
    if (gnutls_x509_trust_list_get_issuer(
1493
0
          list, cert_list[i - 1], &issuer,
1494
0
          GNUTLS_TL_GET_COPY) == 0) {
1495
0
      gnutls_x509_crt_deinit(issuer);
1496
0
      cert_list_size = i;
1497
0
      break;
1498
0
    }
1499
1500
    /* If there is no gap between this and the next certificate,
1501
     * proceed with the next certificate. */
1502
0
    if (i < cert_list_size &&
1503
0
        gnutls_x509_crt_check_issuer(cert_list[i - 1],
1504
0
             cert_list[i])) {
1505
0
      continue;
1506
0
    }
1507
1508
0
    ret = retrieve_issuers(
1509
0
      list, cert_list[i - 1], &retrieved[retrieved_size],
1510
0
      MIN(DEFAULT_MAX_VERIFY_DEPTH - retrieved_size,
1511
0
          cert_list_max_size - cert_list_size));
1512
0
    if (ret < 0) {
1513
0
      break;
1514
0
    } else if (ret > 0) {
1515
0
      assert((unsigned int)ret <=
1516
0
             DEFAULT_MAX_VERIFY_DEPTH - retrieved_size);
1517
0
      assert((unsigned int)ret <=
1518
0
             cert_list_max_size - cert_list_size);
1519
0
      memmove(&cert_list[i + ret], &cert_list[i],
1520
0
        (cert_list_size - i) *
1521
0
          sizeof(gnutls_x509_crt_t));
1522
0
      memcpy(&cert_list[i], &retrieved[retrieved_size],
1523
0
             ret * sizeof(gnutls_x509_crt_t));
1524
0
      retrieved_size += ret;
1525
0
      cert_list_size += ret;
1526
1527
      /* Start again from the end of the previous segment. */
1528
0
      i--;
1529
0
      gl_list_remove(records, cert_list[i]);
1530
0
    }
1531
0
  }
1532
1533
0
  cert_list_size = shorten_clist(list, cert_list, cert_list_size);
1534
0
  if (cert_list_size <= 0) {
1535
0
    ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1536
0
    goto cleanup;
1537
0
  }
1538
1539
0
  hash = hash_pjw_bare(cert_list[cert_list_size - 1]->raw_issuer_dn.data,
1540
0
           cert_list[cert_list_size - 1]->raw_issuer_dn.size);
1541
0
  hash %= list->size;
1542
1543
0
  ret = check_if_in_blocklist(cert_list, cert_list_size, list->distrusted,
1544
0
            list->distrusted_size);
1545
0
  if (ret != 0) {
1546
0
    *voutput = 0;
1547
0
    *voutput |= GNUTLS_CERT_REVOKED;
1548
0
    *voutput |= GNUTLS_CERT_INVALID;
1549
0
    ret = 0;
1550
0
    goto cleanup;
1551
0
  }
1552
1553
0
  *voutput = _gnutls_verify_crt_status(list, cert_list, cert_list_size,
1554
0
               list->node[hash].trusted_cas,
1555
0
               list->node[hash].trusted_ca_size,
1556
0
               flags, purpose, func);
1557
0
  saved_output = *voutput;
1558
1559
0
  if (SIGNER_OLD_OR_UNKNOWN(*voutput) &&
1560
0
      (LAST_DN.size != LAST_IDN.size ||
1561
0
       memcmp(LAST_DN.data, LAST_IDN.data, LAST_IDN.size) != 0)) {
1562
    /* if we couldn't find the issuer, try to see if the last
1563
     * certificate is in the trusted list and try to verify against
1564
     * (if it is not self signed) */
1565
0
    hash = hash_pjw_bare(
1566
0
      cert_list[cert_list_size - 1]->raw_dn.data,
1567
0
      cert_list[cert_list_size - 1]->raw_dn.size);
1568
0
    hash %= list->size;
1569
1570
0
    _gnutls_debug_log(
1571
0
      "issuer in verification was not found or insecure; trying against trust list\n");
1572
1573
0
    *voutput = _gnutls_verify_crt_status(
1574
0
      list, cert_list, cert_list_size,
1575
0
      list->node[hash].trusted_cas,
1576
0
      list->node[hash].trusted_ca_size, flags, purpose, func);
1577
0
    if (*voutput != 0) {
1578
0
      if (SIGNER_WAS_KNOWN(saved_output))
1579
0
        *voutput = saved_output;
1580
0
      gnutls_assert();
1581
0
    }
1582
0
  }
1583
1584
0
  saved_output = *voutput;
1585
1586
#ifdef ENABLE_PKCS11
1587
  if (SIGNER_OLD_OR_UNKNOWN(*voutput) && list->pkcs11_token) {
1588
    /* use the token for verification */
1589
1590
    *voutput = _gnutls_pkcs11_verify_crt_status(
1591
      list, list->pkcs11_token, cert_list, cert_list_size,
1592
      purpose, flags, func);
1593
    if (*voutput != 0) {
1594
      if (SIGNER_WAS_KNOWN(saved_output))
1595
        *voutput = saved_output;
1596
      gnutls_assert();
1597
    }
1598
  }
1599
#endif
1600
1601
  /* End-certificate, key purpose and hostname checks. */
1602
0
  if (purpose) {
1603
0
    ret = _gnutls_check_key_purpose(cert_list[0], purpose, 0);
1604
0
    if (ret != 1) {
1605
0
      gnutls_assert();
1606
0
      *voutput |= GNUTLS_CERT_PURPOSE_MISMATCH |
1607
0
            GNUTLS_CERT_INVALID;
1608
0
    }
1609
0
  }
1610
1611
0
  if (hostname) {
1612
0
    ret = gnutls_x509_crt_check_hostname2(cert_list[0], hostname,
1613
0
                  flags);
1614
0
    if (ret == 0) {
1615
0
      gnutls_assert();
1616
0
      *voutput |= GNUTLS_CERT_UNEXPECTED_OWNER |
1617
0
            GNUTLS_CERT_INVALID;
1618
0
    }
1619
0
  }
1620
1621
0
  if (ip.data) {
1622
0
    ret = gnutls_x509_crt_check_ip(cert_list[0], ip.data, ip.size,
1623
0
                 flags);
1624
0
    if (ret == 0) {
1625
0
      gnutls_assert();
1626
0
      *voutput |= GNUTLS_CERT_UNEXPECTED_OWNER |
1627
0
            GNUTLS_CERT_INVALID;
1628
0
    }
1629
0
  }
1630
1631
0
  if (email) {
1632
0
    ret = gnutls_x509_crt_check_email(cert_list[0], email, 0);
1633
0
    if (ret == 0) {
1634
0
      gnutls_assert();
1635
0
      *voutput |= GNUTLS_CERT_UNEXPECTED_OWNER |
1636
0
            GNUTLS_CERT_INVALID;
1637
0
    }
1638
0
  }
1639
1640
  /* CRL checks follow */
1641
1642
0
  if (*voutput != 0 || (flags & GNUTLS_VERIFY_DISABLE_CRL_CHECKS)) {
1643
0
    ret = 0;
1644
0
    goto cleanup;
1645
0
  }
1646
1647
  /* Check revocation of individual certificates.
1648
   * start with the last one that we already have its hash
1649
   */
1650
0
  ret = _gnutls_x509_crt_check_revocation(cert_list[cert_list_size - 1],
1651
0
            list->node[hash].crls,
1652
0
            list->node[hash].crl_size,
1653
0
            func);
1654
0
  if (ret == 1) { /* revoked */
1655
0
    *voutput |= GNUTLS_CERT_REVOKED;
1656
0
    *voutput |= GNUTLS_CERT_INVALID;
1657
0
    ret = 0;
1658
0
    goto cleanup;
1659
0
  }
1660
1661
0
  for (i = 0; i < cert_list_size - 1; i++) {
1662
0
    hash = hash_pjw_bare(cert_list[i]->raw_issuer_dn.data,
1663
0
             cert_list[i]->raw_issuer_dn.size);
1664
0
    hash %= list->size;
1665
1666
0
    ret = _gnutls_x509_crt_check_revocation(
1667
0
      cert_list[i], list->node[hash].crls,
1668
0
      list->node[hash].crl_size, func);
1669
0
    if (ret < 0) {
1670
0
      gnutls_assert();
1671
0
    } else if (ret == 1) { /* revoked */
1672
0
      *voutput |= GNUTLS_CERT_REVOKED;
1673
0
      *voutput |= GNUTLS_CERT_INVALID;
1674
0
      ret = 0;
1675
0
      goto cleanup;
1676
0
    }
1677
0
  }
1678
1679
0
cleanup:
1680
0
  gnutls_free(cert_list_copy);
1681
0
  for (i = 0; i < retrieved_size; i++) {
1682
0
    gnutls_x509_crt_deinit(retrieved[i]);
1683
0
  }
1684
0
  if (records) {
1685
0
    gl_list_free(records);
1686
0
  }
1687
0
  return ret;
1688
0
}
1689
1690
/**
1691
 * gnutls_x509_trust_list_verify_named_crt:
1692
 * @list: The list
1693
 * @cert: is the certificate to be verified
1694
 * @name: is the certificate's name
1695
 * @name_size: is the certificate's name size
1696
 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
1697
 * @voutput: will hold the certificate verification output.
1698
 * @func: If non-null will be called on each chain element verification with the output.
1699
 *
1700
 * This function will try to find a certificate that is associated with the provided
1701
 * name --see gnutls_x509_trust_list_add_named_crt(). If a match is found the
1702
 * certificate is considered valid. In addition to that this function will also 
1703
 * check CRLs. The @voutput parameter will hold an OR'ed sequence of 
1704
 * %gnutls_certificate_status_t flags.
1705
 *
1706
 * Additionally a certificate verification profile can be specified
1707
 * from the ones in %gnutls_certificate_verification_profiles_t by
1708
 * ORing the result of GNUTLS_PROFILE_TO_VFLAGS() to the verification
1709
 * flags.
1710
 *
1711
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1712
 *   negative error value.
1713
 *
1714
 * Since: 3.0.0
1715
 **/
1716
int gnutls_x509_trust_list_verify_named_crt(gnutls_x509_trust_list_t list,
1717
              gnutls_x509_crt_t cert,
1718
              const void *name, size_t name_size,
1719
              unsigned int flags,
1720
              unsigned int *voutput,
1721
              gnutls_verify_output_function func)
1722
0
{
1723
0
  int ret;
1724
0
  unsigned int i;
1725
0
  size_t hash;
1726
1727
0
  hash = hash_pjw_bare(cert->raw_issuer_dn.data,
1728
0
           cert->raw_issuer_dn.size);
1729
0
  hash %= list->size;
1730
1731
0
  ret = check_if_in_blocklist(&cert, 1, list->distrusted,
1732
0
            list->distrusted_size);
1733
0
  if (ret != 0) {
1734
0
    *voutput = 0;
1735
0
    *voutput |= GNUTLS_CERT_REVOKED;
1736
0
    *voutput |= GNUTLS_CERT_INVALID;
1737
0
    return 0;
1738
0
  }
1739
1740
0
  *voutput = GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNER_NOT_FOUND;
1741
1742
0
  for (i = 0; i < list->node[hash].named_cert_size; i++) {
1743
0
    if (gnutls_x509_crt_equals(
1744
0
          cert, list->node[hash].named_certs[i].cert) !=
1745
0
        0) { /* check if name matches */
1746
0
      if (list->node[hash].named_certs[i].name_size ==
1747
0
            name_size &&
1748
0
          memcmp(list->node[hash].named_certs[i].name, name,
1749
0
           name_size) == 0) {
1750
0
        *voutput = 0;
1751
0
        break;
1752
0
      }
1753
0
    }
1754
0
  }
1755
1756
0
  if (*voutput != 0 || (flags & GNUTLS_VERIFY_DISABLE_CRL_CHECKS))
1757
0
    return 0;
1758
1759
  /* Check revocation of individual certificates.
1760
   * start with the last one that we already have its hash
1761
   */
1762
0
  ret = _gnutls_x509_crt_check_revocation(
1763
0
    cert, list->node[hash].crls, list->node[hash].crl_size, func);
1764
0
  if (ret == 1) { /* revoked */
1765
0
    *voutput |= GNUTLS_CERT_REVOKED;
1766
0
    *voutput |= GNUTLS_CERT_INVALID;
1767
0
    return 0;
1768
0
  }
1769
1770
0
  return 0;
1771
0
}
1772
1773
/* return 1 if @cert is in @list, 0 if not */
1774
int _gnutls_trustlist_inlist(gnutls_x509_trust_list_t list,
1775
           gnutls_x509_crt_t cert)
1776
0
{
1777
0
  int ret;
1778
0
  unsigned int i;
1779
0
  size_t hash;
1780
1781
0
  hash = hash_pjw_bare(cert->raw_dn.data, cert->raw_dn.size);
1782
0
  hash %= list->size;
1783
1784
0
  for (i = 0; i < list->node[hash].trusted_ca_size; i++) {
1785
0
    ret = gnutls_x509_crt_equals(cert,
1786
0
               list->node[hash].trusted_cas[i]);
1787
0
    if (ret != 0)
1788
0
      return 1;
1789
0
  }
1790
1791
0
  return 0;
1792
0
}