Use hash-pjw-bare instead of asn1_bhash().
[gnutls.git] / lib / x509 / verify-high.c
blob5dafd6308a436483cc7f1b2f7c7023efe836c7fc
1 /*
2 * Copyright (C) 2011-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 #include <gnutls_int.h>
24 #include <gnutls_errors.h>
25 #include <libtasn1.h>
26 #include <gnutls_global.h>
27 #include <gnutls_num.h> /* MAX */
28 #include <gnutls_sig.h>
29 #include <gnutls_str.h>
30 #include <gnutls_datum.h>
31 #include <hash-pjw-bare.h>
32 #include "x509_int.h"
33 #include <common.h>
34 #include "verify-high.h"
36 struct named_cert_st {
37 gnutls_x509_crt_t cert;
38 uint8_t name[MAX_SERVER_NAME_SIZE];
39 unsigned int name_size;
42 struct node_st {
43 /* The trusted certificates */
44 gnutls_x509_crt_t *trusted_cas;
45 unsigned int trusted_ca_size;
47 struct named_cert_st *named_certs;
48 unsigned int named_cert_size;
50 /* The trusted CRLs */
51 gnutls_x509_crl_t *crls;
52 unsigned int crl_size;
55 struct gnutls_x509_trust_list_st {
56 unsigned int size;
57 struct node_st *node;
60 #define DEFAULT_SIZE 503
62 /**
63 * gnutls_x509_trust_list_init:
64 * @list: The structure to be initialized
65 * @size: The size of the internal hash table. Use (0) for default size.
67 * This function will initialize an X.509 trust list structure.
69 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
70 * negative error value.
72 * Since: 3.0
73 **/
74 int
75 gnutls_x509_trust_list_init(gnutls_x509_trust_list_t * list,
76 unsigned int size)
78 gnutls_x509_trust_list_t tmp =
79 gnutls_calloc(1, sizeof(struct gnutls_x509_trust_list_st));
81 if (!tmp)
82 return GNUTLS_E_MEMORY_ERROR;
84 if (size == 0)
85 size = DEFAULT_SIZE;
86 tmp->size = size;
88 tmp->node = gnutls_calloc(1, tmp->size * sizeof(tmp->node[0]));
89 if (tmp->node == NULL) {
90 gnutls_assert();
91 gnutls_free(tmp);
92 return GNUTLS_E_MEMORY_ERROR;
95 *list = tmp;
97 return 0; /* success */
101 * gnutls_x509_trust_list_deinit:
102 * @list: The structure to be deinitialized
103 * @all: if non-(0) it will deinitialize all the certificates and CRLs contained in the structure.
105 * This function will deinitialize a trust list.
107 * Since: 3.0
109 void
110 gnutls_x509_trust_list_deinit(gnutls_x509_trust_list_t list,
111 unsigned int all)
113 unsigned int i, j;
115 if (!list)
116 return;
118 for (i = 0; i < list->size; i++) {
119 if (all)
120 for (j = 0; j < list->node[i].trusted_ca_size; j++) {
121 gnutls_x509_crt_deinit(list->node[i].trusted_cas[j]);
123 gnutls_free(list->node[i].trusted_cas);
125 if (all)
126 for (j = 0; j < list->node[i].crl_size; j++) {
127 gnutls_x509_crl_deinit(list->node[i].crls[j]);
129 gnutls_free(list->node[i].crls);
131 if (all)
132 for (j = 0; j < list->node[i].named_cert_size; j++) {
133 gnutls_x509_crt_deinit(list->node[i].named_certs[j].cert);
135 gnutls_free(list->node[i].named_certs);
138 gnutls_free(list->node);
139 gnutls_free(list);
143 * gnutls_x509_trust_list_add_cas:
144 * @list: The structure of the list
145 * @clist: A list of CAs
146 * @clist_size: The length of the CA list
147 * @flags: should be 0.
149 * This function will add the given certificate authorities
150 * to the trusted list. The list of CAs must not be deinitialized
151 * during this structure's lifetime.
153 * Returns: The number of added elements is returned.
155 * Since: 3.0
158 gnutls_x509_trust_list_add_cas(gnutls_x509_trust_list_t list,
159 const gnutls_x509_crt_t * clist,
160 int clist_size, unsigned int flags)
162 gnutls_datum_t dn;
163 int ret, i;
164 uint32_t hash;
166 for (i = 0; i < clist_size; i++) {
167 ret = gnutls_x509_crt_get_raw_dn(clist[i], &dn);
168 if (ret < 0) {
169 gnutls_assert();
170 return i;
173 hash = hash_pjw_bare(dn.data, dn.size);
174 hash %= list->size;
176 _gnutls_free_datum(&dn);
177 list->node[hash].trusted_cas =
178 gnutls_realloc_fast(list->node[hash].trusted_cas,
179 (list->node[hash].trusted_ca_size +
180 1) *
181 sizeof(list->node[hash].trusted_cas[0]));
182 if (list->node[hash].trusted_cas == NULL) {
183 gnutls_assert();
184 return i;
187 list->node[hash].trusted_cas[list->node[hash].trusted_ca_size] =
188 clist[i];
189 list->node[hash].trusted_ca_size++;
192 return i;
196 * gnutls_x509_trust_list_add_named_crt:
197 * @list: The structure of the list
198 * @cert: A certificate
199 * @name: An identifier for the certificate
200 * @name_size: The size of the identifier
201 * @flags: should be 0.
203 * This function will add the given certificate to the trusted
204 * list and associate it with a name. The certificate will not be
205 * be used for verification with gnutls_x509_trust_list_verify_crt()
206 * but only with gnutls_x509_trust_list_verify_named_crt().
208 * In principle this function can be used to set individual "server"
209 * certificates that are trusted by the user for that specific server
210 * but for no other purposes.
212 * The certificate must not be deinitialized during the lifetime
213 * of the trusted list.
215 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
216 * negative error value.
218 * Since: 3.0
221 gnutls_x509_trust_list_add_named_crt(gnutls_x509_trust_list_t list,
222 gnutls_x509_crt_t cert,
223 const void *name, size_t name_size,
224 unsigned int flags)
226 gnutls_datum_t dn;
227 int ret;
228 uint32_t hash;
230 if (name_size >= MAX_SERVER_NAME_SIZE)
231 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
233 ret = gnutls_x509_crt_get_raw_issuer_dn(cert, &dn);
234 if (ret < 0) {
235 gnutls_assert();
236 return ret;
239 hash = hash_pjw_bare(dn.data, dn.size);
240 hash %= list->size;
242 _gnutls_free_datum(&dn);
244 list->node[hash].named_certs =
245 gnutls_realloc_fast(list->node[hash].named_certs,
246 (list->node[hash].named_cert_size +
247 1) * sizeof(list->node[hash].named_certs[0]));
248 if (list->node[hash].named_certs == NULL)
249 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
251 list->node[hash].named_certs[list->node[hash].named_cert_size].cert =
252 cert;
253 memcpy(list->node[hash].named_certs[list->node[hash].named_cert_size].
254 name, name, name_size);
255 list->node[hash].named_certs[list->node[hash].named_cert_size].
256 name_size = name_size;
258 list->node[hash].named_cert_size++;
260 return 0;
264 * gnutls_x509_trust_list_add_crls:
265 * @list: The structure of the list
266 * @crl_list: A list of CRLs
267 * @crl_size: The length of the CRL list
268 * @flags: if GNUTLS_TL_VERIFY_CRL is given the CRLs will be verified before being added.
269 * @verification_flags: gnutls_certificate_verify_flags if flags specifies GNUTLS_TL_VERIFY_CRL
271 * This function will add the given certificate revocation lists
272 * to the trusted list. The list of CRLs must not be deinitialized
273 * during this structure's lifetime.
275 * This function must be called after gnutls_x509_trust_list_add_cas()
276 * to allow verifying the CRLs for validity.
278 * Returns: The number of added elements is returned.
280 * Since: 3.0
283 gnutls_x509_trust_list_add_crls(gnutls_x509_trust_list_t list,
284 const gnutls_x509_crl_t * crl_list,
285 int crl_size, unsigned int flags,
286 unsigned int verification_flags)
288 int ret, i, j = 0;
289 gnutls_datum_t dn;
290 unsigned int vret = 0;
291 uint32_t hash;
293 /* Probably we can optimize things such as removing duplicates
294 * etc.
297 if (crl_size == 0 || crl_list == NULL)
298 return 0;
300 for (i = 0; i < crl_size; i++) {
301 ret = gnutls_x509_crl_get_raw_issuer_dn(crl_list[i], &dn);
302 if (ret < 0) {
303 gnutls_assert();
304 return i;
307 hash = hash_pjw_bare(dn.data, dn.size);
308 hash %= list->size;
310 _gnutls_free_datum(&dn);
312 if (flags & GNUTLS_TL_VERIFY_CRL) {
314 ret =
315 gnutls_x509_crl_verify(crl_list[i],
316 list->node[hash].trusted_cas,
317 list->node[hash].trusted_ca_size,
318 verification_flags, &vret);
319 if (ret < 0 || vret != 0)
320 continue;
323 list->node[hash].crls =
324 gnutls_realloc_fast(list->node[hash].crls,
325 (list->node[hash].crl_size +
326 1) *
327 sizeof(list->node[hash].trusted_cas[0]));
328 if (list->node[hash].crls == NULL) {
329 gnutls_assert();
330 return i;
333 list->node[hash].crls[list->node[hash].crl_size] = crl_list[i];
334 list->node[hash].crl_size++;
335 j++;
338 return j;
341 /* Takes a certificate list and shortens it if there are
342 * intermedia certificates already trusted by us.
344 * FIXME: This is very similar to _gnutls_x509_verify_certificate().
346 * Returns the new size of the list or a negative number on error.
348 static int shorten_clist(gnutls_x509_trust_list_t list,
349 gnutls_x509_crt_t * certificate_list,
350 unsigned int clist_size)
352 int ret;
353 unsigned int j, i;
354 uint32_t hash;
355 gnutls_datum_t dn;
357 if (clist_size > 1) {
358 /* Check if the last certificate in the path is self signed.
359 * In that case ignore it (a certificate is trusted only if it
360 * leads to a trusted party by us, not the server's).
362 * This prevents from verifying self signed certificates against
363 * themselves. This (although not bad) caused verification
364 * failures on some root self signed certificates that use the
365 * MD2 algorithm.
367 if (gnutls_x509_crt_check_issuer(certificate_list[clist_size - 1],
368 certificate_list[clist_size -
369 1]) > 0) {
370 clist_size--;
374 /* We want to shorten the chain by removing the cert that matches
375 * one of the certs we trust and all the certs after that i.e. if
376 * cert chain is A signed-by B signed-by C signed-by D (signed-by
377 * self-signed E but already removed above), and we trust B, remove
378 * B, C and D. */
379 for (i = 1; i < clist_size; i++) {
380 ret = gnutls_x509_crt_get_raw_issuer_dn(certificate_list[i], &dn);
381 if (ret < 0) {
382 gnutls_assert();
383 return ret;
386 hash = hash_pjw_bare(dn.data, dn.size);
387 hash %= list->size;
389 _gnutls_free_datum(&dn);
391 for (j = 0; j < list->node[hash].trusted_ca_size; j++) {
392 if (check_if_same_cert
393 (certificate_list[i],
394 list->node[hash].trusted_cas[j]) == 0) {
395 /* cut the list at the point of first the trusted certificate */
396 clist_size = i + 1;
397 break;
400 /* clist_size may have been changed which gets out of loop */
403 return clist_size;
406 /* Takes a certificate list and orders it with subject, issuer order.
408 * *clist_size contains the size of the ordered list (which is always less or
409 * equal to the original).
411 * Returns the sorted list which may be the original clist.
413 static gnutls_x509_crt_t* sort_clist(gnutls_x509_crt_t sorted[DEFAULT_MAX_VERIFY_DEPTH],
414 gnutls_x509_crt_t * clist,
415 unsigned int *clist_size)
417 int prev;
418 unsigned int j, i;
419 int issuer[DEFAULT_MAX_VERIFY_DEPTH]; /* contain the index of the issuers */
421 /* Do not bother sorting if too many certificates are given.
422 * Prevent any DoS attacks.
424 if (*clist_size > DEFAULT_MAX_VERIFY_DEPTH)
425 return clist;
427 for (i=0;i<DEFAULT_MAX_VERIFY_DEPTH;i++)
428 issuer[i] = -1;
430 /* Find the issuer of each certificate and store it
431 * in issuer array.
433 for(i=0;i<*clist_size;i++)
435 for (j=1;j<*clist_size;j++)
437 if (i==j) continue;
439 if (gnutls_x509_crt_check_issuer(clist[i],
440 clist[j]))
442 issuer[i] = j;
443 break;
448 if (issuer[0] == -1)
450 *clist_size = 1;
451 return clist;
454 prev = 0;
455 sorted[0] = clist[0];
456 for (i=1;i<*clist_size;i++)
458 prev = issuer[prev];
459 if (prev == -1) /* no issuer */
461 *clist_size = i;
462 break;
464 sorted[i] = clist[prev];
467 return sorted;
471 * gnutls_x509_trust_list_get_issuer:
472 * @list: The structure of the list
473 * @cert: is the certificate to find issuer for
474 * @issuer: Will hold the issuer if any. Should be treated as constant.
475 * @flags: Use (0).
477 * This function will attempt to find the issuer of the
478 * given certificate.
480 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
481 * negative error value.
483 * Since: 3.0
485 int gnutls_x509_trust_list_get_issuer(gnutls_x509_trust_list_t list,
486 gnutls_x509_crt_t cert,
487 gnutls_x509_crt_t * issuer,
488 unsigned int flags)
490 gnutls_datum_t dn;
491 int ret;
492 unsigned int i;
493 uint32_t hash;
495 ret = gnutls_x509_crt_get_raw_issuer_dn(cert, &dn);
496 if (ret < 0) {
497 gnutls_assert();
498 return ret;
501 hash = hash_pjw_bare(dn.data, dn.size);
502 hash %= list->size;
504 _gnutls_free_datum(&dn);
506 for (i = 0; i < list->node[hash].trusted_ca_size; i++) {
507 ret =
508 gnutls_x509_crt_check_issuer(cert,
509 list->node[hash].trusted_cas[i]);
510 if (ret > 0) {
511 *issuer = list->node[hash].trusted_cas[i];
512 return 0;
516 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
520 * gnutls_x509_trust_list_verify_crt:
521 * @list: The structure of the list
522 * @cert_list: is the certificate list to be verified
523 * @cert_list_size: is the certificate list size
524 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
525 * @verify: will hold the certificate verification output.
526 * @func: If non-null will be called on each chain element verification with the output.
528 * This function will try to verify the given certificate and return
529 * its status.
531 * Limitation: Pathlen constraints or key usage flags are not consulted.
533 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
534 * negative error value.
536 * Since: 3.0
539 gnutls_x509_trust_list_verify_crt(gnutls_x509_trust_list_t list,
540 gnutls_x509_crt_t * cert_list,
541 unsigned int cert_list_size,
542 unsigned int flags,
543 unsigned int *verify,
544 gnutls_verify_output_function func)
546 gnutls_datum_t dn;
547 int ret;
548 unsigned int i;
549 uint32_t hash;
550 gnutls_x509_crt_t sorted[DEFAULT_MAX_VERIFY_DEPTH];
552 if (cert_list == NULL || cert_list_size < 1)
553 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
555 if (flags & GNUTLS_VERIFY_ALLOW_UNSORTED_CHAIN)
556 cert_list = sort_clist(sorted, cert_list, &cert_list_size);
558 cert_list_size = shorten_clist(list, cert_list, cert_list_size);
559 if (cert_list_size <= 0)
560 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
562 ret =
563 gnutls_x509_crt_get_raw_issuer_dn(cert_list[cert_list_size - 1],
564 &dn);
565 if (ret < 0) {
566 gnutls_assert();
567 return ret;
570 hash = hash_pjw_bare(dn.data, dn.size);
571 hash %= list->size;
573 _gnutls_free_datum(&dn);
575 *verify = _gnutls_x509_verify_certificate(cert_list, cert_list_size,
576 list->node[hash].trusted_cas,
577 list->node[hash].
578 trusted_ca_size, flags,
579 func);
581 if (*verify != 0 || (flags & GNUTLS_VERIFY_DISABLE_CRL_CHECKS))
582 return 0;
584 /* Check revocation of individual certificates.
585 * start with the last one that we already have its hash
587 ret = _gnutls_x509_crt_check_revocation(cert_list[cert_list_size - 1],
588 list->node[hash].crls,
589 list->node[hash].crl_size,
590 func);
591 if (ret == 1) { /* revoked */
592 *verify |= GNUTLS_CERT_REVOKED;
593 *verify |= GNUTLS_CERT_INVALID;
594 return 0;
597 for (i = 0; i < cert_list_size - 1; i++) {
598 ret = gnutls_x509_crt_get_raw_issuer_dn(cert_list[i], &dn);
599 if (ret < 0) {
600 gnutls_assert();
601 return ret;
604 hash = hash_pjw_bare(dn.data, dn.size);
605 hash %= list->size;
607 _gnutls_free_datum(&dn);
609 ret = _gnutls_x509_crt_check_revocation(cert_list[i],
610 list->node[hash].crls,
611 list->node[hash].crl_size,
612 func);
613 if (ret == 1) { /* revoked */
614 *verify |= GNUTLS_CERT_REVOKED;
615 *verify |= GNUTLS_CERT_INVALID;
616 return 0;
620 return 0;
624 * gnutls_x509_trust_list_verify_named_crt:
625 * @list: The structure of the list
626 * @cert: is the certificate to be verified
627 * @name: is the certificate's name
628 * @name_size: is the certificate's name size
629 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
630 * @verify: will hold the certificate verification output.
631 * @func: If non-null will be called on each chain element verification with the output.
633 * This function will try to find a matching named certificate. If a
634 * match is found the certificate is considered valid. In addition to that
635 * this function will also check CRLs.
637 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
638 * negative error value.
640 * Since: 3.0
643 gnutls_x509_trust_list_verify_named_crt(gnutls_x509_trust_list_t list,
644 gnutls_x509_crt_t cert,
645 const void *name,
646 size_t name_size,
647 unsigned int flags,
648 unsigned int *verify,
649 gnutls_verify_output_function func)
651 gnutls_datum_t dn;
652 int ret;
653 unsigned int i;
654 uint32_t hash;
656 ret = gnutls_x509_crt_get_raw_issuer_dn(cert, &dn);
657 if (ret < 0) {
658 gnutls_assert();
659 return ret;
662 hash = hash_pjw_bare(dn.data, dn.size);
663 hash %= list->size;
665 _gnutls_free_datum(&dn);
667 *verify = GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNER_NOT_FOUND;
669 for (i = 0; i < list->node[hash].named_cert_size; i++) {
670 if (check_if_same_cert(cert, list->node[hash].named_certs[i].cert) == 0) { /* check if name matches */
671 if (list->node[hash].named_certs[i].name_size == name_size &&
672 memcmp(list->node[hash].named_certs[i].name, name,
673 name_size) == 0) {
674 *verify = 0;
675 break;
680 if (*verify != 0 || (flags & GNUTLS_VERIFY_DISABLE_CRL_CHECKS))
681 return 0;
683 /* Check revocation of individual certificates.
684 * start with the last one that we already have its hash
686 ret = _gnutls_x509_crt_check_revocation(cert,
687 list->node[hash].crls,
688 list->node[hash].crl_size,
689 func);
690 if (ret == 1) { /* revoked */
691 *verify |= GNUTLS_CERT_REVOKED;
692 *verify |= GNUTLS_CERT_INVALID;
693 return 0;
696 return 0;
699 /* return 0 if @cert is in @list, 1 if not, or < 0 on error. */
701 _gnutls_trustlist_inlist (gnutls_x509_trust_list_t list,
702 gnutls_x509_crt_t cert)
704 gnutls_datum_t dn;
705 int ret;
706 unsigned int i;
707 uint32_t hash;
709 ret = gnutls_x509_crt_get_raw_dn (cert, &dn);
710 if (ret < 0)
712 gnutls_assert();
713 return ret;
716 hash = hash_pjw_bare(dn.data, dn.size);
717 hash %= list->size;
719 _gnutls_free_datum (&dn);
721 for (i = 0; i < list->node[hash].trusted_ca_size; i++)
723 ret = check_if_same_cert (cert, list->node[hash].trusted_cas[i]);
724 if (ret < 0)
726 gnutls_assert ();
727 return ret;
730 if (ret == 0)
731 return 0;
734 return 1;