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