LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib/x509 - verify-high.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 518 621 83.4 %
Date: 2020-10-30 04:50:48 Functions: 23 23 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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
      83        8282 : gnutls_x509_trust_list_init(gnutls_x509_trust_list_t * list,
      84             :                             unsigned int size)
      85             : {
      86        8282 :         gnutls_x509_trust_list_t tmp;
      87             : 
      88        8282 :         FAIL_IF_LIB_ERROR;
      89             : 
      90        8282 :         tmp =
      91        8282 :             gnutls_calloc(1, sizeof(struct gnutls_x509_trust_list_st));
      92             : 
      93        8282 :         if (!tmp)
      94             :                 return GNUTLS_E_MEMORY_ERROR;
      95             : 
      96        8282 :         if (size == 0)
      97        8282 :                 size = DEFAULT_SIZE;
      98        8282 :         tmp->size = size;
      99             : 
     100        8282 :         tmp->node = gnutls_calloc(1, tmp->size * sizeof(tmp->node[0]));
     101        8282 :         if (tmp->node == NULL) {
     102           0 :                 gnutls_assert();
     103           0 :                 gnutls_free(tmp);
     104           0 :                 return GNUTLS_E_MEMORY_ERROR;
     105             :         }
     106             : 
     107        8282 :         *list = tmp;
     108             : 
     109        8282 :         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
     125        7859 : gnutls_x509_trust_list_deinit(gnutls_x509_trust_list_t list,
     126             :                               unsigned int all)
     127             : {
     128        7859 :         unsigned int i, j;
     129             : 
     130        7859 :         if (!list)
     131             :                 return;
     132             : 
     133        7862 :         for (j = 0; j < list->blacklisted_size; j++) {
     134           3 :                 gnutls_x509_crt_deinit(list->blacklisted[j]);
     135             :         }
     136        7859 :         gnutls_free(list->blacklisted);
     137             : 
     138        7861 :         for (j = 0; j < list->keep_certs_size; j++) {
     139           2 :                 gnutls_x509_crt_deinit(list->keep_certs[j]);
     140             :         }
     141        7859 :         gnutls_free(list->keep_certs);
     142             : 
     143     1005950 :         for (i = 0; i < list->size; i++) {
     144      998093 :                 if (all) {
     145      963229 :                         for (j = 0; j < list->node[i].trusted_ca_size; j++) {
     146        3363 :                                 gnutls_x509_crt_deinit(list->node[i].
     147        3363 :                                                        trusted_cas[j]);
     148             :                         }
     149             :                 }
     150      998093 :                 gnutls_free(list->node[i].trusted_cas);
     151             : 
     152             : 
     153      998093 :                 if (all) {
     154      960068 :                         for (j = 0; j < list->node[i].crl_size; j++) {
     155         202 :                                 gnutls_x509_crl_deinit(list->node[i].
     156         202 :                                                        crls[j]);
     157             :                         }
     158             :                 }
     159      998093 :                 gnutls_free(list->node[i].crls);
     160             : 
     161      998093 :                 if (all) {
     162      959867 :                         for (j = 0; j < list->node[i].named_cert_size; j++) {
     163           1 :                                 gnutls_x509_crt_deinit(list->node[i].
     164           1 :                                                        named_certs[j].
     165             :                                                        cert);
     166             :                         }
     167             :                 }
     168      998093 :                 gnutls_free(list->node[i].named_certs);
     169             :         }
     170             : 
     171        7859 :         gnutls_free(list->x509_rdn_sequence.data);
     172        7859 :         gnutls_free(list->node);
     173        7859 :         gnutls_free(list->pkcs11_token);
     174        7859 :         gnutls_free(list);
     175             : }
     176             : 
     177             : static int
     178        4102 : add_new_ca_to_rdn_seq(gnutls_x509_trust_list_t list,
     179             :                        gnutls_x509_crt_t ca)
     180             : {
     181        4102 :         gnutls_datum_t tmp;
     182        4102 :         size_t newsize;
     183        4102 :         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        4102 :         tmp.data = ca->raw_dn.data;
     190        4102 :         tmp.size = ca->raw_dn.size;
     191             : 
     192        4102 :         newsize = list->x509_rdn_sequence.size + 2 + tmp.size;
     193        4102 :         if (newsize < list->x509_rdn_sequence.size) {
     194           0 :                 gnutls_assert();
     195           0 :                 return GNUTLS_E_SHORT_MEMORY_BUFFER;
     196             :         }
     197             : 
     198        4102 :         newdata =
     199        4102 :             gnutls_realloc_fast(list->x509_rdn_sequence.data,
     200             :                                 newsize);
     201        4102 :         if (newdata == NULL) {
     202           0 :                 gnutls_assert();
     203           0 :                 return GNUTLS_E_MEMORY_ERROR;
     204             :         }
     205             : 
     206        4102 :         p = newdata + list->x509_rdn_sequence.size;
     207        4102 :         _gnutls_write_uint16(tmp.size, p);
     208        4102 :         if (tmp.data != NULL)
     209        4102 :                 memcpy(p + 2, tmp.data, tmp.size);
     210             : 
     211        4102 :         list->x509_rdn_sequence.size = newsize;
     212        4102 :         list->x509_rdn_sequence.data = newdata;
     213             : 
     214        4102 :         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
     223           2 : trust_list_add_compat(gnutls_x509_trust_list_t list,
     224             :                                gnutls_x509_crt_t cert)
     225             : {
     226           4 :         list->keep_certs =
     227           2 :                     gnutls_realloc_fast(list->keep_certs,
     228           2 :                                         (list->keep_certs_size +
     229             :                                          1) *
     230             :                                         sizeof(list->keep_certs[0]));
     231           2 :         if (list->keep_certs == NULL) {
     232           0 :                 gnutls_assert();
     233           0 :                 return GNUTLS_E_MEMORY_ERROR;
     234             :         }
     235             : 
     236           2 :         list->keep_certs[list->keep_certs_size] = cert;
     237           2 :         list->keep_certs_size++;
     238             : 
     239           2 :         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
     272        1037 : 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        1037 :         unsigned i, j;
     277        1037 :         size_t hash;
     278        1037 :         int ret;
     279        1037 :         unsigned exists;
     280             : 
     281        7356 :         for (i = 0; i < clist_size; i++) {
     282        6319 :                 exists = 0;
     283        6319 :                 hash =
     284        6319 :                     hash_pjw_bare(clist[i]->raw_dn.data,
     285        6319 :                                   clist[i]->raw_dn.size);
     286        6319 :                 hash %= list->size;
     287             : 
     288             :                 /* avoid duplicates */
     289        6319 :                 if (flags & GNUTLS_TL_NO_DUPLICATES || flags & GNUTLS_TL_NO_DUPLICATE_KEY) {
     290        8165 :                         for (j=0;j<list->node[hash].trusted_ca_size;j++) {
     291        4014 :                                 if (flags & GNUTLS_TL_NO_DUPLICATES)
     292        4014 :                                         ret = gnutls_x509_crt_equals(list->node[hash].trusted_cas[j], clist[i]);
     293             :                                 else
     294           0 :                                         ret = _gnutls_check_if_same_key(list->node[hash].trusted_cas[j], clist[i], 1);
     295        4014 :                                 if (ret != 0) {
     296             :                                         exists = 1;
     297             :                                         break;
     298             :                                 }
     299             :                         }
     300             : 
     301        6104 :                         if (exists != 0) {
     302        1953 :                                 gnutls_x509_crt_deinit(list->node[hash].trusted_cas[j]);
     303        1953 :                                 list->node[hash].trusted_cas[j] = clist[i];
     304        1953 :                                 continue;
     305             :                         }
     306             :                 }
     307             : 
     308        8732 :                 list->node[hash].trusted_cas =
     309        4366 :                     gnutls_realloc_fast(list->node[hash].trusted_cas,
     310        4366 :                                         (list->node[hash].trusted_ca_size +
     311             :                                          1) *
     312             :                                         sizeof(list->node[hash].
     313             :                                                trusted_cas[0]));
     314        4366 :                 if (list->node[hash].trusted_cas == NULL) {
     315           0 :                         gnutls_assert();
     316           0 :                         return i;
     317             :                 }
     318             : 
     319        8638 :                 if (gnutls_x509_crt_get_version(clist[i]) >= 3 &&
     320        4272 :                     gnutls_x509_crt_get_ca_status(clist[i], NULL) <= 0) {
     321         118 :                         gnutls_datum_t dn;
     322         118 :                         gnutls_assert();
     323         118 :                         if (gnutls_x509_crt_get_dn2(clist[i], &dn) >= 0) {
     324         117 :                                 _gnutls_audit_log(NULL,
     325             :                                           "There was a non-CA certificate in the trusted list: %s.\n",
     326             :                                           dn.data);
     327         117 :                                 gnutls_free(dn.data);
     328             :                         }
     329             :                 }
     330             : 
     331        4366 :                 list->node[hash].trusted_cas[list->node[hash].
     332        4366 :                                              trusted_ca_size] = clist[i];
     333        4366 :                 list->node[hash].trusted_ca_size++;
     334             : 
     335        4366 :                 if (flags & GNUTLS_TL_USE_IN_TLS) {
     336        4102 :                         ret = add_new_ca_to_rdn_seq(list, clist[i]);
     337        4102 :                         if (ret < 0) {
     338           0 :                                 gnutls_assert();
     339           0 :                                 return i+1;
     340             :                         }
     341             :                 }
     342             :         }
     343             : 
     344        1037 :         return i;
     345             : }
     346             : 
     347             : static int
     348         174 : advance_iter(gnutls_x509_trust_list_t list,
     349             :              gnutls_x509_trust_list_iter_t iter)
     350             : {
     351         174 :         if (iter->node_index < list->size) {
     352          88 :                 ++iter->ca_index;
     353             : 
     354             :                 /* skip entries */
     355       11137 :                 while (iter->node_index < list->size &&
     356       11050 :                        iter->ca_index >= list->node[iter->node_index].trusted_ca_size) {
     357       11049 :                         ++iter->node_index;
     358       11049 :                         iter->ca_index = 0;
     359             :                 }
     360             : 
     361          88 :                 if (iter->node_index < list->size)
     362             :                         return 0;
     363             :         }
     364             : 
     365             : #ifdef ENABLE_PKCS11
     366         173 :         if (list->pkcs11_token != NULL) {
     367         172 :                 if (iter->pkcs11_list == NULL) {
     368          86 :                         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          86 :                         if (ret < 0)
     371           0 :                                 return gnutls_assert_val(ret);
     372             : 
     373          86 :                         if (iter->pkcs11_size > 0)
     374             :                                 return 0;
     375          86 :                 } else if (iter->pkcs11_index < iter->pkcs11_size) {
     376          86 :                         ++iter->pkcs11_index;
     377          86 :                         if (iter->pkcs11_index < iter->pkcs11_size)
     378             :                                 return 0;
     379             :                 }
     380             :         }
     381             : #endif
     382             : 
     383          87 :         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
     411         174 : 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         174 :         int ret;
     416             : 
     417             :         /* initialize iterator */
     418         174 :         if (*iter == NULL) {
     419          87 :                 *iter = gnutls_malloc(sizeof (struct gnutls_x509_trust_list_iter));
     420          87 :                 if (*iter == NULL)
     421           0 :                         return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
     422             : 
     423          87 :                 (*iter)->node_index = 0;
     424          87 :                 (*iter)->ca_index = 0;
     425             : 
     426             : #ifdef ENABLE_PKCS11
     427          87 :                 (*iter)->pkcs11_list = NULL;
     428          87 :                 (*iter)->pkcs11_size = 0;
     429          87 :                 (*iter)->pkcs11_index = 0;
     430             : #endif
     431             : 
     432             :                 /* Advance iterator to the first valid entry */
     433          87 :                 if (list->node[0].trusted_ca_size == 0) {
     434          87 :                         ret = advance_iter(list, *iter);
     435          87 :                         if (ret != 0) {
     436           0 :                                 gnutls_x509_trust_list_iter_deinit(*iter);
     437           0 :                                 *iter = NULL;
     438             : 
     439           0 :                                 *crt = NULL;
     440           0 :                                 return gnutls_assert_val(ret);
     441             :                         }
     442             :                 }
     443             :         }
     444             : 
     445             :         /* obtain the certificate at the current iterator position */
     446         174 :         if ((*iter)->node_index < list->size) {
     447           1 :                 ret = gnutls_x509_crt_init(crt);
     448           1 :                 if (ret < 0)
     449           0 :                         return gnutls_assert_val(ret);
     450             : 
     451           1 :                 ret = _gnutls_x509_crt_cpy(*crt, list->node[(*iter)->node_index].trusted_cas[(*iter)->ca_index]);
     452           1 :                 if (ret < 0) {
     453           0 :                         gnutls_x509_crt_deinit(*crt);
     454           0 :                         return gnutls_assert_val(ret);
     455             :                 }
     456             :         }
     457             : #ifdef ENABLE_PKCS11
     458         173 :         else if ( (*iter)->pkcs11_index < (*iter)->pkcs11_size) {
     459          86 :                 ret = gnutls_x509_crt_init(crt);
     460          86 :                 if (ret < 0)
     461           0 :                         return gnutls_assert_val(ret);
     462             : 
     463          86 :                 ret = gnutls_x509_crt_import_pkcs11(*crt, (*iter)->pkcs11_list[(*iter)->pkcs11_index]);
     464          86 :                 if (ret < 0) {
     465           0 :                         gnutls_x509_crt_deinit(*crt);
     466           0 :                         return gnutls_assert_val(ret);
     467             :                 }
     468             :         }
     469             : #endif
     470             : 
     471             :         else {
     472             :                 /* iterator is at end */
     473          87 :                 gnutls_x509_trust_list_iter_deinit(*iter);
     474          87 :                 *iter = NULL;
     475             : 
     476          87 :                 *crt = NULL;
     477          87 :                 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          87 :         ret = advance_iter(list, *iter);
     486          87 :         if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
     487           0 :                 gnutls_x509_crt_deinit(*crt);
     488           0 :                 *crt = NULL;
     489             : 
     490           0 :                 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             :  **/
     504          87 : void gnutls_x509_trust_list_iter_deinit(gnutls_x509_trust_list_iter_t iter)
     505             : {
     506          87 :         if (!iter)
     507             :                 return;
     508             : 
     509             : #ifdef ENABLE_PKCS11
     510          87 :         if (iter->pkcs11_size > 0) {
     511             :                 unsigned i;
     512         172 :                 for (i = 0; i < iter->pkcs11_size; ++i)
     513          86 :                         gnutls_pkcs11_obj_deinit(iter->pkcs11_list[i]);
     514          86 :                 gnutls_free(iter->pkcs11_list);
     515             :         }
     516             : #endif
     517             : 
     518          87 :         gnutls_free(iter);
     519             : }
     520             : 
     521          35 : static gnutls_x509_crt_t crt_cpy(gnutls_x509_crt_t src)
     522             : {
     523          35 : gnutls_x509_crt_t dst;
     524          35 : int ret;
     525             : 
     526          35 :         ret = gnutls_x509_crt_init(&dst);
     527          35 :         if (ret < 0) {
     528           0 :                 gnutls_assert();
     529           0 :                 return NULL;
     530             :         }
     531             : 
     532          35 :         ret = _gnutls_x509_crt_cpy(dst, src);
     533          35 :         if (ret < 0) {
     534           0 :                 gnutls_x509_crt_deinit(dst);
     535           0 :                 gnutls_assert();
     536           0 :                 return NULL;
     537             :         }
     538             : 
     539          35 :         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
     562           3 : 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           3 :         int r = 0;
     567           3 :         unsigned j, i;
     568           3 :         size_t hash;
     569             : 
     570           6 :         for (i = 0; i < clist_size; i++) {
     571           3 :                 hash =
     572           3 :                     hash_pjw_bare(clist[i]->raw_dn.data,
     573           3 :                                   clist[i]->raw_dn.size);
     574           3 :                 hash %= list->size;
     575             : 
     576           3 :                 for (j = 0; j < list->node[hash].trusted_ca_size; j++) {
     577           3 :                         if (gnutls_x509_crt_equals
     578             :                             (clist[i],
     579           3 :                              list->node[hash].trusted_cas[j]) != 0) {
     580             : 
     581           3 :                                 gnutls_x509_crt_deinit(list->node[hash].
     582           3 :                                                        trusted_cas[j]);
     583           3 :                                 list->node[hash].trusted_cas[j] =
     584           3 :                                     list->node[hash].trusted_cas[list->
     585             :                                                                  node
     586           3 :                                                                  [hash].
     587             :                                                                  trusted_ca_size
     588           3 :                                                                  - 1];
     589           3 :                                 list->node[hash].trusted_ca_size--;
     590           3 :                                 r++;
     591           3 :                                 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           6 :                 list->blacklisted =
     600           3 :                     gnutls_realloc_fast(list->blacklisted,
     601           3 :                                 (list->blacklisted_size + 1) *
     602             :                                 sizeof(list->blacklisted[0]));
     603           3 :                 if (list->blacklisted == NULL)
     604           0 :                         return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
     605             : 
     606           3 :                 list->blacklisted[list->blacklisted_size] = crt_cpy(clist[i]);
     607           3 :                 if (list->blacklisted[list->blacklisted_size] != NULL)
     608           3 :                         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
     642           1 : 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           1 :         size_t hash;
     648             : 
     649           1 :         if (name_size >= MAX_SERVER_NAME_SIZE)
     650           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     651             : 
     652           1 :         hash =
     653           1 :             hash_pjw_bare(cert->raw_issuer_dn.data,
     654           1 :                           cert->raw_issuer_dn.size);
     655           1 :         hash %= list->size;
     656             : 
     657           2 :         list->node[hash].named_certs =
     658           1 :             gnutls_realloc_fast(list->node[hash].named_certs,
     659           1 :                                 (list->node[hash].named_cert_size +
     660             :                                  1) *
     661             :                                 sizeof(list->node[hash].named_certs[0]));
     662           1 :         if (list->node[hash].named_certs == NULL)
     663           0 :                 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
     664             : 
     665           1 :         list->node[hash].named_certs[list->node[hash].named_cert_size].
     666           1 :             cert = cert;
     667           1 :         memcpy(list->node[hash].
     668           1 :                named_certs[list->node[hash].named_cert_size].name, name,
     669             :                name_size);
     670           1 :         list->node[hash].named_certs[list->node[hash].
     671           1 :                                      named_cert_size].name_size =
     672             :             name_size;
     673             : 
     674           1 :         list->node[hash].named_cert_size++;
     675             : 
     676           1 :         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
     707          84 : 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          84 :         int ret;
     713          84 :         unsigned x, i, j = 0;
     714          84 :         unsigned int vret = 0;
     715          84 :         size_t hash;
     716          84 :         gnutls_x509_crl_t *tmp;
     717             : 
     718             :         /* Probably we can optimize things such as removing duplicates
     719             :          * etc.
     720             :          */
     721          84 :         if (crl_size == 0 || crl_list == NULL)
     722             :                 return 0;
     723             : 
     724         290 :         for (i = 0; i < crl_size; i++) {
     725         207 :                 hash =
     726         207 :                     hash_pjw_bare(crl_list[i]->raw_issuer_dn.data,
     727         207 :                                   crl_list[i]->raw_issuer_dn.size);
     728         207 :                 hash %= list->size;
     729             : 
     730         207 :                 if (flags & GNUTLS_TL_VERIFY_CRL) {
     731             : 
     732           5 :                         ret =
     733          10 :                             gnutls_x509_crl_verify(crl_list[i],
     734           5 :                                                    list->node[hash].
     735             :                                                    trusted_cas,
     736           5 :                                                    list->node[hash].
     737             :                                                    trusted_ca_size,
     738             :                                                    verification_flags,
     739             :                                                    &vret);
     740           5 :                         if (ret < 0 || vret != 0) {
     741           4 :                                 _gnutls_debug_log("CRL verification failed, not adding it\n");
     742           4 :                                 if (flags & GNUTLS_TL_NO_DUPLICATES)
     743           1 :                                         gnutls_x509_crl_deinit(crl_list[i]);
     744           4 :                                 if (flags & GNUTLS_TL_FAIL_ON_INVALID_CRL)
     745           1 :                                         return gnutls_assert_val(GNUTLS_E_CRL_VERIFICATION_ERROR);
     746           3 :                                 continue;
     747             :                         }
     748             :                 }
     749             : 
     750             :                 /* If the CRL added overrides a previous one, then overwrite
     751             :                  * the old one */
     752         203 :                 if (flags & GNUTLS_TL_NO_DUPLICATES) {
     753           2 :                         for (x=0;x<list->node[hash].crl_size;x++) {
     754           0 :                                 if (crl_list[i]->raw_issuer_dn.size == list->node[hash].crls[x]->raw_issuer_dn.size &&
     755           0 :                                     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           0 :                                         if (gnutls_x509_crl_get_this_update(crl_list[i]) >=
     757           0 :                                             gnutls_x509_crl_get_this_update(list->node[hash].crls[x])) {
     758             : 
     759           0 :                                                 gnutls_x509_crl_deinit(list->node[hash].crls[x]);
     760           0 :                                                 list->node[hash].crls[x] = crl_list[i];
     761           0 :                                                 goto next;
     762             :                                         } else {
     763             :                                                 /* The new is older, discard it */
     764           0 :                                                 gnutls_x509_crl_deinit(crl_list[i]);
     765           0 :                                                 goto next;
     766             :                                         }
     767             :                                 }
     768             :                         }
     769             :                 }
     770             : 
     771         203 :                 tmp =
     772         406 :                     gnutls_realloc(list->node[hash].crls,
     773         203 :                                         (list->node[hash].crl_size +
     774             :                                          1) *
     775             :                                         sizeof(list->node[hash].
     776             :                                                crls[0]));
     777         203 :                 if (tmp == NULL) {
     778           0 :                         ret = i;
     779           0 :                         gnutls_assert();
     780           0 :                         if (flags & GNUTLS_TL_NO_DUPLICATES)
     781           0 :                                 while (i < crl_size)
     782           0 :                                         gnutls_x509_crl_deinit(crl_list[i++]);
     783           0 :                         return ret;
     784             :                 }
     785         203 :                 list->node[hash].crls = tmp;
     786             : 
     787             : 
     788         203 :                 list->node[hash].crls[list->node[hash].crl_size] =
     789         203 :                     crl_list[i];
     790         203 :                 list->node[hash].crl_size++;
     791             : 
     792         203 :  next:
     793         203 :                 j++;
     794             :         }
     795             : 
     796          83 :         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             :  */
     804         795 : static int shorten_clist(gnutls_x509_trust_list_t list,
     805             :                          gnutls_x509_crt_t * certificate_list,
     806             :                          unsigned int clist_size)
     807             : {
     808         795 :         unsigned int j, i;
     809         795 :         size_t hash;
     810             : 
     811         795 :         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         501 :                 if (gnutls_x509_crt_check_issuer
     822             :                     (certificate_list[clist_size - 1],
     823         501 :                      certificate_list[clist_size - 1]) != 0) {
     824         281 :                         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        1250 :         for (i = 1; i < clist_size; i++) {
     834         455 :                 hash =
     835         455 :                     hash_pjw_bare(certificate_list[i]->raw_issuer_dn.data,
     836         455 :                                   certificate_list[i]->raw_issuer_dn.size);
     837         455 :                 hash %= list->size;
     838             : 
     839         752 :                 for (j = 0; j < list->node[hash].trusted_ca_size; j++) {
     840         298 :                         if (gnutls_x509_crt_equals
     841             :                             (certificate_list[i],
     842         298 :                              list->node[hash].trusted_cas[j]) != 0) {
     843             :                                 /* cut the list at the point of first the trusted certificate */
     844           1 :                                 clist_size = i + 1;
     845           1 :                                 break;
     846             :                         }
     847             :                 }
     848             :                 /* clist_size may have been changed which gets out of loop */
     849             :         }
     850             : 
     851         795 :         return clist_size;
     852             : }
     853             : 
     854          13 : int _gnutls_trust_list_get_issuer(gnutls_x509_trust_list_t list,
     855             :                                   gnutls_x509_crt_t cert,
     856             :                                   gnutls_x509_crt_t * issuer,
     857             :                                   unsigned int flags)
     858             : {
     859          13 :         int ret;
     860          13 :         unsigned int i;
     861          13 :         size_t hash;
     862             : 
     863          13 :         hash =
     864          13 :             hash_pjw_bare(cert->raw_issuer_dn.data,
     865          13 :                           cert->raw_issuer_dn.size);
     866          13 :         hash %= list->size;
     867             : 
     868          13 :         for (i = 0; i < list->node[hash].trusted_ca_size; i++) {
     869          18 :                 ret =
     870           9 :                     gnutls_x509_crt_check_issuer(cert,
     871           9 :                                                  list->node[hash].
     872           9 :                                                  trusted_cas[i]);
     873           9 :                 if (ret != 0) {
     874           9 :                         if (flags & GNUTLS_TL_GET_COPY) {
     875           3 :                                 *issuer = crt_cpy(list->node[hash].trusted_cas[i]);
     876             :                         } else {
     877           6 :                                 *issuer = list->node[hash].trusted_cas[i];
     878             :                         }
     879           9 :                         return 0;
     880             :                 }
     881             :         }
     882             : 
     883             :         return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
     884             : }
     885             : 
     886             : static
     887          42 : int trust_list_get_issuer_by_dn(gnutls_x509_trust_list_t list,
     888             :                                       const gnutls_datum_t *dn,
     889             :                                       const gnutls_datum_t *spki,
     890             :                                       gnutls_x509_crt_t * issuer,
     891             :                                       unsigned int flags)
     892             : {
     893          42 :         int ret;
     894          42 :         unsigned int i, j;
     895          42 :         size_t hash;
     896          42 :         uint8_t tmp[256];
     897          42 :         size_t tmp_size;
     898             : 
     899          42 :         if (dn) {
     900          38 :                 hash =
     901          38 :                     hash_pjw_bare(dn->data,
     902          38 :                                   dn->size);
     903          38 :                 hash %= list->size;
     904             : 
     905          38 :                 for (i = 0; i < list->node[hash].trusted_ca_size; i++) {
     906          29 :                         ret = _gnutls_x509_compare_raw_dn(dn, &list->node[hash].trusted_cas[i]->raw_dn);
     907          29 :                         if (ret != 0) {
     908          29 :                                 if (spki && spki->size > 0) {
     909           0 :                                         tmp_size = sizeof(tmp);
     910             : 
     911           0 :                                         ret = gnutls_x509_crt_get_subject_key_id(list->node[hash].trusted_cas[i], tmp, &tmp_size, NULL);
     912           0 :                                         if (ret < 0)
     913           0 :                                                 continue;
     914           0 :                                         if (spki->size != tmp_size || memcmp(spki->data, tmp, spki->size) != 0)
     915           0 :                                                 continue;
     916             :                                 }
     917          29 :                                 *issuer = crt_cpy(list->node[hash].trusted_cas[i]);
     918          29 :                                 return 0;
     919             :                         }
     920             :                 }
     921           4 :         } else if (spki) {
     922             :                 /* search everything! */
     923         512 :                 for (i = 0; i < list->size; i++) {
     924         512 :                         for (j = 0; j < list->node[i].trusted_ca_size; j++) {
     925           4 :                                 tmp_size = sizeof(tmp);
     926             : 
     927           4 :                                 ret = gnutls_x509_crt_get_subject_key_id(list->node[i].trusted_cas[j], tmp, &tmp_size, NULL);
     928           4 :                                 if (ret < 0)
     929           0 :                                         continue;
     930             : 
     931           4 :                                 if (spki->size != tmp_size || memcmp(spki->data, tmp, spki->size) != 0)
     932           4 :                                         continue;
     933             : 
     934           0 :                                 *issuer = crt_cpy(list->node[i].trusted_cas[j]);
     935           0 :                                 return 0;
     936             :                         }
     937             :                 }
     938             :         }
     939             : 
     940             :         return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
     941             : }
     942             : 
     943             : /**
     944             :  * gnutls_x509_trust_list_get_issuer:
     945             :  * @list: The list
     946             :  * @cert: is the certificate to find issuer for
     947             :  * @issuer: Will hold the issuer if any. Should be treated as constant.
     948             :  * @flags: flags from %gnutls_trust_list_flags_t (%GNUTLS_TL_GET_COPY is applicable)
     949             :  *
     950             :  * This function will find the issuer of the given certificate.
     951             :  * If the flag %GNUTLS_TL_GET_COPY is specified a copy of the issuer
     952             :  * will be returned which must be freed using gnutls_x509_crt_deinit().
     953             :  * In that case the provided @issuer must not be initialized.
     954             :  *
     955             :  * Note that the flag %GNUTLS_TL_GET_COPY is required for this function
     956             :  * to work with PKCS#11 trust lists in a thread-safe way.
     957             :  *
     958             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
     959             :  *   negative error value.
     960             :  *
     961             :  * Since: 3.0
     962             :  **/
     963          11 : int gnutls_x509_trust_list_get_issuer(gnutls_x509_trust_list_t list,
     964             :                                       gnutls_x509_crt_t cert,
     965             :                                       gnutls_x509_crt_t * issuer,
     966             :                                       unsigned int flags)
     967             : {
     968          11 :         int ret;
     969             : 
     970          11 :         ret = _gnutls_trust_list_get_issuer(list, cert, issuer, flags);
     971          11 :         if (ret == 0) {
     972             :                 return 0;
     973             :         }
     974             : 
     975             : #ifdef ENABLE_PKCS11
     976           4 :         if (ret < 0 && list->pkcs11_token) {
     977           4 :                 gnutls_x509_crt_t crt;
     978           4 :                 gnutls_datum_t der = {NULL, 0};
     979             :                 /* use the token for verification */
     980           4 :                 ret = gnutls_pkcs11_get_raw_issuer(list->pkcs11_token, cert, &der,
     981             :                         GNUTLS_X509_FMT_DER, GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE);
     982           4 :                 if (ret < 0) {
     983           0 :                         gnutls_assert();
     984           0 :                         return ret;
     985             :                 }
     986             : 
     987           4 :                 ret = gnutls_x509_crt_init(&crt);
     988           4 :                 if (ret < 0) {
     989           0 :                         gnutls_free(der.data);
     990           0 :                         return gnutls_assert_val(ret);
     991             :                 }
     992             : 
     993           4 :                 ret = gnutls_x509_crt_import(crt, &der, GNUTLS_X509_FMT_DER);
     994           4 :                 gnutls_free(der.data);
     995           4 :                 if (ret < 0) {
     996           0 :                         gnutls_x509_crt_deinit(crt);
     997           0 :                         return gnutls_assert_val(ret);
     998             :                 }
     999             : 
    1000           4 :                 if (flags & GNUTLS_TL_GET_COPY) {
    1001           2 :                         *issuer = crt;
    1002           2 :                         return 0;
    1003             :                 } else {
    1004             :                         /* we add this CA to the keep_cert list in order to make it
    1005             :                          * persistent. It will be deallocated when the trust list is.
    1006             :                          */
    1007           2 :                         ret = trust_list_add_compat(list, crt);
    1008           2 :                         if (ret < 0) {
    1009           0 :                                 gnutls_x509_crt_deinit(crt);
    1010           0 :                                 return gnutls_assert_val(ret);
    1011             :                         }
    1012           2 :                         *issuer = crt;
    1013           2 :                         return ret;
    1014             :                 }
    1015             :         }
    1016             : #endif
    1017             :         return ret;
    1018             : }
    1019             : 
    1020             : /**
    1021             :  * gnutls_x509_trust_list_get_issuer_by_dn:
    1022             :  * @list: The list
    1023             :  * @dn: is the issuer's DN
    1024             :  * @issuer: Will hold the issuer if any. Should be deallocated after use.
    1025             :  * @flags: Use zero
    1026             :  *
    1027             :  * This function will find the issuer with the given name, and
    1028             :  * return a copy of the issuer, which must be freed using gnutls_x509_crt_deinit().
    1029             :  *
    1030             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
    1031             :  *   negative error value.
    1032             :  *
    1033             :  * Since: 3.4.0
    1034             :  **/
    1035          38 : int gnutls_x509_trust_list_get_issuer_by_dn(gnutls_x509_trust_list_t list,
    1036             :                                       const gnutls_datum_t *dn,
    1037             :                                       gnutls_x509_crt_t *issuer,
    1038             :                                       unsigned int flags)
    1039             : {
    1040          38 :         int ret;
    1041             : 
    1042          38 :         ret = trust_list_get_issuer_by_dn(list, dn, NULL, issuer, flags);
    1043          38 :         if (ret == 0) {
    1044             :                 return 0;
    1045             :         }
    1046             : 
    1047             : #ifdef ENABLE_PKCS11
    1048           9 :         if (ret < 0 && list->pkcs11_token) {
    1049           1 :                 gnutls_x509_crt_t crt;
    1050           1 :                 gnutls_datum_t der = {NULL, 0};
    1051             :                 /* use the token for verification */
    1052           1 :                 ret = gnutls_pkcs11_get_raw_issuer_by_dn(list->pkcs11_token, dn, &der,
    1053             :                         GNUTLS_X509_FMT_DER, GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE);
    1054           1 :                 if (ret < 0) {
    1055           0 :                         gnutls_assert();
    1056           0 :                         return ret;
    1057             :                 }
    1058             : 
    1059           1 :                 ret = gnutls_x509_crt_init(&crt);
    1060           1 :                 if (ret < 0) {
    1061           0 :                         gnutls_free(der.data);
    1062           0 :                         return gnutls_assert_val(ret);
    1063             :                 }
    1064             : 
    1065           1 :                 ret = gnutls_x509_crt_import(crt, &der, GNUTLS_X509_FMT_DER);
    1066           1 :                 gnutls_free(der.data);
    1067           1 :                 if (ret < 0) {
    1068           0 :                         gnutls_x509_crt_deinit(crt);
    1069           0 :                         return gnutls_assert_val(ret);
    1070             :                 }
    1071             : 
    1072           1 :                 *issuer = crt;
    1073           1 :                 return 0;
    1074             :         }
    1075             : #endif
    1076             :         return ret;
    1077             : }
    1078             : 
    1079             : /**
    1080             :  * gnutls_x509_trust_list_get_issuer_by_subject_key_id:
    1081             :  * @list: The list
    1082             :  * @dn: is the issuer's DN (may be %NULL)
    1083             :  * @spki: is the subject key ID
    1084             :  * @issuer: Will hold the issuer if any. Should be deallocated after use.
    1085             :  * @flags: Use zero
    1086             :  *
    1087             :  * This function will find the issuer with the given name and subject key ID, and
    1088             :  * return a copy of the issuer, which must be freed using gnutls_x509_crt_deinit().
    1089             :  *
    1090             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
    1091             :  *   negative error value.
    1092             :  *
    1093             :  * Since: 3.4.2
    1094             :  **/
    1095           4 : int gnutls_x509_trust_list_get_issuer_by_subject_key_id(gnutls_x509_trust_list_t list,
    1096             :                                       const gnutls_datum_t *dn,
    1097             :                                       const gnutls_datum_t *spki,
    1098             :                                       gnutls_x509_crt_t *issuer,
    1099             :                                       unsigned int flags)
    1100             : {
    1101           4 :         int ret;
    1102             : 
    1103           4 :         ret = trust_list_get_issuer_by_dn(list, dn, spki, issuer, flags);
    1104           4 :         if (ret == 0) {
    1105             :                 return 0;
    1106             :         }
    1107             : 
    1108             : #ifdef ENABLE_PKCS11
    1109           4 :         if (ret < 0 && list->pkcs11_token) {
    1110           0 :                 gnutls_x509_crt_t crt;
    1111           0 :                 gnutls_datum_t der = {NULL, 0};
    1112             :                 /* use the token for verification */
    1113           0 :                 ret = gnutls_pkcs11_get_raw_issuer_by_subject_key_id(list->pkcs11_token, dn, spki, &der,
    1114             :                         GNUTLS_X509_FMT_DER, GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE);
    1115           0 :                 if (ret < 0) {
    1116           0 :                         gnutls_assert();
    1117           0 :                         return ret;
    1118             :                 }
    1119             : 
    1120           0 :                 ret = gnutls_x509_crt_init(&crt);
    1121           0 :                 if (ret < 0) {
    1122           0 :                         gnutls_free(der.data);
    1123           0 :                         return gnutls_assert_val(ret);
    1124             :                 }
    1125             : 
    1126           0 :                 ret = gnutls_x509_crt_import(crt, &der, GNUTLS_X509_FMT_DER);
    1127           0 :                 gnutls_free(der.data);
    1128           0 :                 if (ret < 0) {
    1129           0 :                         gnutls_x509_crt_deinit(crt);
    1130           0 :                         return gnutls_assert_val(ret);
    1131             :                 }
    1132             : 
    1133           0 :                 *issuer = crt;
    1134           0 :                 return 0;
    1135             :         }
    1136             : #endif
    1137             :         return ret;
    1138             : }
    1139             : 
    1140             : static
    1141        1196 : int check_if_in_blacklist(gnutls_x509_crt_t * cert_list, unsigned int cert_list_size,
    1142             :         gnutls_x509_crt_t * blacklist, unsigned int blacklist_size)
    1143             : {
    1144        1196 : unsigned i, j;
    1145             : 
    1146        1196 :         if (blacklist_size == 0)
    1147             :                 return 0;
    1148             : 
    1149           1 :         for (i=0;i<cert_list_size;i++) {
    1150           1 :                 for (j=0;j<blacklist_size;j++) {
    1151           1 :                         if (gnutls_x509_crt_equals(cert_list[i], blacklist[j]) != 0) {
    1152             :                                 return 1;
    1153             :                         }
    1154             :                 }
    1155             :         }
    1156             : 
    1157             :         return 0;
    1158             : }
    1159             : 
    1160             : /**
    1161             :  * gnutls_x509_trust_list_verify_crt:
    1162             :  * @list: The list
    1163             :  * @cert_list: is the certificate list to be verified
    1164             :  * @cert_list_size: is the certificate list size
    1165             :  * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
    1166             :  * @voutput: will hold the certificate verification output.
    1167             :  * @func: If non-null will be called on each chain element verification with the output.
    1168             :  *
    1169             :  * This function will try to verify the given certificate and return
    1170             :  * its status. The @voutput parameter will hold an OR'ed sequence of
    1171             :  * %gnutls_certificate_status_t flags.
    1172             :  *
    1173             :  * The details of the verification are the same as in gnutls_x509_trust_list_verify_crt2().
    1174             :  *
    1175             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
    1176             :  *   negative error value.
    1177             :  *
    1178             :  * Since: 3.0
    1179             :  **/
    1180             : int
    1181         206 : gnutls_x509_trust_list_verify_crt(gnutls_x509_trust_list_t list,
    1182             :                                   gnutls_x509_crt_t * cert_list,
    1183             :                                   unsigned int cert_list_size,
    1184             :                                   unsigned int flags,
    1185             :                                   unsigned int *voutput,
    1186             :                                   gnutls_verify_output_function func)
    1187             : {
    1188         206 :         return gnutls_x509_trust_list_verify_crt2(list, cert_list, cert_list_size,
    1189             :                                                   NULL, 0, flags, voutput, func);
    1190             : }
    1191             : 
    1192             : #define LAST_DN cert_list[cert_list_size-1]->raw_dn
    1193             : #define LAST_IDN cert_list[cert_list_size-1]->raw_issuer_dn
    1194             : /* This macro is introduced to detect a verification output which
    1195             :  * indicates an unknown signer, a signer which uses an insecure
    1196             :  * algorithm (e.g., sha1), a signer has expired, or something that
    1197             :  * indicates a superseded signer */
    1198             : #define SIGNER_OLD_OR_UNKNOWN(output) ((output & GNUTLS_CERT_SIGNER_NOT_FOUND) || \
    1199             :                                        (output & GNUTLS_CERT_EXPIRED) || \
    1200             :                                        (output & GNUTLS_CERT_INSECURE_ALGORITHM))
    1201             : #define SIGNER_WAS_KNOWN(output) (!(output & GNUTLS_CERT_SIGNER_NOT_FOUND))
    1202             : 
    1203             : /**
    1204             :  * gnutls_x509_trust_list_verify_crt2:
    1205             :  * @list: The list
    1206             :  * @cert_list: is the certificate list to be verified
    1207             :  * @cert_list_size: is the certificate list size
    1208             :  * @data: an array of typed data
    1209             :  * @elements: the number of data elements
    1210             :  * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
    1211             :  * @voutput: will hold the certificate verification output.
    1212             :  * @func: If non-null will be called on each chain element verification with the output.
    1213             :  *
    1214             :  * This function will attempt to verify the given certificate chain and return
    1215             :  * its status. The @voutput parameter will hold an OR'ed sequence of
    1216             :  * %gnutls_certificate_status_t flags.
    1217             :  *
    1218             :  * When a certificate chain of @cert_list_size with more than one certificates is
    1219             :  * provided, the verification status will apply to the first certificate in the chain
    1220             :  * that failed verification. The verification process starts from the end of the chain
    1221             :  * (from CA to end certificate). The first certificate in the chain must be the end-certificate
    1222             :  * while the rest of the members may be sorted or not.
    1223             :  *
    1224             :  * Additionally a certificate verification profile can be specified
    1225             :  * from the ones in %gnutls_certificate_verification_profiles_t by
    1226             :  * ORing the result of GNUTLS_PROFILE_TO_VFLAGS() to the verification
    1227             :  * flags.
    1228             :  *
    1229             :  * Additional verification parameters are possible via the @data types; the
    1230             :  * acceptable types are %GNUTLS_DT_DNS_HOSTNAME, %GNUTLS_DT_IP_ADDRESS and %GNUTLS_DT_KEY_PURPOSE_OID.
    1231             :  * The former accepts as data a null-terminated hostname, and the latter a null-terminated
    1232             :  * object identifier (e.g., %GNUTLS_KP_TLS_WWW_SERVER).
    1233             :  * If a DNS hostname is provided then this function will compare
    1234             :  * the hostname in the end certificate against the given. If names do not match the
    1235             :  * %GNUTLS_CERT_UNEXPECTED_OWNER status flag will be set. In addition it
    1236             :  * will consider certificates provided with gnutls_x509_trust_list_add_named_crt().
    1237             :  *
    1238             :  * If a key purpose OID is provided and the end-certificate contains the extended key
    1239             :  * usage PKIX extension, it will be required to match the provided OID
    1240             :  * or be marked for any purpose, otherwise verification will fail with 
    1241             :  * %GNUTLS_CERT_PURPOSE_MISMATCH status.
    1242             :  *
    1243             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
    1244             :  *   negative error value. Note that verification failure will not result to an
    1245             :  *   error code, only @voutput will be updated.
    1246             :  *
    1247             :  * Since: 3.3.8
    1248             :  **/
    1249             : int
    1250         796 : gnutls_x509_trust_list_verify_crt2(gnutls_x509_trust_list_t list,
    1251             :                                   gnutls_x509_crt_t * cert_list,
    1252             :                                   unsigned int cert_list_size,
    1253             :                                   gnutls_typed_vdata_st *data,
    1254             :                                   unsigned int elements,
    1255             :                                   unsigned int flags,
    1256             :                                   unsigned int *voutput,
    1257             :                                   gnutls_verify_output_function func)
    1258             : {
    1259         796 :         int ret;
    1260         796 :         unsigned int i;
    1261         796 :         size_t hash;
    1262         796 :         gnutls_x509_crt_t sorted[DEFAULT_MAX_VERIFY_DEPTH];
    1263         796 :         const char *hostname = NULL, *purpose = NULL, *email = NULL;
    1264         796 :         unsigned hostname_size = 0;
    1265         796 :         unsigned have_set_name = 0;
    1266         796 :         unsigned saved_output;
    1267         796 :         gnutls_datum_t ip = {NULL, 0};
    1268             : 
    1269         796 :         if (cert_list == NULL || cert_list_size < 1)
    1270           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    1271             : 
    1272        1586 :         for (i=0;i<elements;i++) {
    1273         790 :                 if (data[i].type == GNUTLS_DT_DNS_HOSTNAME) {
    1274         398 :                         hostname = (void*)data[i].data;
    1275         398 :                         if (data[i].size > 0) {
    1276           4 :                                 hostname_size = data[i].size;
    1277             :                         }
    1278             : 
    1279         398 :                         if (have_set_name != 0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    1280             :                         have_set_name = 1;
    1281         392 :                 } else if (data[i].type == GNUTLS_DT_IP_ADDRESS) {
    1282           3 :                         if (data[i].size > 0) {
    1283           3 :                                 ip.data = data[i].data;
    1284           3 :                                 ip.size = data[i].size;
    1285             :                         }
    1286             : 
    1287           3 :                         if (have_set_name != 0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    1288             :                         have_set_name = 1;
    1289         389 :                 } else if (data[i].type == GNUTLS_DT_RFC822NAME) {
    1290           8 :                         email = (void*)data[i].data;
    1291             : 
    1292           8 :                         if (have_set_name != 0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    1293             :                         have_set_name = 1;
    1294         381 :                 } else if (data[i].type == GNUTLS_DT_KEY_PURPOSE_OID) {
    1295         381 :                         purpose = (void*)data[i].data;
    1296             :                 }
    1297             :         }
    1298             : 
    1299         796 :         if (hostname) { /* shortcut using the named certs - if any */
    1300         398 :                 unsigned vtmp = 0;
    1301         398 :                 if (hostname_size == 0)
    1302         394 :                         hostname_size = strlen(hostname);
    1303             : 
    1304         398 :                 ret = gnutls_x509_trust_list_verify_named_crt(list,
    1305             :                                         cert_list[0], hostname, hostname_size,
    1306             :                                         flags, &vtmp, func);
    1307         398 :                 if (ret == 0 && vtmp == 0) {
    1308           1 :                         *voutput = vtmp;
    1309           1 :                         return 0;
    1310             :                 }
    1311             :         }
    1312             : 
    1313         795 :         if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_UNSORTED_CHAIN))
    1314         794 :                 cert_list = _gnutls_sort_clist(sorted, cert_list, &cert_list_size, NULL);
    1315             : 
    1316         795 :         cert_list_size = shorten_clist(list, cert_list, cert_list_size);
    1317         795 :         if (cert_list_size <= 0)
    1318           0 :                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
    1319             : 
    1320         795 :         hash =
    1321         795 :             hash_pjw_bare(cert_list[cert_list_size - 1]->raw_issuer_dn.
    1322             :                           data,
    1323         795 :                           cert_list[cert_list_size -
    1324         795 :                                     1]->raw_issuer_dn.size);
    1325         795 :         hash %= list->size;
    1326             : 
    1327         795 :         ret = check_if_in_blacklist(cert_list, cert_list_size,
    1328             :                 list->blacklisted, list->blacklisted_size);
    1329         795 :         if (ret != 0) {
    1330           1 :                 *voutput = 0;
    1331           1 :                 *voutput |= GNUTLS_CERT_REVOKED;
    1332           1 :                 *voutput |= GNUTLS_CERT_INVALID;
    1333           1 :                 return 0;
    1334             :         }
    1335             : 
    1336        1588 :         *voutput =
    1337         794 :             _gnutls_verify_crt_status(list, cert_list, cert_list_size,
    1338         794 :                                       list->node[hash].trusted_cas,
    1339         794 :                                       list->node[hash].trusted_ca_size,
    1340             :                                       flags, purpose, func);
    1341         794 :         saved_output = *voutput;
    1342             : 
    1343         794 :         if (SIGNER_OLD_OR_UNKNOWN(*voutput) &&
    1344         302 :                 (LAST_DN.size != LAST_IDN.size ||
    1345          84 :                  memcmp(LAST_DN.data, LAST_IDN.data, LAST_IDN.size) != 0)) {
    1346             : 
    1347             :                 /* if we couldn't find the issuer, try to see if the last
    1348             :                  * certificate is in the trusted list and try to verify against
    1349             :                  * (if it is not self signed) */
    1350         261 :                 hash =
    1351         261 :                     hash_pjw_bare(cert_list[cert_list_size - 1]->raw_dn.
    1352             :                           data, cert_list[cert_list_size - 1]->raw_dn.size);
    1353         261 :                 hash %= list->size;
    1354             : 
    1355         261 :                  _gnutls_debug_log("issuer in verification was not found or insecure; trying against trust list\n");
    1356             : 
    1357         522 :                 *voutput =
    1358         261 :                     _gnutls_verify_crt_status(list, cert_list, cert_list_size,
    1359         261 :                                               list->node[hash].trusted_cas,
    1360         261 :                                               list->node[hash].trusted_ca_size,
    1361             :                                               flags, purpose, func);
    1362         261 :                 if (*voutput != 0) {
    1363         255 :                         if (SIGNER_WAS_KNOWN(saved_output))
    1364          33 :                                 *voutput = saved_output;
    1365         255 :                         gnutls_assert();
    1366             :                 }
    1367             :         }
    1368             : 
    1369         794 :         saved_output = *voutput;
    1370             : 
    1371             : #ifdef ENABLE_PKCS11
    1372         794 :         if (SIGNER_OLD_OR_UNKNOWN(*voutput) && list->pkcs11_token) {
    1373             :                 /* use the token for verification */
    1374             : 
    1375          86 :                 *voutput = _gnutls_pkcs11_verify_crt_status(list, list->pkcs11_token,
    1376             :                                                             cert_list, cert_list_size,
    1377             :                                                             purpose,
    1378             :                                                             flags, func);
    1379          86 :                 if (*voutput != 0) {
    1380          49 :                         if (SIGNER_WAS_KNOWN(saved_output))
    1381           0 :                                 *voutput = saved_output;
    1382          49 :                         gnutls_assert();
    1383             :                 }
    1384             :         }
    1385             : #endif
    1386             : 
    1387             :         /* End-certificate, key purpose and hostname checks. */
    1388         794 :         if (purpose) {
    1389         381 :                 ret = _gnutls_check_key_purpose(cert_list[0], purpose, 0);
    1390         381 :                 if (ret != 1) {
    1391          11 :                         gnutls_assert();
    1392          11 :                         *voutput |= GNUTLS_CERT_PURPOSE_MISMATCH|GNUTLS_CERT_INVALID;
    1393             :                 }
    1394             :         }
    1395             : 
    1396         794 :         if (hostname) {
    1397         794 :                 ret =
    1398         397 :                     gnutls_x509_crt_check_hostname2(cert_list[0], hostname, flags);
    1399         397 :                 if (ret == 0) {
    1400         173 :                         gnutls_assert();
    1401         173 :                         *voutput |= GNUTLS_CERT_UNEXPECTED_OWNER|GNUTLS_CERT_INVALID;
    1402             :                 }
    1403             :         }
    1404             : 
    1405         794 :         if (ip.data) {
    1406           6 :                 ret =
    1407           3 :                     gnutls_x509_crt_check_ip(cert_list[0], ip.data, ip.size, flags);
    1408           3 :                 if (ret == 0) {
    1409           1 :                         gnutls_assert();
    1410           1 :                         *voutput |= GNUTLS_CERT_UNEXPECTED_OWNER|GNUTLS_CERT_INVALID;
    1411             :                 }
    1412             :         }
    1413             : 
    1414         794 :         if (email) {
    1415          16 :                 ret =
    1416           8 :                     gnutls_x509_crt_check_email(cert_list[0], email, 0);
    1417           8 :                 if (ret == 0) {
    1418           4 :                         gnutls_assert();
    1419           4 :                         *voutput |= GNUTLS_CERT_UNEXPECTED_OWNER|GNUTLS_CERT_INVALID;
    1420             :                 }
    1421             :         }
    1422             : 
    1423             :         /* CRL checks follow */
    1424             : 
    1425         794 :         if (*voutput != 0 || (flags & GNUTLS_VERIFY_DISABLE_CRL_CHECKS))
    1426             :                 return 0;
    1427             : 
    1428             :         /* Check revocation of individual certificates.
    1429             :          * start with the last one that we already have its hash
    1430             :          */
    1431         396 :         ret =
    1432         792 :             _gnutls_x509_crt_check_revocation(cert_list
    1433         396 :                                               [cert_list_size - 1],
    1434         396 :                                               list->node[hash].crls,
    1435         396 :                                               list->node[hash].crl_size,
    1436             :                                               func);
    1437         396 :         if (ret == 1) {         /* revoked */
    1438           2 :                 *voutput |= GNUTLS_CERT_REVOKED;
    1439           2 :                 *voutput |= GNUTLS_CERT_INVALID;
    1440           2 :                 return 0;
    1441             :         }
    1442             : 
    1443         650 :         for (i = 0; i < cert_list_size - 1; i++) {
    1444         261 :                 hash =
    1445         261 :                     hash_pjw_bare(cert_list[i]->raw_issuer_dn.data,
    1446         261 :                                   cert_list[i]->raw_issuer_dn.size);
    1447         261 :                 hash %= list->size;
    1448             : 
    1449         522 :                 ret = _gnutls_x509_crt_check_revocation(cert_list[i],
    1450         261 :                                                         list->node[hash].
    1451             :                                                         crls,
    1452         261 :                                                         list->node[hash].
    1453             :                                                         crl_size, func);
    1454         261 :                 if (ret < 0) {
    1455           0 :                         gnutls_assert();
    1456         261 :                 } else if (ret == 1) {  /* revoked */
    1457           5 :                         *voutput |= GNUTLS_CERT_REVOKED;
    1458           5 :                         *voutput |= GNUTLS_CERT_INVALID;
    1459           5 :                         return 0;
    1460             :                 }
    1461             :         }
    1462             : 
    1463             :         return 0;
    1464             : }
    1465             : 
    1466             : /**
    1467             :  * gnutls_x509_trust_list_verify_named_crt:
    1468             :  * @list: The list
    1469             :  * @cert: is the certificate to be verified
    1470             :  * @name: is the certificate's name
    1471             :  * @name_size: is the certificate's name size
    1472             :  * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
    1473             :  * @voutput: will hold the certificate verification output.
    1474             :  * @func: If non-null will be called on each chain element verification with the output.
    1475             :  *
    1476             :  * This function will try to find a certificate that is associated with the provided
    1477             :  * name --see gnutls_x509_trust_list_add_named_crt(). If a match is found the
    1478             :  * certificate is considered valid. In addition to that this function will also 
    1479             :  * check CRLs. The @voutput parameter will hold an OR'ed sequence of 
    1480             :  * %gnutls_certificate_status_t flags.
    1481             :  *
    1482             :  * Additionally a certificate verification profile can be specified
    1483             :  * from the ones in %gnutls_certificate_verification_profiles_t by
    1484             :  * ORing the result of GNUTLS_PROFILE_TO_VFLAGS() to the verification
    1485             :  * flags.
    1486             :  *
    1487             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
    1488             :  *   negative error value.
    1489             :  *
    1490             :  * Since: 3.0.0
    1491             :  **/
    1492             : int
    1493         401 : gnutls_x509_trust_list_verify_named_crt(gnutls_x509_trust_list_t list,
    1494             :                                         gnutls_x509_crt_t cert,
    1495             :                                         const void *name,
    1496             :                                         size_t name_size,
    1497             :                                         unsigned int flags,
    1498             :                                         unsigned int *voutput,
    1499             :                                         gnutls_verify_output_function func)
    1500             : {
    1501         401 :         int ret;
    1502         401 :         unsigned int i;
    1503         401 :         size_t hash;
    1504             : 
    1505             : 
    1506         401 :         hash =
    1507         401 :             hash_pjw_bare(cert->raw_issuer_dn.data,
    1508         401 :                           cert->raw_issuer_dn.size);
    1509         401 :         hash %= list->size;
    1510             : 
    1511         401 :         ret = check_if_in_blacklist(&cert, 1,
    1512             :                 list->blacklisted, list->blacklisted_size);
    1513         401 :         if (ret != 0) {
    1514           0 :                 *voutput = 0;
    1515           0 :                 *voutput |= GNUTLS_CERT_REVOKED;
    1516           0 :                 *voutput |= GNUTLS_CERT_INVALID;
    1517           0 :                 return 0;
    1518             :         }
    1519             : 
    1520         401 :         *voutput = GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNER_NOT_FOUND;
    1521             : 
    1522         404 :         for (i = 0; i < list->node[hash].named_cert_size; i++) {
    1523           5 :                 if (gnutls_x509_crt_equals(cert, list->node[hash].named_certs[i].cert) != 0) {       /* check if name matches */
    1524           5 :                         if (list->node[hash].named_certs[i].name_size ==
    1525             :                             name_size
    1526           2 :                             && memcmp(list->node[hash].named_certs[i].name,
    1527             :                                       name, name_size) == 0) {
    1528           2 :                                 *voutput = 0;
    1529           2 :                                 break;
    1530             :                         }
    1531             :                 }
    1532             :         }
    1533             : 
    1534         401 :         if (*voutput != 0 || (flags & GNUTLS_VERIFY_DISABLE_CRL_CHECKS))
    1535             :                 return 0;
    1536             : 
    1537             :         /* Check revocation of individual certificates.
    1538             :          * start with the last one that we already have its hash
    1539             :          */
    1540           4 :         ret = _gnutls_x509_crt_check_revocation(cert,
    1541           2 :                                                 list->node[hash].crls,
    1542           2 :                                                 list->node[hash].crl_size,
    1543             :                                                 func);
    1544           2 :         if (ret == 1) {         /* revoked */
    1545           0 :                 *voutput |= GNUTLS_CERT_REVOKED;
    1546           0 :                 *voutput |= GNUTLS_CERT_INVALID;
    1547           0 :                 return 0;
    1548             :         }
    1549             : 
    1550             :         return 0;
    1551             : }
    1552             : 
    1553             : /* return 1 if @cert is in @list, 0 if not */
    1554             : int
    1555          22 : _gnutls_trustlist_inlist(gnutls_x509_trust_list_t list,
    1556             :                          gnutls_x509_crt_t cert)
    1557             : {
    1558          22 :         int ret;
    1559          22 :         unsigned int i;
    1560          22 :         size_t hash;
    1561             : 
    1562          22 :         hash = hash_pjw_bare(cert->raw_dn.data, cert->raw_dn.size);
    1563          22 :         hash %= list->size;
    1564             : 
    1565          22 :         for (i = 0; i < list->node[hash].trusted_ca_size; i++) {
    1566           4 :                 ret =
    1567           2 :                     gnutls_x509_crt_equals(cert,
    1568           2 :                                                list->node[hash].
    1569           2 :                                                trusted_cas[i]);
    1570           2 :                 if (ret != 0)
    1571             :                         return 1;
    1572             :         }
    1573             : 
    1574             :         return 0;
    1575             : }

Generated by: LCOV version 1.14