37
37
#define INIT_HASH 0x33a1
39
39
struct named_cert_st {
40
gnutls_x509_crt_t cert;
41
uint8_t name[MAX_NAME_SIZE];
42
unsigned int name_size;
40
gnutls_x509_crt_t cert;
41
uint8_t name[MAX_NAME_SIZE];
42
unsigned int name_size;
46
/* The trusted certificates */
47
gnutls_x509_crt_t * trusted_cas;
48
unsigned int trusted_ca_size;
50
struct named_cert_st *named_certs;
51
unsigned int named_cert_size;
53
/* The trusted CRLs */
54
gnutls_x509_crl_t * crls;
55
unsigned int crl_size;
46
/* The trusted certificates */
47
gnutls_x509_crt_t *trusted_cas;
48
unsigned int trusted_ca_size;
50
struct named_cert_st *named_certs;
51
unsigned int named_cert_size;
53
/* The trusted CRLs */
54
gnutls_x509_crl_t *crls;
55
unsigned int crl_size;
58
58
struct gnutls_x509_trust_list_st {
76
gnutls_x509_trust_list_init (gnutls_x509_trust_list_t * list, unsigned int size)
76
gnutls_x509_trust_list_init(gnutls_x509_trust_list_t * list,
78
gnutls_x509_trust_list_t tmp = gnutls_calloc (1, sizeof (struct gnutls_x509_trust_list_st));
81
return GNUTLS_E_MEMORY_ERROR;
83
if (size == 0) size = DEFAULT_SIZE;
86
tmp->node = gnutls_calloc(1, tmp->size * sizeof(tmp->node[0]));
87
if (tmp->node == NULL)
91
return GNUTLS_E_MEMORY_ERROR;
79
gnutls_x509_trust_list_t tmp =
80
gnutls_calloc(1, sizeof(struct gnutls_x509_trust_list_st));
83
return GNUTLS_E_MEMORY_ERROR;
89
tmp->node = gnutls_calloc(1, tmp->size * sizeof(tmp->node[0]));
90
if (tmp->node == NULL) {
93
return GNUTLS_E_MEMORY_ERROR;
96
return 0; /* success */
98
return 0; /* success */
109
gnutls_x509_trust_list_deinit (gnutls_x509_trust_list_t list, unsigned int all)
111
gnutls_x509_trust_list_deinit(gnutls_x509_trust_list_t list,
118
for (i=0;i<list->size;i++)
120
for (j=0;j<list->node[i].trusted_ca_size;j++)
122
gnutls_x509_crt_deinit(list->node[i].trusted_cas[j]);
124
gnutls_free(list->node[i].trusted_cas);
125
for (j=0;j<list->node[i].crl_size;j++)
127
gnutls_x509_crl_deinit(list->node[i].crls[j]);
129
gnutls_free(list->node[i].crls);
119
for (i = 0; i < list->size; i++) {
121
for (j = 0; j < list->node[i].trusted_ca_size; j++) {
122
gnutls_x509_crt_deinit(list->node[i].trusted_cas[j]);
124
gnutls_free(list->node[i].trusted_cas);
127
for (j = 0; j < list->node[i].crl_size; j++) {
128
gnutls_x509_crl_deinit(list->node[i].crls[j]);
130
gnutls_free(list->node[i].crls);
131
gnutls_free(list->node[i].named_certs);
133
gnutls_free (list->node);
134
gnutls_free(list->node);
153
gnutls_x509_trust_list_add_cas (gnutls_x509_trust_list_t list,
154
const gnutls_x509_crt_t * clist, int clist_size, unsigned int flags)
154
gnutls_x509_trust_list_add_cas(gnutls_x509_trust_list_t list,
155
const gnutls_x509_crt_t * clist,
156
int clist_size, unsigned int flags)
160
for (i=0;i<clist_size;i++)
162
for (i = 0; i < clist_size; i++) {
162
163
ret = gnutls_x509_crt_get_raw_dn(clist[i], &dn);
169
169
hash = _gnutls_bhash(dn.data, dn.size, INIT_HASH);
170
170
hash %= list->size;
172
172
_gnutls_free_datum(&dn);
174
list->node[hash].trusted_cas = gnutls_realloc_fast( list->node[hash].trusted_cas, (list->node[hash].trusted_ca_size+1)*sizeof(list->node[hash].trusted_cas[0]));
175
if (list->node[hash].trusted_cas == NULL)
173
list->node[hash].trusted_cas =
174
gnutls_realloc_fast(list->node[hash].trusted_cas,
175
(list->node[hash].trusted_ca_size +
177
sizeof(list->node[hash].trusted_cas[0]));
178
if (list->node[hash].trusted_cas == NULL) {
181
list->node[hash].trusted_cas[list->node[hash].trusted_ca_size] = clist[i];
183
list->node[hash].trusted_cas[list->node[hash].trusted_ca_size] =
182
185
list->node[hash].trusted_ca_size++;
214
gnutls_x509_trust_list_add_named_crt (gnutls_x509_trust_list_t list,
215
gnutls_x509_crt_t cert, const void* name, size_t name_size, unsigned int flags)
217
gnutls_x509_trust_list_add_named_crt(gnutls_x509_trust_list_t list,
218
gnutls_x509_crt_t cert,
219
const void *name, size_t name_size,
221
if (name_size >= MAX_NAME_SIZE)
222
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
224
ret = gnutls_x509_crt_get_raw_issuer_dn(cert, &dn);
226
if (name_size >= MAX_NAME_SIZE)
227
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
229
ret = gnutls_x509_crt_get_raw_issuer_dn(cert, &dn);
231
hash = _gnutls_bhash(dn.data, dn.size, INIT_HASH);
234
_gnutls_free_datum(&dn);
236
list->node[hash].named_certs = gnutls_realloc_fast( list->node[hash].named_certs, (list->node[hash].named_cert_size+1)*sizeof(list->node[hash].named_certs[0]));
237
if (list->node[hash].named_certs == NULL)
238
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
240
list->node[hash].named_certs[list->node[hash].named_cert_size].cert = cert;
241
memcpy(list->node[hash].named_certs[list->node[hash].named_cert_size].name, name, name_size);
242
list->node[hash].named_certs[list->node[hash].named_cert_size].name_size = name_size;
244
list->node[hash].named_cert_size++;
235
hash = _gnutls_bhash(dn.data, dn.size, INIT_HASH);
238
_gnutls_free_datum(&dn);
240
list->node[hash].named_certs =
241
gnutls_realloc_fast(list->node[hash].named_certs,
242
(list->node[hash].named_cert_size +
243
1) * sizeof(list->node[hash].named_certs[0]));
244
if (list->node[hash].named_certs == NULL)
245
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
247
list->node[hash].named_certs[list->node[hash].named_cert_size].cert =
249
memcpy(list->node[hash].named_certs[list->node[hash].named_cert_size].
250
name, name, name_size);
251
list->node[hash].named_certs[list->node[hash].named_cert_size].
252
name_size = name_size;
254
list->node[hash].named_cert_size++;
269
gnutls_x509_trust_list_add_crls (gnutls_x509_trust_list_t list,
270
const gnutls_x509_crl_t * crl_list, int crl_size, unsigned int flags,
271
unsigned int verification_flags)
279
gnutls_x509_trust_list_add_crls(gnutls_x509_trust_list_t list,
280
const gnutls_x509_crl_t * crl_list,
281
int crl_size, unsigned int flags,
282
unsigned int verification_flags)
275
unsigned int vret = 0;
278
/* Probably we can optimize things such as removing duplicates
282
if (crl_size == 0 || crl_list == NULL)
285
for (i=0;i<crl_size;i++)
286
unsigned int vret = 0;
289
/* Probably we can optimize things such as removing duplicates
293
if (crl_size == 0 || crl_list == NULL)
296
for (i = 0; i < crl_size; i++) {
287
297
ret = gnutls_x509_crl_get_raw_issuer_dn(crl_list[i], &dn);
294
303
hash = _gnutls_bhash(dn.data, dn.size, INIT_HASH);
295
304
hash %= list->size;
297
306
_gnutls_free_datum(&dn);
299
if (flags & GNUTLS_TL_VERIFY_CRL)
308
if (flags & GNUTLS_TL_VERIFY_CRL) {
302
ret = gnutls_x509_crl_verify(crl_list[i], list->node[hash].trusted_cas,
303
list->node[hash].trusted_ca_size, verification_flags, &vret);
311
gnutls_x509_crl_verify(crl_list[i],
312
list->node[hash].trusted_cas,
313
list->node[hash].trusted_ca_size,
314
verification_flags, &vret);
304
315
if (ret < 0 || vret != 0)
308
list->node[hash].crls = gnutls_realloc_fast( list->node[hash].crls, (list->node[hash].crl_size+1)*sizeof(list->node[hash].trusted_cas[0]));
309
if (list->node[hash].crls == NULL)
319
list->node[hash].crls =
320
gnutls_realloc_fast(list->node[hash].crls,
321
(list->node[hash].crl_size +
323
sizeof(list->node[hash].trusted_cas[0]));
324
if (list->node[hash].crls == NULL) {
315
329
list->node[hash].crls[list->node[hash].crl_size] = crl_list[i];
316
330
list->node[hash].crl_size++;
323
337
/* Takes a certificate list and shortens it if there are
328
342
* Returns the new size of the list or a negative number on error.
330
344
static int shorten_clist(gnutls_x509_trust_list_t list,
331
gnutls_x509_crt_t* certificate_list, int clist_size)
345
gnutls_x509_crt_t * certificate_list,
339
/* Check if the last certificate in the path is self signed.
340
* In that case ignore it (a certificate is trusted only if it
341
* leads to a trusted party by us, not the server's).
343
* This prevents from verifying self signed certificates against
344
* themselves. This (although not bad) caused verification
345
* failures on some root self signed certificates that use the
348
if (gnutls_x509_crt_check_issuer (certificate_list[clist_size - 1],
349
certificate_list[clist_size - 1]) > 0)
352
if (clist_size > 1) {
353
/* Check if the last certificate in the path is self signed.
354
* In that case ignore it (a certificate is trusted only if it
355
* leads to a trusted party by us, not the server's).
357
* This prevents from verifying self signed certificates against
358
* themselves. This (although not bad) caused verification
359
* failures on some root self signed certificates that use the
362
if (gnutls_x509_crt_check_issuer(certificate_list[clist_size - 1],
363
certificate_list[clist_size -
355
/* We want to shorten the chain by removing the cert that matches
356
* one of the certs we trust and all the certs after that i.e. if
357
* cert chain is A signed-by B signed-by C signed-by D (signed-by
358
* self-signed E but already removed above), and we trust B, remove
360
for (i=1; i < clist_size; i++)
369
/* We want to shorten the chain by removing the cert that matches
370
* one of the certs we trust and all the certs after that i.e. if
371
* cert chain is A signed-by B signed-by C signed-by D (signed-by
372
* self-signed E but already removed above), and we trust B, remove
374
for (i = 1; i < clist_size; i++) {
364
ret = gnutls_x509_crt_get_raw_issuer_dn(certificate_list[i], &dn);
377
ret = gnutls_x509_crt_get_raw_issuer_dn(certificate_list[i], &dn);
371
hash = _gnutls_bhash(dn.data, dn.size, INIT_HASH);
374
_gnutls_free_datum(&dn);
376
for (j = 0; j < list->node[hash].trusted_ca_size; j++)
378
if (check_if_same_cert (certificate_list[i], list->node[hash].trusted_cas[j]) == 0)
380
/* cut the list at the point of first the trusted certificate */
383
hash = _gnutls_bhash(dn.data, dn.size, INIT_HASH);
386
_gnutls_free_datum(&dn);
388
for (j = 0; j < list->node[hash].trusted_ca_size; j++) {
389
if (check_if_same_cert
390
(certificate_list[i],
391
list->node[hash].trusted_cas[j]) == 0) {
392
/* cut the list at the point of first the trusted certificate */
385
/* clist_size may have been changed which gets out of loop */
397
/* clist_size may have been changed which gets out of loop */
406
418
int gnutls_x509_trust_list_get_issuer(gnutls_x509_trust_list_t list,
407
gnutls_x509_crt_t cert, gnutls_x509_crt_t* issuer, unsigned int flags)
419
gnutls_x509_crt_t cert,
420
gnutls_x509_crt_t * issuer,
413
ret = gnutls_x509_crt_get_raw_issuer_dn(cert, &dn);
427
ret = gnutls_x509_crt_get_raw_issuer_dn(cert, &dn);
420
hash = _gnutls_bhash(dn.data, dn.size, INIT_HASH);
423
_gnutls_free_datum(&dn);
425
for (i=0;i<list->node[hash].trusted_ca_size;i++)
427
ret = gnutls_x509_crt_check_issuer (cert, list->node[hash].trusted_cas[i]);
430
*issuer = list->node[hash].trusted_cas[i];
433
hash = _gnutls_bhash(dn.data, dn.size, INIT_HASH);
436
_gnutls_free_datum(&dn);
438
for (i = 0; i < list->node[hash].trusted_ca_size; i++) {
440
gnutls_x509_crt_check_issuer(cert,
441
list->node[hash].trusted_cas[i]);
443
*issuer = list->node[hash].trusted_cas[i];
435
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
448
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
456
gnutls_x509_trust_list_verify_crt (
457
gnutls_x509_trust_list_t list,
458
gnutls_x509_crt_t *cert_list,
459
unsigned int cert_list_size,
461
unsigned int *verify,
462
gnutls_verify_output_function func)
469
gnutls_x509_trust_list_verify_crt(gnutls_x509_trust_list_t list,
470
gnutls_x509_crt_t * cert_list,
471
unsigned int cert_list_size,
473
unsigned int *verify,
474
gnutls_verify_output_function func)
468
if (cert_list == NULL || cert_list_size < 1)
469
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
471
cert_list_size = shorten_clist(list, cert_list, cert_list_size);
472
if (cert_list_size <= 0)
473
return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
475
ret = gnutls_x509_crt_get_raw_issuer_dn(cert_list[cert_list_size-1], &dn);
482
hash = _gnutls_bhash(dn.data, dn.size, INIT_HASH);
485
_gnutls_free_datum(&dn);
487
*verify = _gnutls_x509_verify_certificate(cert_list, cert_list_size,
488
list->node[hash].trusted_cas, list->node[hash].trusted_ca_size,
491
if (*verify != 0 || (flags & GNUTLS_VERIFY_DISABLE_CRL_CHECKS)) return 0;
493
/* Check revocation of individual certificates.
494
* start with the last one that we already have its hash
496
ret = _gnutls_x509_crt_check_revocation (cert_list[cert_list_size-1],
497
list->node[hash].crls,
498
list->node[hash].crl_size, func);
501
*verify |= GNUTLS_CERT_REVOKED;
502
*verify |= GNUTLS_CERT_INVALID;
506
for (i=0;i<cert_list_size-1;i++)
508
ret = gnutls_x509_crt_get_raw_issuer_dn(cert_list[i], &dn);
515
hash = _gnutls_bhash(dn.data, dn.size, INIT_HASH);
518
_gnutls_free_datum(&dn);
520
ret = _gnutls_x509_crt_check_revocation (cert_list[i],
521
list->node[hash].crls,
522
list->node[hash].crl_size, func);
525
*verify |= GNUTLS_CERT_REVOKED;
526
*verify |= GNUTLS_CERT_INVALID;
480
if (cert_list == NULL || cert_list_size < 1)
481
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
483
cert_list_size = shorten_clist(list, cert_list, cert_list_size);
484
if (cert_list_size <= 0)
485
return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
488
gnutls_x509_crt_get_raw_issuer_dn(cert_list[cert_list_size - 1],
495
hash = _gnutls_bhash(dn.data, dn.size, INIT_HASH);
498
_gnutls_free_datum(&dn);
500
*verify = _gnutls_x509_verify_certificate(cert_list, cert_list_size,
501
list->node[hash].trusted_cas,
503
trusted_ca_size, flags,
506
if (*verify != 0 || (flags & GNUTLS_VERIFY_DISABLE_CRL_CHECKS))
509
/* Check revocation of individual certificates.
510
* start with the last one that we already have its hash
512
ret = _gnutls_x509_crt_check_revocation(cert_list[cert_list_size - 1],
513
list->node[hash].crls,
514
list->node[hash].crl_size,
516
if (ret == 1) { /* revoked */
517
*verify |= GNUTLS_CERT_REVOKED;
518
*verify |= GNUTLS_CERT_INVALID;
522
for (i = 0; i < cert_list_size - 1; i++) {
523
ret = gnutls_x509_crt_get_raw_issuer_dn(cert_list[i], &dn);
529
hash = _gnutls_bhash(dn.data, dn.size, INIT_HASH);
532
_gnutls_free_datum(&dn);
534
ret = _gnutls_x509_crt_check_revocation(cert_list[i],
535
list->node[hash].crls,
536
list->node[hash].crl_size,
538
if (ret == 1) { /* revoked */
539
*verify |= GNUTLS_CERT_REVOKED;
540
*verify |= GNUTLS_CERT_INVALID;
554
gnutls_x509_trust_list_verify_named_crt (
555
gnutls_x509_trust_list_t list,
556
gnutls_x509_crt_t cert,
560
unsigned int *verify,
561
gnutls_verify_output_function func)
568
gnutls_x509_trust_list_verify_named_crt(gnutls_x509_trust_list_t list,
569
gnutls_x509_crt_t cert,
573
unsigned int *verify,
574
gnutls_verify_output_function func)
567
ret = gnutls_x509_crt_get_raw_issuer_dn(cert, &dn);
580
ret = gnutls_x509_crt_get_raw_issuer_dn(cert, &dn);
574
hash = _gnutls_bhash(dn.data, dn.size, INIT_HASH);
577
_gnutls_free_datum(&dn);
579
*verify = GNUTLS_CERT_INVALID;
581
for (i=0;i<list->node[hash].named_cert_size;i++)
583
if (check_if_same_cert(cert, list->node[hash].named_certs[i].cert)==0)
584
{ /* check if name matches */
585
if (list->node[hash].named_certs[i].name_size==name_size &&
586
memcmp(list->node[hash].named_certs[i].name, name, name_size) == 0)
586
hash = _gnutls_bhash(dn.data, dn.size, INIT_HASH);
589
_gnutls_free_datum(&dn);
591
*verify = GNUTLS_CERT_INVALID;
593
for (i = 0; i < list->node[hash].named_cert_size; i++) {
594
if (check_if_same_cert(cert, list->node[hash].named_certs[i].cert) == 0) { /* check if name matches */
595
if (list->node[hash].named_certs[i].name_size == name_size &&
596
memcmp(list->node[hash].named_certs[i].name, name,
594
if (*verify != 0 || (flags & GNUTLS_VERIFY_DISABLE_CRL_CHECKS)) return 0;
604
if (*verify != 0 || (flags & GNUTLS_VERIFY_DISABLE_CRL_CHECKS))
596
/* Check revocation of individual certificates.
597
* start with the last one that we already have its hash
599
ret = _gnutls_x509_crt_check_revocation (cert,
600
list->node[hash].crls,
601
list->node[hash].crl_size, func);
604
*verify |= GNUTLS_CERT_REVOKED;
605
*verify |= GNUTLS_CERT_INVALID;
607
/* Check revocation of individual certificates.
608
* start with the last one that we already have its hash
610
ret = _gnutls_x509_crt_check_revocation(cert,
611
list->node[hash].crls,
612
list->node[hash].crl_size,
614
if (ret == 1) { /* revoked */
615
*verify |= GNUTLS_CERT_REVOKED;
616
*verify |= GNUTLS_CERT_INVALID;