Coverage Report

Created: 2023-03-26 07:33

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