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