LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib/x509 - verify.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 589 744 79.2 %
Date: 2020-10-30 04:50:48 Functions: 22 24 91.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2003-2014 Free Software Foundation, Inc.
       3             :  * Copyright (C) 2013 Nikos Mavrogiannopoulos
       4             :  * Copyright (C) 2014 Red Hat
       5             :  *
       6             :  * Author: Nikos Mavrogiannopoulos
       7             :  *
       8             :  * This file is part of GnuTLS.
       9             :  *
      10             :  * The GnuTLS is free software; you can redistribute it and/or
      11             :  * modify it under the terms of the GNU Lesser General Public License
      12             :  * as published by the Free Software Foundation; either version 2.1 of
      13             :  * the License, or (at your option) any later version.
      14             :  *
      15             :  * This library is distributed in the hope that it will be useful, but
      16             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      18             :  * Lesser General Public License for more details.
      19             :  *
      20             :  * You should have received a copy of the GNU Lesser General Public License
      21             :  * along with this program.  If not, see <https://www.gnu.org/licenses/>
      22             :  *
      23             :  */
      24             : 
      25             : /* All functions which relate to X.509 certificate verification stuff are
      26             :  * included here
      27             :  */
      28             : 
      29             : #include "gnutls_int.h"
      30             : #include "errors.h"
      31             : #include <libtasn1.h>
      32             : #include <global.h>
      33             : #include <num.h>          /* MAX */
      34             : #include <tls-sig.h>
      35             : #include <str.h>
      36             : #include <datum.h>
      37             : #include <pkcs11_int.h>
      38             : #include <x509_int.h>
      39             : #include <common.h>
      40             : #include <pk.h>
      41             : #include <x509/verify-high.h>
      42             : #include "supported_exts.h"
      43             : #include "profiles.h"
      44             : 
      45             : /* Checks if two certs have the same name and the same key.  Return 1 on match. 
      46             :  * If @is_ca is zero then this function is identical to gnutls_x509_crt_equals()
      47             :  */
      48             : unsigned
      49        1120 : _gnutls_check_if_same_key(gnutls_x509_crt_t cert1,
      50             :                           gnutls_x509_crt_t cert2,
      51             :                           unsigned is_ca)
      52             : {
      53        1120 :         int ret;
      54        1120 :         unsigned result;
      55             : 
      56        1120 :         if (is_ca == 0)
      57         607 :                 return gnutls_x509_crt_equals(cert1, cert2);
      58             : 
      59         513 :         ret = _gnutls_is_same_dn(cert1, cert2);
      60         513 :         if (ret == 0)
      61             :                 return 0;
      62             : 
      63          18 :         if (cert1->raw_spki.size > 0 && (cert1->raw_spki.size == cert2->raw_spki.size) &&
      64          18 :             (memcmp(cert1->raw_spki.data, cert2->raw_spki.data, cert1->raw_spki.size) == 0))
      65             :                 result = 1;
      66             :         else
      67           0 :                 result = 0;
      68             : 
      69             :         return result;
      70             : }
      71             : 
      72             : unsigned
      73           0 : _gnutls_check_if_same_key2(gnutls_x509_crt_t cert1,
      74             :                            gnutls_datum_t * cert2bin)
      75             : {
      76           0 :         int ret;
      77           0 :         gnutls_x509_crt_t cert2;
      78             : 
      79           0 :         ret = gnutls_x509_crt_init(&cert2);
      80           0 :         if (ret < 0)
      81           0 :                 return gnutls_assert_val(0);
      82             : 
      83           0 :         ret = gnutls_x509_crt_import(cert2, cert2bin, GNUTLS_X509_FMT_DER);
      84           0 :         if (ret < 0) {
      85           0 :                 gnutls_x509_crt_deinit(cert2);
      86           0 :                 return gnutls_assert_val(0);
      87             :         }
      88             : 
      89           0 :         ret = _gnutls_check_if_same_key(cert1, cert2, 1);
      90             : 
      91           0 :         gnutls_x509_crt_deinit(cert2);
      92           0 :         return ret;
      93             : }
      94             : 
      95             : /* checks whether there are present unknown/unsupported critical extensions.
      96             :  *
      97             :  * Returns true if they are present.
      98             :  */
      99        2167 : static unsigned check_for_unknown_exts(gnutls_x509_crt_t cert)
     100             : {
     101        2167 :         unsigned i;
     102        2167 :         char oid[MAX_OID_SIZE];
     103        2167 :         size_t oid_size;
     104        2167 :         unsigned critical;
     105        2167 :         int ret;
     106             : 
     107       12100 :         for (i=0;;i++) {
     108       12100 :                 oid_size = sizeof(oid);
     109       12100 :                 oid[0] = 0;
     110       12100 :                 critical = 0;
     111             : 
     112       12100 :                 ret = gnutls_x509_crt_get_extension_info(cert, i, oid, &oid_size, &critical);
     113       12100 :                 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
     114             :                         return 0;
     115        9958 :                 } else if (ret < 0) {
     116           0 :                         gnutls_assert();
     117             :                         /* could not decode? */
     118           0 :                         _gnutls_debug_log("Could not decode extension %d\n", i);
     119           0 :                         return 1;
     120             :                 }
     121             : 
     122        9958 :                 if (critical == 0)
     123        6334 :                         continue;
     124             : 
     125        3624 :                 if (is_ext_oid_supported(oid, oid_size) == NULL) {
     126          25 :                         gnutls_assert();
     127          25 :                         _gnutls_debug_log("Unsupported critical extension: %s\n", oid);
     128          25 :                         return 1;
     129             :                 }
     130             :         }
     131             : 
     132             :         return 0;
     133             : }
     134             : 
     135             : /* Checks if the issuer of a certificate is a
     136             :  * Certificate Authority, or if the certificate is the same
     137             :  * as the issuer (and therefore it doesn't need to be a CA).
     138             :  *
     139             :  * Returns true or false, if the issuer is a CA,
     140             :  * or not.
     141             :  */
     142             : static unsigned
     143        1096 : check_if_ca(gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
     144             :             unsigned int *max_path, unsigned int flags)
     145             : {
     146        1096 :         gnutls_datum_t cert_signed_data = { NULL, 0 };
     147        1096 :         gnutls_datum_t issuer_signed_data = { NULL, 0 };
     148        1096 :         gnutls_datum_t cert_signature = { NULL, 0 };
     149        1096 :         gnutls_datum_t issuer_signature = { NULL, 0 };
     150        1096 :         int pathlen = -1, ret;
     151        1096 :         unsigned result;
     152        1096 :         unsigned int ca_status = 0;
     153             : 
     154             :         /* Check if the issuer is the same with the
     155             :          * certificate. This is added in order for trusted
     156             :          * certificates to be able to verify themselves.
     157             :          */
     158             : 
     159        1096 :         ret =
     160        1096 :             _gnutls_x509_get_signed_data(issuer->cert, &issuer->der, "tbsCertificate",
     161             :                                          &issuer_signed_data);
     162        1096 :         if (ret < 0) {
     163           0 :                 gnutls_assert();
     164           0 :                 goto fail;
     165             :         }
     166             : 
     167        1096 :         ret =
     168        1096 :             _gnutls_x509_get_signed_data(cert->cert, &cert->der, "tbsCertificate",
     169             :                                          &cert_signed_data);
     170        1096 :         if (ret < 0) {
     171           0 :                 gnutls_assert();
     172           0 :                 goto fail;
     173             :         }
     174             : 
     175        1096 :         ret =
     176        1096 :             _gnutls_x509_get_signature(issuer->cert, "signature",
     177             :                                        &issuer_signature);
     178        1096 :         if (ret < 0) {
     179           0 :                 gnutls_assert();
     180           0 :                 goto fail;
     181             :         }
     182             : 
     183        1096 :         ret =
     184        1096 :             _gnutls_x509_get_signature(cert->cert, "signature",
     185             :                                        &cert_signature);
     186        1096 :         if (ret < 0) {
     187           8 :                 gnutls_assert();
     188           8 :                 goto fail;
     189             :         }
     190             : 
     191             :         /* If the subject certificate is the same as the issuer
     192             :          * return true.
     193             :          */
     194        1088 :         if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_SAME))
     195         842 :                 if (cert_signed_data.size == issuer_signed_data.size) {
     196          16 :                         if ((memcmp
     197          16 :                              (cert_signed_data.data,
     198          16 :                               issuer_signed_data.data,
     199             :                               cert_signed_data.size) == 0)
     200           0 :                             && (cert_signature.size ==
     201           0 :                                 issuer_signature.size)
     202           0 :                             &&
     203           0 :                             (memcmp
     204           0 :                              (cert_signature.data, issuer_signature.data,
     205             :                               cert_signature.size) == 0)) {
     206           0 :                                 result = 1;
     207           0 :                                 goto cleanup;
     208             :                         }
     209             :                 }
     210             : 
     211        1088 :         ret =
     212        1088 :             gnutls_x509_crt_get_basic_constraints(issuer, NULL, &ca_status,
     213             :                                                   &pathlen);
     214        1088 :         if (ret < 0) {
     215          16 :                 ca_status = 0;
     216          16 :                 pathlen = -1;
     217             :         }
     218             : 
     219        1088 :         if (ca_status != 0 && pathlen != -1) {
     220          86 :                 if ((unsigned) pathlen < *max_path)
     221          84 :                         *max_path = pathlen;
     222             :         }
     223             : 
     224        1088 :         if (ca_status != 0) {
     225        1064 :                 result = 1;
     226        1064 :                 goto cleanup;
     227             :         }
     228             :         /* Handle V1 CAs that do not have a basicConstraint, but accept
     229             :            these certs only if the appropriate flags are set. */
     230          24 :         else if ((ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) &&
     231          16 :                  ((flags & GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT) ||
     232          16 :                   (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT) &&
     233           0 :                    (gnutls_x509_crt_check_issuer(issuer, issuer) != 0)))) {
     234           0 :                 gnutls_assert();
     235           0 :                 result = 1;
     236           0 :                 goto cleanup;
     237             :         } else {
     238          24 :                 gnutls_assert();
     239             :         }
     240             : 
     241          24 :  fail:
     242             :         result = 0;
     243             : 
     244        1096 :  cleanup:
     245        1096 :         _gnutls_free_datum(&cert_signed_data);
     246        1096 :         _gnutls_free_datum(&issuer_signed_data);
     247        1096 :         _gnutls_free_datum(&cert_signature);
     248        1096 :         _gnutls_free_datum(&issuer_signature);
     249        1096 :         return result;
     250             : }
     251             : 
     252             : 
     253             : /* This function checks if cert's issuer is issuer.
     254             :  * This does a straight (DER) compare of the issuer/subject DN fields in
     255             :  * the given certificates, as well as check the authority key ID.
     256             :  *
     257             :  * Returns 1 if they match and (0) if they don't match. 
     258             :  */
     259        4898 : static unsigned is_issuer(gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer)
     260             : {
     261        4898 :         uint8_t id1[MAX_KEY_ID_SIZE];
     262        4898 :         uint8_t id2[MAX_KEY_ID_SIZE];
     263        4898 :         size_t id1_size;
     264        4898 :         size_t id2_size;
     265        4898 :         int ret;
     266        4898 :         unsigned result;
     267             : 
     268        4898 :         if (_gnutls_x509_compare_raw_dn
     269        4898 :             (&cert->raw_issuer_dn, &issuer->raw_dn) != 0)
     270             :                 result = 1;
     271             :         else
     272             :                 result = 0;
     273             : 
     274        3539 :         if (result != 0) {
     275             :                 /* check if the authority key identifier matches the subject key identifier
     276             :                  * of the issuer */
     277        3539 :                 id1_size = sizeof(id1);
     278             : 
     279        3539 :                 ret =
     280        3539 :                     gnutls_x509_crt_get_authority_key_id(cert, id1,
     281             :                                                          &id1_size, NULL);
     282        3539 :                 if (ret < 0) {
     283             :                         /* If there is no authority key identifier in the
     284             :                          * certificate, assume they match */
     285         494 :                         result = 1;
     286         494 :                         goto cleanup;
     287             :                 }
     288             : 
     289        3045 :                 id2_size = sizeof(id2);
     290        3045 :                 ret =
     291        3045 :                     gnutls_x509_crt_get_subject_key_id(issuer, id2,
     292             :                                                        &id2_size, NULL);
     293        3045 :                 if (ret < 0) {
     294             :                         /* If there is no subject key identifier in the
     295             :                          * issuer certificate, assume they match */
     296          10 :                         result = 1;
     297          10 :                         gnutls_assert();
     298          10 :                         goto cleanup;
     299             :                 }
     300             : 
     301        3035 :                 if (id1_size == id2_size
     302        3035 :                     && memcmp(id1, id2, id1_size) == 0)
     303             :                         result = 1;
     304             :                 else
     305           1 :                         result = 0;
     306             :         }
     307             : 
     308        4898 :       cleanup:
     309        4898 :         return result;
     310             : }
     311             : 
     312             : /* Check if the given certificate is the issuer of the CRL.
     313             :  * Returns 1 on success and 0 otherwise.
     314             :  */
     315          12 : static unsigned is_crl_issuer(gnutls_x509_crl_t crl, gnutls_x509_crt_t issuer)
     316             : {
     317          12 :         if (_gnutls_x509_compare_raw_dn
     318          12 :             (&crl->raw_issuer_dn, &issuer->raw_dn) != 0)
     319             :                 return 1;
     320             :         else
     321           1 :                 return 0;
     322             : }
     323             : 
     324             : /* Checks if the DN of two certificates is the same.
     325             :  * Returns 1 if they match and (0) if they don't match. Otherwise
     326             :  * a negative error code is returned to indicate error.
     327             :  */
     328        5500 : unsigned _gnutls_is_same_dn(gnutls_x509_crt_t cert1, gnutls_x509_crt_t cert2)
     329             : {
     330        5500 :         if (_gnutls_x509_compare_raw_dn(&cert1->raw_dn, &cert2->raw_dn) !=
     331             :             0)
     332             :                 return 1;
     333             :         else
     334        3451 :                 return 0;
     335             : }
     336             : 
     337             : /* Finds an issuer of the certificate. If multiple issuers
     338             :  * are present, returns one that is activated and not expired.
     339             :  */
     340             : static inline gnutls_x509_crt_t
     341        1149 : find_issuer(gnutls_x509_crt_t cert,
     342             :             const gnutls_x509_crt_t * trusted_cas, int tcas_size)
     343             : {
     344        1149 :         int i;
     345        1149 :         gnutls_x509_crt_t issuer = NULL;
     346             : 
     347             :         /* this is serial search. 
     348             :          */
     349        2301 :         for (i = 0; i < tcas_size; i++) {
     350        1152 :                 if (is_issuer(cert, trusted_cas[i]) != 0) {
     351        1137 :                         if (issuer == NULL) {
     352        1137 :                                 issuer = trusted_cas[i];
     353             :                         } else {
     354           0 :                                 time_t now = gnutls_time(0);
     355             : 
     356           0 :                                 if (now <
     357           0 :                                     gnutls_x509_crt_get_expiration_time
     358             :                                     (trusted_cas[i])
     359           0 :                                     && now >=
     360           0 :                                     gnutls_x509_crt_get_activation_time
     361             :                                     (trusted_cas[i])) {
     362           0 :                                         issuer = trusted_cas[i];
     363             :                                 }
     364             :                         }
     365             :                 }
     366             :         }
     367             : 
     368        1149 :         return issuer;
     369             : }
     370             : 
     371        2634 : static unsigned int check_time_status(gnutls_x509_crt_t crt, time_t now)
     372             : {
     373        2634 :         int status = 0;
     374        2634 :         time_t t;
     375             : 
     376        2634 :         t = gnutls_x509_crt_get_activation_time(crt);
     377        2634 :         if (t == (time_t) - 1 || now < t) {
     378        2634 :                 status |= GNUTLS_CERT_NOT_ACTIVATED;
     379        2634 :                 status |= GNUTLS_CERT_INVALID;
     380             :                 return status;
     381             :         }
     382             : 
     383        2597 :         t = gnutls_x509_crt_get_expiration_time(crt);
     384        2597 :         if (t == (time_t) - 1 || now > t) {
     385          66 :                 status |= GNUTLS_CERT_EXPIRED;
     386          66 :                 status |= GNUTLS_CERT_INVALID;
     387          66 :                 return status;
     388             :         }
     389             : 
     390             :         return 0;
     391             : }
     392             : 
     393         945 : unsigned _gnutls_is_broken_sig_allowed(const gnutls_sign_entry_st *se, unsigned int flags)
     394             : {
     395         945 :         gnutls_digest_algorithm_t hash;
     396             : 
     397             :         /* we have a catch all */
     398         945 :         if ((flags & GNUTLS_VERIFY_ALLOW_BROKEN) == GNUTLS_VERIFY_ALLOW_BROKEN)
     399             :                 return 1;
     400             : 
     401             :         /* the first two are for backwards compatibility */
     402         112 :         if ((se->id == GNUTLS_SIGN_RSA_MD2)
     403           0 :             && (flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2))
     404             :                 return 1;
     405         112 :         if ((se->id == GNUTLS_SIGN_RSA_MD5)
     406          62 :             && (flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5))
     407             :                 return 1;
     408             : 
     409          94 :         hash = se->hash;
     410          94 :         if (hash == GNUTLS_DIG_SHA1 && (flags & GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1))
     411           8 :                 return 1;
     412             : 
     413             :         return 0;
     414             : }
     415             : 
     416             : #define CASE_SEC_PARAM(profile, level) \
     417             :         case profile: \
     418             :                 sym_bits = gnutls_sec_param_to_symmetric_bits(level); \
     419             :                 hash = gnutls_sign_get_hash_algorithm(sigalg); \
     420             :                 entry = mac_to_entry(hash); \
     421             :                 if (hash <= 0 || entry == NULL) { \
     422             :                         _gnutls_cert_log("cert", crt); \
     423             :                         _gnutls_debug_log(#level": certificate's signature hash is unknown\n"); \
     424             :                         return gnutls_assert_val(0); \
     425             :                 } \
     426             :                 if (_gnutls_sign_get_hash_strength(sigalg) < sym_bits) { \
     427             :                         _gnutls_cert_log("cert", crt); \
     428             :                         _gnutls_debug_log(#level": certificate's signature hash strength is unacceptable (is %u bits, needed %u)\n", _gnutls_sign_get_hash_strength(sigalg), sym_bits); \
     429             :                         return gnutls_assert_val(0); \
     430             :                 } \
     431             :                 sp = gnutls_pk_bits_to_sec_param(pkalg, bits); \
     432             :                 if (sp < level) { \
     433             :                         _gnutls_cert_log("cert", crt); \
     434             :                         _gnutls_debug_log(#level": certificate's security level is unacceptable\n"); \
     435             :                         return gnutls_assert_val(0); \
     436             :                 } \
     437             :                 if (issuer) { \
     438             :                         sp = gnutls_pk_bits_to_sec_param(issuer_pkalg, issuer_bits); \
     439             :                         if (sp < level) { \
     440             :                                 _gnutls_cert_log("issuer", issuer); \
     441             :                                 _gnutls_debug_log(#level": certificate's issuer security level is unacceptable\n"); \
     442             :                                 return gnutls_assert_val(0); \
     443             :                         } \
     444             :                 } \
     445             :                 break;
     446             : 
     447             : /* Checks whether the provided certificates are acceptable
     448             :  * according to verification profile specified.
     449             :  *
     450             :  * @crt: a certificate
     451             :  * @issuer: the certificates issuer (allowed to be NULL)
     452             :  * @sigalg: the signature algorithm used
     453             :  * @flags: the specified verification flags
     454             :  */
     455        1702 : static unsigned is_level_acceptable(
     456             :         gnutls_x509_crt_t crt, gnutls_x509_crt_t issuer,
     457             :         gnutls_sign_algorithm_t sigalg, unsigned flags)
     458             : {
     459        1702 :         gnutls_certificate_verification_profiles_t profile = GNUTLS_VFLAGS_TO_PROFILE(flags);
     460        1702 :         const mac_entry_st *entry;
     461        1702 :         int issuer_pkalg = 0, pkalg, ret;
     462        1702 :         unsigned bits = 0, issuer_bits = 0, sym_bits = 0;
     463        1702 :         gnutls_pk_params_st params;
     464        1702 :         gnutls_sec_param_t sp;
     465        1702 :         int hash;
     466        1702 :         gnutls_certificate_verification_profiles_t min_profile;
     467             : 
     468        1702 :         min_profile = _gnutls_get_system_wide_verification_profile();
     469             : 
     470        1702 :         if (min_profile) {
     471           6 :                 if (profile < min_profile) {
     472           0 :                         gnutls_assert();
     473             :                         profile = min_profile;
     474             :                 }
     475             :         }
     476             : 
     477        1702 :         if (profile == GNUTLS_PROFILE_UNKNOWN) {
     478             :                 return 1;
     479             :         }
     480             : 
     481         671 :         pkalg = gnutls_x509_crt_get_pk_algorithm(crt, &bits);
     482         671 :         if (pkalg < 0)
     483           0 :                 return gnutls_assert_val(0);
     484             : 
     485         671 :         if (issuer) {
     486         476 :                 issuer_pkalg = gnutls_x509_crt_get_pk_algorithm(issuer, &issuer_bits);
     487         476 :                 if (issuer_pkalg < 0)
     488           0 :                         return gnutls_assert_val(0);
     489             :         }
     490             : 
     491         671 :         switch (profile) {
     492           3 :                 CASE_SEC_PARAM(GNUTLS_PROFILE_VERY_WEAK, GNUTLS_SEC_PARAM_VERY_WEAK);
     493         603 :                 CASE_SEC_PARAM(GNUTLS_PROFILE_LOW, GNUTLS_SEC_PARAM_LOW);
     494           9 :                 CASE_SEC_PARAM(GNUTLS_PROFILE_LEGACY, GNUTLS_SEC_PARAM_LEGACY);
     495           6 :                 CASE_SEC_PARAM(GNUTLS_PROFILE_MEDIUM, GNUTLS_SEC_PARAM_MEDIUM);
     496          14 :                 CASE_SEC_PARAM(GNUTLS_PROFILE_HIGH, GNUTLS_SEC_PARAM_HIGH);
     497          24 :                 CASE_SEC_PARAM(GNUTLS_PROFILE_ULTRA, GNUTLS_SEC_PARAM_ULTRA);
     498           5 :                 CASE_SEC_PARAM(GNUTLS_PROFILE_FUTURE, GNUTLS_SEC_PARAM_FUTURE);
     499          11 :                 case GNUTLS_PROFILE_SUITEB128:
     500             :                 case GNUTLS_PROFILE_SUITEB192: {
     501          11 :                         unsigned curve, issuer_curve;
     502             : 
     503             :                         /* check suiteB params validity: rfc5759 */
     504             : 
     505          11 :                         if (gnutls_x509_crt_get_version(crt) != 3) {
     506           0 :                                 _gnutls_debug_log("SUITEB: certificate uses an unacceptable version number\n");
     507           0 :                                 return gnutls_assert_val(0);
     508             :                         }
     509             : 
     510          11 :                         if (sigalg != GNUTLS_SIGN_ECDSA_SHA256 && sigalg != GNUTLS_SIGN_ECDSA_SHA384) {
     511           0 :                                 _gnutls_debug_log("SUITEB: certificate is not signed using ECDSA-SHA256 or ECDSA-SHA384\n");
     512           0 :                                 return gnutls_assert_val(0);
     513             :                         }
     514             : 
     515          11 :                         if (pkalg != GNUTLS_PK_EC) {
     516           0 :                                 _gnutls_debug_log("SUITEB: certificate does not contain ECC parameters\n");
     517           0 :                                 return gnutls_assert_val(0);
     518             :                         }
     519             : 
     520          11 :                         if (issuer_pkalg != GNUTLS_PK_EC) {
     521           5 :                                 _gnutls_debug_log("SUITEB: certificate's issuer does not have ECC parameters\n");
     522           5 :                                 return gnutls_assert_val(0);
     523             :                         }
     524             : 
     525           6 :                         ret = _gnutls_x509_crt_get_mpis(crt, &params);
     526           6 :                         if (ret < 0) {
     527           0 :                                 _gnutls_debug_log("SUITEB: cannot read certificate params\n");
     528           0 :                                 return gnutls_assert_val(0);
     529             :                         }
     530             : 
     531           6 :                         curve = params.curve;
     532           6 :                         gnutls_pk_params_release(&params);
     533             : 
     534           6 :                         if (curve != GNUTLS_ECC_CURVE_SECP256R1 &&
     535             :                                 curve != GNUTLS_ECC_CURVE_SECP384R1) {
     536           0 :                                 _gnutls_debug_log("SUITEB: certificate's ECC params do not contain SECP256R1 or SECP384R1\n");
     537           0 :                                 return gnutls_assert_val(0);
     538             :                         }
     539             : 
     540           6 :                         if (profile == GNUTLS_PROFILE_SUITEB192) {
     541           3 :                                 if (curve != GNUTLS_ECC_CURVE_SECP384R1) {
     542           3 :                                         _gnutls_debug_log("SUITEB192: certificate does not use SECP384R1\n");
     543           3 :                                         return gnutls_assert_val(0);
     544             :                                 }
     545             :                         }
     546             : 
     547           3 :                         if (issuer != NULL) {
     548           3 :                                 if (gnutls_x509_crt_get_version(issuer) != 3) {
     549           0 :                                         _gnutls_debug_log("SUITEB: certificate's issuer uses an unacceptable version number\n");
     550           0 :                                         return gnutls_assert_val(0);
     551             :                                 }
     552             : 
     553           3 :                                 ret = _gnutls_x509_crt_get_mpis(issuer, &params);
     554           3 :                                 if (ret < 0) {
     555           0 :                                         _gnutls_debug_log("SUITEB: cannot read certificate params\n");
     556           0 :                                         return gnutls_assert_val(0);
     557             :                                 }
     558             : 
     559           3 :                                 issuer_curve = params.curve;
     560           3 :                                 gnutls_pk_params_release(&params);
     561             : 
     562           3 :                                 if (issuer_curve != GNUTLS_ECC_CURVE_SECP256R1 &&
     563             :                                         issuer_curve != GNUTLS_ECC_CURVE_SECP384R1) {
     564           0 :                                         _gnutls_debug_log("SUITEB: certificate's issuer ECC params do not contain SECP256R1 or SECP384R1\n");
     565           0 :                                         return gnutls_assert_val(0);
     566             :                                 }
     567             : 
     568           3 :                                 if (issuer_curve < curve) {
     569           0 :                                         _gnutls_debug_log("SUITEB: certificate's issuer ECC params are weaker than the certificate's\n");
     570           0 :                                         return gnutls_assert_val(0);
     571             :                                 }
     572             : 
     573           3 :                                 if (sigalg == GNUTLS_SIGN_ECDSA_SHA256 && 
     574           3 :                                         issuer_curve == GNUTLS_ECC_CURVE_SECP384R1) {
     575           0 :                                         _gnutls_debug_log("SUITEB: certificate is signed with ECDSA-SHA256 when using SECP384R1\n");
     576           0 :                                         return gnutls_assert_val(0);
     577             :                                 }
     578             :                         }
     579             : 
     580             :                         break;
     581           0 :                 case GNUTLS_PROFILE_UNKNOWN: /* already checked; avoid compiler warnings */
     582           0 :                         _gnutls_debug_log("An unknown profile (%d) was encountered\n", (int)profile);
     583             :                 }
     584             :         }
     585             : 
     586             :         return 1;
     587             : }
     588             : 
     589             : typedef struct verify_state_st {
     590             :         time_t now;
     591             :         unsigned int max_path;
     592             :         gnutls_x509_name_constraints_t nc;
     593             :         gnutls_x509_tlsfeatures_t tls_feat;
     594             :         gnutls_verify_output_function *func;
     595             : } verify_state_st;
     596             : 
     597             : #define MARK_INVALID(x) { gnutls_assert(); \
     598             :         out |= (x|GNUTLS_CERT_INVALID); \
     599             :         result = 0; }
     600             : 
     601             : static int _gnutls_x509_verify_data(gnutls_sign_algorithm_t sign,
     602             :                                     const gnutls_datum_t * data,
     603             :                                     const gnutls_datum_t * signature,
     604             :                                     gnutls_x509_crt_t cert,
     605             :                                     gnutls_x509_crt_t issuer,
     606             :                                     unsigned vflags);
     607             : 
     608             : /*
     609             :  * Verifies the given certificate against a certificate list of
     610             :  * trusted CAs.
     611             :  *
     612             :  * Returns only 0 or 1. If 1 it means that the certificate
     613             :  * was successfully verified.
     614             :  *
     615             :  * 'flags': an OR of the gnutls_certificate_verify_flags enumeration.
     616             :  *
     617             :  * Output will hold some extra information about the verification
     618             :  * procedure.
     619             :  */
     620        1678 : static unsigned verify_crt(gnutls_x509_trust_list_t tlist,
     621             :                            gnutls_x509_crt_t cert,
     622             :                            const gnutls_x509_crt_t * trusted_cas,
     623             :                            int tcas_size, unsigned int flags,
     624             :                            unsigned int *output,
     625             :                            verify_state_st *vparams,
     626             :                            unsigned end_cert)
     627             : {
     628        1678 :         gnutls_datum_t cert_signed_data = { NULL, 0 };
     629        1678 :         gnutls_datum_t cert_signature = { NULL, 0 };
     630        1678 :         gnutls_x509_crt_t issuer = NULL;
     631        1678 :         int issuer_version;
     632        1678 :         unsigned result = 1;
     633        1678 :         unsigned int out = 0, usage;
     634        1678 :         int sigalg, ret;
     635        1678 :         const gnutls_sign_entry_st *se;
     636             : 
     637        1678 :         if (output)
     638        1678 :                 *output = 0;
     639             : 
     640        1678 :         if (vparams->max_path == 0) {
     641           9 :                 MARK_INVALID(GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE);
     642             :                 /* bail immediately, to avoid inconistency  */
     643           9 :                 goto cleanup;
     644             :         }
     645        1669 :         vparams->max_path--;
     646             : 
     647        1669 :         if (tcas_size >= 1)
     648        1149 :                 issuer = find_issuer(cert, trusted_cas, tcas_size);
     649             : 
     650        1669 :         if (issuer == NULL && tlist != NULL && tlist->issuer_callback != NULL) {
     651           2 :                 _gnutls_debug_log("Missing issuer callback set.\n");
     652             : 
     653             :                 /* missing issuer is populated by the callback */
     654           2 :                 ret = tlist->issuer_callback(tlist, cert);
     655           2 :                 if (ret < 0) {
     656             :                         /* if the callback fails, continue as though the callback
     657             :                          * wasn't invoked i.e issuer remains NULL */
     658           0 :                         gnutls_assert();
     659           0 :                         issuer = NULL;
     660             :                 }
     661             : 
     662           2 :                 ret = _gnutls_trust_list_get_issuer(tlist, cert, &issuer, 0);
     663           2 :                 if (ret < 0) {
     664           0 :                         gnutls_assert();
     665           0 :                         issuer = NULL;
     666             :                 }
     667             :         }
     668             : 
     669        1669 :         ret =
     670        1669 :             _gnutls_x509_get_signed_data(cert->cert, &cert->der, "tbsCertificate",
     671             :                                          &cert_signed_data);
     672        1669 :         if (ret < 0) {
     673           0 :                 MARK_INVALID(0);
     674           0 :                 cert_signed_data.data = NULL;
     675             :         }
     676             : 
     677        1669 :         ret =
     678        1669 :             _gnutls_x509_get_signature(cert->cert, "signature",
     679             :                                        &cert_signature);
     680        1669 :         if (ret < 0) {
     681          18 :                 MARK_INVALID(0);
     682          18 :                 cert_signature.data = NULL;
     683             :         }
     684             : 
     685        1669 :         ret =
     686        1669 :             _gnutls_x509_get_signature_algorithm(cert->cert,
     687             :                                                  "signatureAlgorithm");
     688        1669 :         if (ret < 0) {
     689           7 :                 MARK_INVALID(0);
     690             :         }
     691        1669 :         sigalg = ret;
     692             : 
     693        1669 :         se = _gnutls_sign_to_entry(sigalg);
     694             : 
     695             :         /* issuer is not in trusted certificate
     696             :          * authorities.
     697             :          */
     698        1669 :         if (issuer == NULL) {
     699         530 :                 MARK_INVALID(GNUTLS_CERT_SIGNER_NOT_FOUND);
     700             :         } else {
     701        1139 :                 if (vparams->nc != NULL) {
     702             :                         /* append the issuer's constraints */
     703        1139 :                         ret = gnutls_x509_crt_get_name_constraints(issuer, vparams->nc,
     704             :                                 GNUTLS_NAME_CONSTRAINTS_FLAG_APPEND, NULL);
     705        1139 :                         if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
     706           0 :                                 MARK_INVALID(GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE);
     707           0 :                                 goto nc_done;
     708             :                         }
     709             : 
     710             :                         /* only check name constraints in server certificates, not CAs */
     711        1139 :                         if (end_cert != 0) {
     712         654 :                                 ret = gnutls_x509_name_constraints_check_crt(vparams->nc, GNUTLS_SAN_DNSNAME, cert);
     713         654 :                                 if (ret == 0) {
     714          18 :                                         MARK_INVALID(GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE);
     715          18 :                                         goto nc_done;
     716             :                                 }
     717             : 
     718         636 :                                 ret = gnutls_x509_name_constraints_check_crt(vparams->nc, GNUTLS_SAN_RFC822NAME, cert);
     719         636 :                                 if (ret == 0) {
     720           4 :                                         MARK_INVALID(GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE);
     721           4 :                                         goto nc_done;
     722             :                                 }
     723             : 
     724         632 :                                 ret = gnutls_x509_name_constraints_check_crt(vparams->nc, GNUTLS_SAN_DN, cert);
     725         632 :                                 if (ret == 0) {
     726           0 :                                         MARK_INVALID(GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE);
     727           0 :                                         goto nc_done;
     728             :                                 }
     729             : 
     730         632 :                                 ret = gnutls_x509_name_constraints_check_crt(vparams->nc, GNUTLS_SAN_URI, cert);
     731         632 :                                 if (ret == 0) {
     732           0 :                                         MARK_INVALID(GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE);
     733           0 :                                         goto nc_done;
     734             :                                 }
     735             : 
     736         632 :                                 ret = gnutls_x509_name_constraints_check_crt(vparams->nc, GNUTLS_SAN_IPADDRESS, cert);
     737         632 :                                 if (ret == 0) {
     738           3 :                                         MARK_INVALID(GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE);
     739           3 :                                         goto nc_done;
     740             :                                 }
     741             :                         }
     742             :                 }
     743             : 
     744        1114 :  nc_done:
     745        1139 :                 if (vparams->tls_feat != NULL) {
     746             :                         /* append the issuer's constraints */
     747        1139 :                         ret = gnutls_x509_crt_get_tlsfeatures(issuer, vparams->tls_feat, GNUTLS_EXT_FLAG_APPEND, NULL);
     748        1139 :                         if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
     749           0 :                                 MARK_INVALID(GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE);
     750           0 :                                 goto feat_done;
     751             :                         }
     752             : 
     753        1139 :                         ret = gnutls_x509_tlsfeatures_check_crt(vparams->tls_feat, cert);
     754        1139 :                         if (ret == 0) {
     755          12 :                                 MARK_INVALID(GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE);
     756          12 :                                 goto feat_done;
     757             :                         }
     758             :                 }
     759             : 
     760        1127 :  feat_done:
     761        1139 :                 issuer_version = gnutls_x509_crt_get_version(issuer);
     762             : 
     763        1139 :                 if (issuer_version < 0) {
     764           0 :                         MARK_INVALID(0);
     765        1139 :                 } else if (!(flags & GNUTLS_VERIFY_DISABLE_CA_SIGN) &&
     766        1139 :                            ((flags & GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT)
     767         699 :                             || issuer_version != 1)) {
     768        1096 :                         if (check_if_ca(cert, issuer, &vparams->max_path, flags) != 1) {
     769          32 :                                 MARK_INVALID(GNUTLS_CERT_SIGNER_NOT_CA);
     770             :                         }
     771             : 
     772        1096 :                         ret =
     773        1096 :                             gnutls_x509_crt_get_key_usage(issuer, &usage, NULL);
     774        1096 :                         if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
     775         938 :                                 if (ret < 0) {
     776           0 :                                         MARK_INVALID(0);
     777         938 :                                 } else if (!(usage & GNUTLS_KEY_KEY_CERT_SIGN)) {
     778           2 :                                         MARK_INVALID(GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE);
     779             :                                 }
     780             :                         }
     781             :                 }
     782             : 
     783        1139 :                 if (sigalg < 0) {
     784           7 :                         MARK_INVALID(0);
     785        1132 :                 } else if (cert_signed_data.data != NULL &&
     786        1132 :                     cert_signature.data != NULL) {
     787        1124 :                         ret =
     788        1124 :                             _gnutls_x509_verify_data(sigalg,
     789             :                                                      &cert_signed_data,
     790             :                                                      &cert_signature,
     791             :                                                      cert,
     792             :                                                      issuer, flags);
     793             : 
     794        1124 :                         if (ret == GNUTLS_E_PK_SIG_VERIFY_FAILED) {
     795          15 :                                 MARK_INVALID(GNUTLS_CERT_SIGNATURE_FAILURE);
     796        1109 :                         } else if (ret == GNUTLS_E_CONSTRAINT_ERROR) {
     797          12 :                                 MARK_INVALID(GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE);
     798        1097 :                         } else if (ret < 0) {
     799          15 :                                 MARK_INVALID(0);
     800             :                         }
     801             :                 }
     802             :         }
     803             : 
     804             :         /* we always check the issuer for unsupported critical extensions */
     805        1669 :         if (issuer && check_for_unknown_exts(issuer) != 0) {
     806          10 :                 if (!(flags & GNUTLS_VERIFY_IGNORE_UNKNOWN_CRIT_EXTENSIONS)) {
     807           6 :                         MARK_INVALID(GNUTLS_CERT_UNKNOWN_CRIT_EXTENSIONS);
     808             :                 }
     809             :         }
     810             : 
     811             :         /* we only check the end-certificate for critical extensions; that
     812             :          * way do not perform this check twice on the certificates when
     813             :          * verifying a large list */
     814        1669 :         if (end_cert && check_for_unknown_exts(cert) != 0) {
     815          15 :                 if (!(flags & GNUTLS_VERIFY_IGNORE_UNKNOWN_CRIT_EXTENSIONS)) {
     816          13 :                         MARK_INVALID(GNUTLS_CERT_UNKNOWN_CRIT_EXTENSIONS);
     817             :                 }
     818             :         }
     819             : 
     820        1669 :         if (sigalg >= 0 && se) {
     821        1662 :                 if (is_level_acceptable(cert, issuer, sigalg, flags) == 0) {
     822          45 :                         MARK_INVALID(GNUTLS_CERT_INSECURE_ALGORITHM);
     823             :                 }
     824             : 
     825             :                 /* If the certificate is not self signed check if the algorithms
     826             :                  * used are secure. If the certificate is self signed it doesn't
     827             :                  * really matter.
     828             :                  */
     829        2159 :                 if (_gnutls_sign_is_secure2(se, GNUTLS_SIGN_FLAG_SECURE_FOR_CERTS) == 0 &&
     830         564 :                     _gnutls_is_broken_sig_allowed(se, flags) == 0 &&
     831          67 :                     is_issuer(cert, cert) == 0) {
     832          63 :                         MARK_INVALID(GNUTLS_CERT_INSECURE_ALGORITHM);
     833             :                 }
     834             :         }
     835             : 
     836             :         /* Check activation/expiration times
     837             :          */
     838        1669 :         if (!(flags & GNUTLS_VERIFY_DISABLE_TIME_CHECKS)) {
     839             :                 /* check the time of the issuer first */
     840        1552 :                 if (issuer != NULL &&
     841        1063 :                     !(flags & GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS)) {
     842        1049 :                         out |= check_time_status(issuer, vparams->now);
     843        1049 :                         if (out != 0) {
     844         129 :                                 gnutls_assert();
     845             :                                 result = 0;
     846             :                         }
     847             :                 }
     848             : 
     849        1552 :                 out |= check_time_status(cert, vparams->now);
     850        1552 :                 if (out != 0) {
     851         659 :                         gnutls_assert();
     852             :                         result = 0;
     853             :                 }
     854             :         }
     855             : 
     856        1010 :       cleanup:
     857        1678 :         if (output)
     858        1678 :                 *output |= out;
     859             : 
     860        1678 :         if (vparams->func) {
     861         276 :                 if (result == 0) {
     862          64 :                         out |= GNUTLS_CERT_INVALID;
     863             :                 }
     864         276 :                 vparams->func(cert, issuer, NULL, out);
     865             :         }
     866        1678 :         _gnutls_free_datum(&cert_signed_data);
     867        1678 :         _gnutls_free_datum(&cert_signature);
     868             : 
     869        1678 :         return result;
     870             : }
     871             : 
     872             : /**
     873             :  * gnutls_x509_crt_check_issuer:
     874             :  * @cert: is the certificate to be checked
     875             :  * @issuer: is the certificate of a possible issuer
     876             :  *
     877             :  * This function will check if the given certificate was issued by the
     878             :  * given issuer. It checks the DN fields and the authority
     879             :  * key identifier and subject key identifier fields match.
     880             :  *
     881             :  * If the same certificate is provided at the @cert and @issuer fields,
     882             :  * it will check whether the certificate is self-signed.
     883             :  *
     884             :  * Returns: It will return true (1) if the given certificate is issued
     885             :  *   by the given issuer, and false (0) if not.  
     886             :  **/
     887             : unsigned
     888        3679 : gnutls_x509_crt_check_issuer(gnutls_x509_crt_t cert,
     889             :                              gnutls_x509_crt_t issuer)
     890             : {
     891        3679 :         return is_issuer(cert, issuer);
     892             : }
     893             : 
     894             : static
     895          40 : unsigned check_ca_sanity(const gnutls_x509_crt_t issuer,
     896             :                          time_t now, unsigned int flags)
     897             : {
     898          40 :         unsigned int status = 0;
     899          40 :         unsigned sigalg;
     900          40 :         int ret;
     901             : 
     902             :         /* explicit time check for trusted CA that we remove from
     903             :          * list. GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS
     904             :          */
     905          40 :         if (!(flags & GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS) &&
     906             :             !(flags & GNUTLS_VERIFY_DISABLE_TIME_CHECKS)) {
     907          33 :                 status |= check_time_status(issuer, now);
     908             :         }
     909             : 
     910          40 :         ret =
     911          40 :             _gnutls_x509_get_signature_algorithm(issuer->cert, "signatureAlgorithm");
     912          40 :         sigalg = ret;
     913             : 
     914             :         /* we explicitly allow CAs which we do not support their self-algorithms
     915             :          * to pass. */
     916          40 :         if (ret >= 0 && !is_level_acceptable(issuer, NULL, sigalg, flags)) {
     917           5 :                 status |= GNUTLS_CERT_INSECURE_ALGORITHM|GNUTLS_CERT_INVALID;
     918             :         }
     919             : 
     920          40 :         return status;
     921             : 
     922             : }
     923             : 
     924             : /* Verify X.509 certificate chain.
     925             :  *
     926             :  * Note that the return value is an OR of GNUTLS_CERT_* elements.
     927             :  *
     928             :  * This function verifies a X.509 certificate list. The certificate
     929             :  * list should lead to a trusted certificate in order to be trusted.
     930             :  */
     931             : unsigned int
     932        1254 : _gnutls_verify_crt_status(gnutls_x509_trust_list_t tlist,
     933             :                           const gnutls_x509_crt_t * certificate_list,
     934             :                           int clist_size,
     935             :                           const gnutls_x509_crt_t * trusted_cas,
     936             :                           int tcas_size,
     937             :                           unsigned int flags,
     938             :                           const char *purpose,
     939             :                           gnutls_verify_output_function func)
     940             : {
     941        1254 :         int i = 0, ret;
     942        1254 :         unsigned int status = 0, output;
     943        1254 :         time_t now = gnutls_time(0);
     944        1254 :         verify_state_st vparams;
     945             : 
     946        1254 :         if (clist_size > 1) {
     947             :                 /* Check if the last certificate in the path is self signed.
     948             :                  * In that case ignore it (a certificate is trusted only if it
     949             :                  * leads to a trusted party by us, not the server's).
     950             :                  *
     951             :                  * This prevents from verifying self signed certificates against
     952             :                  * themselves. This (although not bad) caused verification
     953             :                  * failures on some root self signed certificates that use the
     954             :                  * MD2 algorithm.
     955             :                  */
     956         577 :                 if (gnutls_x509_crt_check_issuer
     957             :                     (certificate_list[clist_size - 1],
     958         577 :                      certificate_list[clist_size - 1]) != 0) {
     959          47 :                         clist_size--;
     960             :                 }
     961             :         }
     962             : 
     963             :         /* We want to shorten the chain by removing the cert that matches
     964             :          * one of the certs we trust and all the certs after that i.e. if
     965             :          * cert chain is A signed-by B signed-by C signed-by D (signed-by
     966             :          * self-signed E but already removed above), and we trust B, remove
     967             :          * B, C and D. */
     968        1254 :         if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_SAME))
     969             :                 i = 0;          /* also replace the first one */
     970             :         else
     971         165 :                 i = 1;          /* do not replace the first one */
     972             : 
     973        3034 :         for (; i < clist_size; i++) {
     974             :                 int j;
     975             : 
     976        2868 :                 for (j = 0; j < tcas_size; j++) {
     977             :                         /* we check for a certificate that may not be identical with the one
     978             :                          * sent by the client, but will have the same name and key. That is
     979             :                          * because it can happen that a CA certificate is upgraded from intermediate
     980             :                          * CA to self-signed CA at some point. */
     981        1112 :                         if (_gnutls_check_if_same_key
     982        1112 :                             (certificate_list[i], trusted_cas[j], i) != 0) {
     983             : 
     984          30 :                                 status |= check_ca_sanity(trusted_cas[j], now, flags);
     985             : 
     986          30 :                                 if (func)
     987           3 :                                         func(certificate_list[i],
     988             :                                              trusted_cas[j], NULL, status);
     989             : 
     990          30 :                                 if (status != 0) {
     991           8 :                                         return gnutls_assert_val(status);
     992             :                                 }
     993             : 
     994             :                                 clist_size = i;
     995             :                                 break;
     996             :                         }
     997             :                 }
     998             :                 /* clist_size may have been changed which gets out of loop */
     999             :         }
    1000             : 
    1001        1248 :         if (clist_size == 0) {
    1002             :                 /* The certificate is already present in the trusted certificate list.
    1003             :                  * Nothing to verify. */
    1004             :                 return status;
    1005             :         }
    1006             : 
    1007        1235 :         memset(&vparams, 0, sizeof(vparams));
    1008        1235 :         vparams.now = now;
    1009        1235 :         vparams.max_path = MAX_VERIFY_DEPTH;
    1010        1235 :         vparams.func = func;
    1011             : 
    1012        1235 :         ret = gnutls_x509_name_constraints_init(&vparams.nc);
    1013        1235 :         if (ret < 0) {
    1014           0 :                 gnutls_assert();
    1015           0 :                 status |= GNUTLS_CERT_INVALID;
    1016           0 :                 return status;
    1017             :         }
    1018             : 
    1019        1235 :         ret = gnutls_x509_tlsfeatures_init(&vparams.tls_feat);
    1020        1235 :         if (ret < 0) {
    1021           0 :                 gnutls_assert();
    1022           0 :                 status |= GNUTLS_CERT_INVALID;
    1023           0 :                 goto cleanup;
    1024             :         }
    1025             : 
    1026             :         /* Verify the last certificate in the certificate path
    1027             :          * against the trusted CA certificate list.
    1028             :          *
    1029             :          * If no CAs are present returns CERT_INVALID. Thus works
    1030             :          * in self signed etc certificates.
    1031             :          */
    1032        1235 :         output = 0;
    1033             : 
    1034        2470 :         ret = verify_crt(tlist,
    1035        1235 :                          certificate_list[clist_size - 1],
    1036             :                          trusted_cas, tcas_size, flags,
    1037             :                          &output,
    1038             :                          &vparams,
    1039             :                          clist_size==1?1:0);
    1040        1235 :         if (ret != 1) {
    1041             :                 /* if the last certificate in the certificate
    1042             :                  * list is invalid, then the certificate is not
    1043             :                  * trusted.
    1044             :                  */
    1045         653 :                 gnutls_assert();
    1046         653 :                 status |= output;
    1047         653 :                 status |= GNUTLS_CERT_INVALID;
    1048         653 :                 goto cleanup;
    1049             :         }
    1050             : 
    1051             :         /* Verify the certificate path (chain)
    1052             :          */
    1053         951 :         for (i = clist_size - 1; i > 0; i--) {
    1054         447 :                 output = 0;
    1055             : 
    1056         447 :                 if (purpose != NULL) {
    1057         111 :                         ret = _gnutls_check_key_purpose(certificate_list[i], purpose, 1);
    1058         111 :                         if (ret != 1) {
    1059           4 :                                 gnutls_assert();
    1060           4 :                                 status |= GNUTLS_CERT_INVALID;
    1061           4 :                                 status |= GNUTLS_CERT_PURPOSE_MISMATCH;
    1062             : 
    1063           4 :                                 if (func)
    1064           0 :                                         func(certificate_list[i-1],
    1065             :                                              certificate_list[i], NULL, status);
    1066           4 :                                 goto cleanup;
    1067             :                         }
    1068             :                 }
    1069             : 
    1070             :                 /* note that here we disable this V1 CA flag. So that no version 1
    1071             :                  * certificates can exist in a supplied chain.
    1072             :                  */
    1073         443 :                 if (!(flags & GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT)) {
    1074         434 :                         flags |= GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT;
    1075             :                 }
    1076             : 
    1077         443 :                 if (!verify_crt(tlist,
    1078         443 :                                 certificate_list[i - 1],
    1079         443 :                                 &certificate_list[i], 1,
    1080             :                                 flags, &output,
    1081             :                                 &vparams,
    1082             :                                 i==1?1:0)) {
    1083          74 :                         gnutls_assert();
    1084          74 :                         status |= output;
    1085          74 :                         status |= GNUTLS_CERT_INVALID;
    1086          74 :                         goto cleanup;
    1087             :                 }
    1088             :         }
    1089             : 
    1090         504 : cleanup:
    1091        1235 :         gnutls_x509_name_constraints_deinit(vparams.nc);
    1092        1235 :         gnutls_x509_tlsfeatures_deinit(vparams.tls_feat);
    1093        1235 :         return status;
    1094             : }
    1095             : 
    1096             : 
    1097             : #define PURPOSE_NSSGC "2.16.840.1.113730.4.1"
    1098             : #define PURPOSE_VSGC "2.16.840.1.113733.1.8.1"
    1099             : 
    1100             : /* Returns true if the provided purpose is in accordance with the certificate.
    1101             :  */
    1102         599 : unsigned _gnutls_check_key_purpose(gnutls_x509_crt_t cert, const char *purpose, unsigned no_any)
    1103             : {
    1104         599 :         char oid[MAX_OID_SIZE];
    1105         599 :         size_t oid_size;
    1106         599 :         int ret;
    1107         599 :         unsigned critical = 0;
    1108         599 :         unsigned check_obsolete_oids = 0;
    1109         599 :         unsigned i;
    1110             : 
    1111             :         /* The check_obsolete_oids hack is because of certain very old CA certificates
    1112             :          * around which instead of having the GNUTLS_KP_TLS_WWW_SERVER have some old
    1113             :          * OIDs for that purpose. Assume these OIDs equal GNUTLS_KP_TLS_WWW_SERVER in
    1114             :          * CA certs */
    1115         599 :         if (strcmp(purpose, GNUTLS_KP_TLS_WWW_SERVER) == 0) {
    1116         542 :                 unsigned ca_status;
    1117         542 :                 ret =
    1118         542 :                     gnutls_x509_crt_get_basic_constraints(cert, NULL, &ca_status,
    1119             :                                                           NULL);
    1120         542 :                 if (ret < 0)
    1121          16 :                         ca_status = 0;
    1122             : 
    1123         542 :                 if (ca_status)
    1124         164 :                         check_obsolete_oids = 1;
    1125             :         }
    1126             : 
    1127         599 :         for (i=0;;i++) {
    1128         623 :                 oid_size = sizeof(oid);
    1129         623 :                 ret = gnutls_x509_crt_get_key_purpose_oid(cert, i, oid, &oid_size, &critical);
    1130         623 :                 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
    1131         305 :                         if (i==0) {
    1132             :                                 /* no key purpose in certificate, assume ANY */
    1133             :                                 return 1;
    1134             :                         } else {
    1135          20 :                                 gnutls_assert();
    1136             :                                 break;
    1137             :                         }
    1138         318 :                 } else if (ret < 0) {
    1139           0 :                         gnutls_assert();
    1140             :                         break;
    1141             :                 }
    1142             : 
    1143         318 :                 if (check_obsolete_oids) {
    1144           7 :                         if (strcmp(oid, PURPOSE_NSSGC) == 0) {
    1145             :                                 return 1;
    1146           6 :                         } else if (strcmp(oid, PURPOSE_VSGC) == 0) {
    1147             :                                 return 1;
    1148             :                         }
    1149             :                 }
    1150             : 
    1151         317 :                 if (strcmp(oid, purpose) == 0 || (no_any == 0 && strcmp(oid, GNUTLS_KP_ANY) == 0)) {
    1152             :                         return 1;
    1153             :                 }
    1154          24 :                 _gnutls_debug_log("looking for key purpose '%s', but have '%s'\n", purpose, oid);
    1155             :         }
    1156             :         return 0;
    1157             : }
    1158             : 
    1159             : #ifdef ENABLE_PKCS11
    1160             : /* Verify X.509 certificate chain using a PKCS #11 token.
    1161             :  *
    1162             :  * Note that the return value is an OR of GNUTLS_CERT_* elements.
    1163             :  *
    1164             :  * Unlike the non-PKCS#11 version, this function accepts a key purpose
    1165             :  * (from GNUTLS_KP_...). That is because in the p11-kit trust modules
    1166             :  * anchors are mixed and get assigned a purpose.
    1167             :  *
    1168             :  * This function verifies a X.509 certificate list. The certificate
    1169             :  * list should lead to a trusted certificate in order to be trusted.
    1170             :  */
    1171             : unsigned int
    1172          86 : _gnutls_pkcs11_verify_crt_status(gnutls_x509_trust_list_t tlist,
    1173             :                                  const char* url,
    1174             :                                  const gnutls_x509_crt_t * certificate_list,
    1175             :                                  unsigned clist_size,
    1176             :                                  const char *purpose,
    1177             :                                  unsigned int flags,
    1178             :                                  gnutls_verify_output_function func)
    1179             : {
    1180          86 :         int ret;
    1181          86 :         unsigned int status = 0, i;
    1182          86 :         gnutls_x509_crt_t issuer = NULL;
    1183          86 :         gnutls_datum_t raw_issuer = {NULL, 0};
    1184          86 :         time_t now = gnutls_time(0);
    1185             : 
    1186          86 :         if (clist_size > 1) {
    1187             :                 /* Check if the last certificate in the path is self signed.
    1188             :                  * In that case ignore it (a certificate is trusted only if it
    1189             :                  * leads to a trusted party by us, not the server's).
    1190             :                  *
    1191             :                  * This prevents from verifying self signed certificates against
    1192             :                  * themselves. This (although not bad) caused verification
    1193             :                  * failures on some root self signed certificates that use the
    1194             :                  * MD2 algorithm.
    1195             :                  */
    1196          59 :                 if (gnutls_x509_crt_check_issuer
    1197             :                     (certificate_list[clist_size - 1],
    1198          59 :                      certificate_list[clist_size - 1]) != 0) {
    1199           0 :                         clist_size--;
    1200             :                 }
    1201             :         }
    1202             : 
    1203             :         /* We want to shorten the chain by removing the cert that matches
    1204             :          * one of the certs we trust and all the certs after that i.e. if
    1205             :          * cert chain is A signed-by B signed-by C signed-by D (signed-by
    1206             :          * self-signed E but already removed above), and we trust B, remove
    1207             :          * B, C and D. */
    1208          86 :         if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_SAME))
    1209             :                 i = 0;          /* also replace the first one */
    1210             :         else
    1211           2 :                 i = 1;          /* do not replace the first one */
    1212             : 
    1213         234 :         for (; i < clist_size; i++) {
    1214         158 :                 unsigned vflags;
    1215         158 :                 gnutls_x509_crt_t trusted_cert;
    1216             : 
    1217         158 :                 if (i == 0) /* in the end certificate do full comparison */
    1218             :                         vflags = GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE|
    1219             :                                 GNUTLS_PKCS11_OBJ_FLAG_COMPARE|GNUTLS_PKCS11_OBJ_FLAG_RETRIEVE_TRUSTED;
    1220             :                 else
    1221          74 :                         vflags = GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE|
    1222             :                                 GNUTLS_PKCS11_OBJ_FLAG_COMPARE_KEY|GNUTLS_PKCS11_OBJ_FLAG_RETRIEVE_TRUSTED;
    1223             : 
    1224         158 :                 if (_gnutls_pkcs11_crt_is_known (url, certificate_list[i], vflags, &trusted_cert) != 0) {
    1225             : 
    1226          10 :                         status |= check_ca_sanity(trusted_cert, now, flags);
    1227             : 
    1228          10 :                         if (func)
    1229           0 :                                 func(trusted_cert,
    1230             :                                      certificate_list[i], NULL, status);
    1231             : 
    1232          10 :                         gnutls_x509_crt_deinit(trusted_cert);
    1233             : 
    1234          10 :                         if (status != 0) {
    1235           2 :                                 return gnutls_assert_val(status);
    1236             :                         }
    1237             : 
    1238           8 :                         clist_size = i;
    1239           8 :                         break;
    1240             :                 }
    1241             :                 /* clist_size may have been changed which gets out of loop */
    1242             :         }
    1243             : 
    1244          84 :         if (clist_size == 0) {
    1245             :                 /* The certificate is already present in the trusted certificate list.
    1246             :                  * Nothing to verify. */
    1247             :                 return status;
    1248             :         }
    1249             : 
    1250             :         /* check for blacklists */
    1251         230 :         for (i = 0; i < clist_size; i++) {
    1252         150 :                 if (gnutls_pkcs11_crt_is_known (url, certificate_list[i], 
    1253             :                         GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE|
    1254             :                         GNUTLS_PKCS11_OBJ_FLAG_RETRIEVE_DISTRUSTED) != 0) {
    1255           0 :                         status |= GNUTLS_CERT_INVALID;
    1256           0 :                         status |= GNUTLS_CERT_REVOKED;
    1257           0 :                         if (func)
    1258           0 :                                 func(certificate_list[i], certificate_list[i], NULL, status);
    1259           0 :                         goto cleanup;
    1260             :                 }
    1261             :         }
    1262             : 
    1263             :         /* check against issuer */
    1264          80 :         ret = gnutls_pkcs11_get_raw_issuer(url, certificate_list[clist_size - 1],
    1265             :                                            &raw_issuer, GNUTLS_X509_FMT_DER,
    1266             :                                            GNUTLS_PKCS11_OBJ_FLAG_OVERWRITE_TRUSTMOD_EXT|GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE);
    1267          80 :         if (ret < 0) {
    1268           2 :                 gnutls_assert();
    1269           2 :                 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE && clist_size > 2) {
    1270             : 
    1271             :                         /* check if the last certificate in the chain is present
    1272             :                          * in our trusted list, and if yes, verify against it. */
    1273           0 :                         ret = gnutls_pkcs11_crt_is_known(url, certificate_list[clist_size - 1],
    1274             :                                 GNUTLS_PKCS11_OBJ_FLAG_RETRIEVE_TRUSTED|GNUTLS_PKCS11_OBJ_FLAG_COMPARE);
    1275           0 :                         if (ret != 0) {
    1276           0 :                                 return _gnutls_verify_crt_status(tlist,
    1277             :                                                 certificate_list, clist_size,
    1278             :                                                 &certificate_list[clist_size - 1],
    1279             :                                                 1, flags, purpose, func);
    1280             :                         }
    1281             :                 }
    1282             : 
    1283           2 :                 status |= GNUTLS_CERT_INVALID;
    1284           2 :                 status |= GNUTLS_CERT_SIGNER_NOT_FOUND;
    1285             :                 /* verify the certificate list against 0 trusted CAs in order
    1286             :                  * to get, any additional flags from the certificate list (e.g.,
    1287             :                  * insecure algorithms or expired */
    1288           2 :                 status |= _gnutls_verify_crt_status(tlist, certificate_list, clist_size,
    1289             :                                                     NULL, 0, flags, purpose, func);
    1290           2 :                 goto cleanup;
    1291             :         }
    1292             : 
    1293          78 :         ret = gnutls_x509_crt_init(&issuer);
    1294          78 :         if (ret < 0) {
    1295           0 :                 gnutls_assert();
    1296           0 :                 status |= GNUTLS_CERT_INVALID;
    1297           0 :                 status |= GNUTLS_CERT_SIGNER_NOT_FOUND;
    1298           0 :                 goto cleanup;
    1299             :         }
    1300             : 
    1301          78 :         ret = gnutls_x509_crt_import(issuer, &raw_issuer, GNUTLS_X509_FMT_DER);
    1302          78 :         if (ret < 0) {
    1303           0 :                 gnutls_assert();
    1304           0 :                 status |= GNUTLS_CERT_INVALID;
    1305           0 :                 status |= GNUTLS_CERT_SIGNER_NOT_FOUND;
    1306           0 :                 goto cleanup;
    1307             :         }
    1308             : 
    1309             :         /* check if the raw issuer is blacklisted (it can happen if
    1310             :          * the issuer is both in the trusted list and the blacklisted)
    1311             :          */
    1312          78 :         if (gnutls_pkcs11_crt_is_known (url, issuer,
    1313             :                 GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE|
    1314             :                 GNUTLS_PKCS11_OBJ_FLAG_RETRIEVE_DISTRUSTED) != 0) {
    1315           0 :                 status |= GNUTLS_CERT_INVALID;
    1316           0 :                 status |= GNUTLS_CERT_SIGNER_NOT_FOUND; /* if the signer is revoked - it is as if it doesn't exist */
    1317           0 :                 goto cleanup;
    1318             :         }
    1319             : 
    1320             :         /* security modules that provide trust, bundle all certificates (of all purposes)
    1321             :          * together. In software that doesn't specify any purpose assume the default to
    1322             :          * be www-server. */
    1323         147 :         ret = _gnutls_check_key_purpose(issuer, purpose==NULL?GNUTLS_KP_TLS_WWW_SERVER:purpose, 0);
    1324          78 :         if (ret != 1) {
    1325           0 :                 gnutls_assert();
    1326           0 :                 status |= GNUTLS_CERT_INVALID;
    1327           0 :                 status |= GNUTLS_CERT_SIGNER_NOT_FOUND;
    1328           0 :                 goto cleanup;
    1329             :         }
    1330             : 
    1331          78 :         status = _gnutls_verify_crt_status(tlist, certificate_list, clist_size,
    1332             :                                            &issuer, 1, flags, purpose, func);
    1333             : 
    1334          80 : cleanup:
    1335          80 :         gnutls_free(raw_issuer.data);
    1336          80 :         if (issuer != NULL)
    1337          78 :                 gnutls_x509_crt_deinit(issuer);
    1338             : 
    1339             :         return status;
    1340             : }
    1341             : #endif
    1342             : 
    1343             : static int
    1344        1124 : _gnutls_x509_validate_sign_params(gnutls_pk_algorithm_t pk_algorithm,
    1345             :                                   ASN1_TYPE cert,
    1346             :                                   const char *name,
    1347             :                                   gnutls_x509_spki_st *sig_params)
    1348             : {
    1349             :         /* The signature parameter validation is only needed for RSA-PSS */
    1350        1124 :         if (pk_algorithm == GNUTLS_PK_RSA_PSS) {
    1351          58 :                 int result;
    1352          58 :                 gnutls_x509_spki_st params;
    1353             : 
    1354          58 :                 result = _gnutls_x509_read_sign_params(cert, name, &params);
    1355          58 :                 if (result < 0) {
    1356             :                         /* If parameters field is absent, no parameter
    1357             :                          * validation is needed */
    1358          15 :                         if (result != GNUTLS_E_ASN1_ELEMENT_NOT_FOUND &&
    1359          15 :                             result != GNUTLS_E_ASN1_VALUE_NOT_FOUND) {
    1360           0 :                                 gnutls_assert();
    1361           6 :                                 return result;
    1362             :                         }
    1363             :                 } else {
    1364             :                         /* Check if the underlying hash algorithms are same.  */
    1365          43 :                         if (sig_params->rsa_pss_dig != params.rsa_pss_dig) {
    1366           3 :                                 gnutls_assert();
    1367           3 :                                 return GNUTLS_E_CONSTRAINT_ERROR;
    1368             :                         }
    1369             : 
    1370             :                         /* The salt length used to generate the
    1371             :                          * signature must be equal to or larger than
    1372             :                          * the one in the key parameter. */
    1373          40 :                         if (sig_params->salt_size < params.salt_size) {
    1374           3 :                                 gnutls_assert();
    1375           3 :                                 return GNUTLS_E_CONSTRAINT_ERROR;
    1376             :                         }
    1377             :                 }
    1378             :         }
    1379             :         return 0;
    1380             : }
    1381             : 
    1382             : /* verifies if the certificate is properly signed.
    1383             :  * returns GNUTLS_E_PK_VERIFY_SIG_FAILED on failure and 1 on success.
    1384             :  * 
    1385             :  * 'data' is the signed data
    1386             :  * 'signature' is the signature!
    1387             :  */
    1388             : static int
    1389        1135 : _gnutls_x509_verify_data(gnutls_sign_algorithm_t sign,
    1390             :                          const gnutls_datum_t * data,
    1391             :                          const gnutls_datum_t * signature,
    1392             :                          gnutls_x509_crt_t cert,
    1393             :                          gnutls_x509_crt_t issuer,
    1394             :                          unsigned vflags)
    1395             : {
    1396        1135 :         gnutls_pk_params_st params;
    1397        1135 :         gnutls_pk_algorithm_t issuer_pk;
    1398        1135 :         int ret;
    1399        1135 :         gnutls_x509_spki_st sign_params;
    1400        1135 :         const gnutls_sign_entry_st *se;
    1401             : 
    1402             :         /* Read the MPI parameters from the issuer's certificate.
    1403             :          */
    1404        1135 :         ret = _gnutls_x509_crt_get_mpis(issuer, &params);
    1405        1135 :         if (ret < 0) {
    1406           0 :                 gnutls_assert();
    1407           0 :                 return ret;
    1408             :         }
    1409             : 
    1410        1135 :         issuer_pk = gnutls_x509_crt_get_pk_algorithm(issuer, NULL);
    1411             : 
    1412        1135 :         se = _gnutls_sign_to_entry(sign);
    1413        1135 :         if (se == NULL)
    1414           0 :                 return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM);
    1415             : 
    1416        1135 :         if (cert != NULL) {
    1417        1124 :                 ret = _gnutls_x509_read_sign_params(cert->cert,
    1418             :                                                     "signatureAlgorithm",
    1419             :                                                     &sign_params);
    1420        1124 :                 if (ret < 0) {
    1421           0 :                         gnutls_assert();
    1422           0 :                         goto cleanup;
    1423             :                 }
    1424             : 
    1425        1124 :                 ret = _gnutls_x509_validate_sign_params(issuer_pk,
    1426             :                                                         issuer->cert,
    1427             :                                                         "tbsCertificate."
    1428             :                                                         "subjectPublicKeyInfo."
    1429             :                                                         "algorithm",
    1430             :                                                         &sign_params);
    1431        1124 :                 if (ret < 0) {
    1432           6 :                         gnutls_assert();
    1433           6 :                         goto cleanup;
    1434             :                 }
    1435             :         } else {
    1436          11 :                 memcpy(&sign_params, &params.spki,
    1437             :                        sizeof(gnutls_x509_spki_st));
    1438             : 
    1439          11 :                 sign_params.pk = se->pk;
    1440          11 :                 if (sign_params.pk == GNUTLS_PK_RSA_PSS)
    1441           3 :                         sign_params.rsa_pss_dig = se->hash;
    1442             :         }
    1443             : 
    1444        1129 :         ret = pubkey_verify_data(se, hash_to_entry(se->hash), data, signature, &params,
    1445             :                                  &sign_params, vflags);
    1446        1129 :         if (ret < 0) {
    1447          38 :                 gnutls_assert();
    1448             :         }
    1449             : 
    1450        1129 :  cleanup:
    1451             :         /* release all allocated MPIs
    1452             :          */
    1453        1135 :         gnutls_pk_params_release(&params);
    1454             : 
    1455        1135 :         return ret;
    1456             : }
    1457             : 
    1458             : /**
    1459             :  * gnutls_x509_crt_list_verify:
    1460             :  * @cert_list: is the certificate list to be verified
    1461             :  * @cert_list_length: holds the number of certificate in cert_list
    1462             :  * @CA_list: is the CA list which will be used in verification
    1463             :  * @CA_list_length: holds the number of CA certificate in CA_list
    1464             :  * @CRL_list: holds a list of CRLs.
    1465             :  * @CRL_list_length: the length of CRL list.
    1466             :  * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
    1467             :  * @verify: will hold the certificate verification output.
    1468             :  *
    1469             :  *
    1470             :  * This function will try to verify the given certificate list and
    1471             :  * return its status. The details of the verification are the same
    1472             :  * as in gnutls_x509_trust_list_verify_crt2().
    1473             :  *
    1474             :  * You must check the peer's name in order to check if the verified
    1475             :  * certificate belongs to the actual peer.
    1476             :  *
    1477             :  * The certificate verification output will be put in @verify and will
    1478             :  * be one or more of the gnutls_certificate_status_t enumerated
    1479             :  * elements bitwise or'd.  For a more detailed verification status use
    1480             :  * gnutls_x509_crt_verify() per list element.
    1481             :  *
    1482             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
    1483             :  *   negative error value.
    1484             :  **/
    1485             : int
    1486          98 : gnutls_x509_crt_list_verify(const gnutls_x509_crt_t * cert_list,
    1487             :                             unsigned cert_list_length,
    1488             :                             const gnutls_x509_crt_t * CA_list,
    1489             :                             unsigned CA_list_length,
    1490             :                             const gnutls_x509_crl_t * CRL_list,
    1491             :                             unsigned CRL_list_length, unsigned int flags,
    1492             :                             unsigned int *verify)
    1493             : {
    1494          98 :         unsigned i;
    1495          98 :         int ret;
    1496          98 :         gnutls_x509_trust_list_t tlist;
    1497             : 
    1498          98 :         if (cert_list == NULL || cert_list_length == 0)
    1499             :                 return GNUTLS_E_NO_CERTIFICATE_FOUND;
    1500             : 
    1501          98 :         gnutls_x509_trust_list_init(&tlist, 0);
    1502             : 
    1503             :         /* Verify certificate
    1504             :          */
    1505          98 :         *verify = _gnutls_verify_crt_status(tlist, cert_list, cert_list_length,
    1506             :                                             CA_list, CA_list_length,
    1507             :                                             flags, NULL, NULL);
    1508             : 
    1509             :         /* Check for revoked certificates in the chain.
    1510             :          */
    1511         308 :         for (i = 0; i < cert_list_length; i++) {
    1512         210 :                 ret = gnutls_x509_crt_check_revocation(cert_list[i],
    1513             :                                                        CRL_list,
    1514             :                                                        CRL_list_length);
    1515         210 :                 if (ret == 1) { /* revoked */
    1516           0 :                         *verify |= GNUTLS_CERT_REVOKED;
    1517           0 :                         *verify |= GNUTLS_CERT_INVALID;
    1518             :                 }
    1519             :         }
    1520             : 
    1521          98 :         gnutls_x509_trust_list_deinit(tlist, 0);
    1522          98 :         return 0;
    1523             : }
    1524             : 
    1525             : /**
    1526             :  * gnutls_x509_crt_verify:
    1527             :  * @cert: is the certificate to be verified
    1528             :  * @CA_list: is one certificate that is considered to be trusted one
    1529             :  * @CA_list_length: holds the number of CA certificate in CA_list
    1530             :  * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
    1531             :  * @verify: will hold the certificate verification output.
    1532             :  *
    1533             :  * This function will try to verify the given certificate and return
    1534             :  * its status. Note that a verification error does not imply a negative
    1535             :  * return status. In that case the @verify status is set.
    1536             :  *
    1537             :  * The details of the verification are the same
    1538             :  * as in gnutls_x509_trust_list_verify_crt2().
    1539             :  *
    1540             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
    1541             :  *   negative error value.
    1542             :  **/
    1543             : int
    1544          21 : gnutls_x509_crt_verify(gnutls_x509_crt_t cert,
    1545             :                        const gnutls_x509_crt_t * CA_list,
    1546             :                        unsigned CA_list_length, unsigned int flags,
    1547             :                        unsigned int *verify)
    1548             : {
    1549          21 :         gnutls_x509_trust_list_t tlist;
    1550             : 
    1551          21 :         gnutls_x509_trust_list_init(&tlist, 0);
    1552             : 
    1553             :         /* Verify certificate
    1554             :          */
    1555          21 :         *verify = _gnutls_verify_crt_status(tlist, &cert, 1,
    1556             :                                             CA_list, CA_list_length,
    1557             :                                             flags, NULL, NULL);
    1558             : 
    1559          21 :         gnutls_x509_trust_list_deinit(tlist, 0);
    1560          21 :         return 0;
    1561             : }
    1562             : 
    1563             : /**
    1564             :  * gnutls_x509_crl_check_issuer:
    1565             :  * @crl: is the CRL to be checked
    1566             :  * @issuer: is the certificate of a possible issuer
    1567             :  *
    1568             :  * This function will check if the given CRL was issued by the given
    1569             :  * issuer certificate.
    1570             :  *
    1571             :  * Returns: true (1) if the given CRL was issued by the given issuer,
    1572             :  * and false (0) if not.
    1573             :  **/
    1574             : unsigned
    1575           0 : gnutls_x509_crl_check_issuer(gnutls_x509_crl_t crl,
    1576             :                              gnutls_x509_crt_t issuer)
    1577             : {
    1578           0 :         return is_crl_issuer(crl, issuer);
    1579             : }
    1580             : 
    1581             : static inline gnutls_x509_crt_t
    1582          12 : find_crl_issuer(gnutls_x509_crl_t crl,
    1583             :                 const gnutls_x509_crt_t * trusted_cas, int tcas_size)
    1584             : {
    1585          12 :         int i;
    1586             : 
    1587             :         /* this is serial search. 
    1588             :          */
    1589             : 
    1590          13 :         for (i = 0; i < tcas_size; i++) {
    1591          12 :                 if (is_crl_issuer(crl, trusted_cas[i]) != 0)
    1592          11 :                         return trusted_cas[i];
    1593             :         }
    1594             : 
    1595           1 :         gnutls_assert();
    1596             :         return NULL;
    1597             : }
    1598             : 
    1599             : /**
    1600             :  * gnutls_x509_crl_verify:
    1601             :  * @crl: is the crl to be verified
    1602             :  * @trusted_cas: is a certificate list that is considered to be trusted one
    1603             :  * @tcas_size: holds the number of CA certificates in CA_list
    1604             :  * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
    1605             :  * @verify: will hold the crl verification output.
    1606             :  *
    1607             :  * This function will try to verify the given crl and return its verification status.
    1608             :  * See gnutls_x509_crt_list_verify() for a detailed description of
    1609             :  * return values. Note that since GnuTLS 3.1.4 this function includes
    1610             :  * the time checks.
    1611             :  *
    1612             :  * Note that value in @verify is set only when the return value of this 
    1613             :  * function is success (i.e, failure to trust a CRL a certificate does not imply 
    1614             :  * a negative return value).
    1615             :  *
    1616             :  * Before GnuTLS 3.5.7 this function would return zero or a positive
    1617             :  * number on success.
    1618             :  *
    1619             :  * Returns: On success, %GNUTLS_E_SUCCESS (0), otherwise a
    1620             :  *   negative error value.
    1621             :  **/
    1622             : int
    1623          13 : gnutls_x509_crl_verify(gnutls_x509_crl_t crl,
    1624             :                        const gnutls_x509_crt_t * trusted_cas,
    1625             :                        unsigned tcas_size, unsigned int flags,
    1626             :                        unsigned int *verify)
    1627             : {
    1628             : /* CRL is ignored for now */
    1629          13 :         gnutls_datum_t crl_signed_data = { NULL, 0 };
    1630          13 :         gnutls_datum_t crl_signature = { NULL, 0 };
    1631          13 :         gnutls_x509_crt_t issuer = NULL;
    1632          13 :         int result, sigalg;
    1633          13 :         time_t now = gnutls_time(0);
    1634          13 :         time_t nextu;
    1635          13 :         unsigned int usage;
    1636             : 
    1637          13 :         if (verify)
    1638          13 :                 *verify = 0;
    1639             : 
    1640          13 :         if (tcas_size >= 1)
    1641          12 :                 issuer = find_crl_issuer(crl, trusted_cas, tcas_size);
    1642             : 
    1643          13 :         result =
    1644          13 :             _gnutls_x509_get_signed_data(crl->crl, &crl->der, "tbsCertList",
    1645             :                                          &crl_signed_data);
    1646          13 :         if (result < 0) {
    1647           0 :                 gnutls_assert();
    1648           0 :                 if (verify)
    1649           0 :                         *verify |= GNUTLS_CERT_INVALID;
    1650           0 :                 goto cleanup;
    1651             :         }
    1652             : 
    1653          13 :         result =
    1654          13 :             _gnutls_x509_get_signature(crl->crl, "signature",
    1655             :                                        &crl_signature);
    1656          13 :         if (result < 0) {
    1657           0 :                 gnutls_assert();
    1658           0 :                 if (verify)
    1659           0 :                         *verify |= GNUTLS_CERT_INVALID;
    1660           0 :                 goto cleanup;
    1661             :         }
    1662             : 
    1663          13 :         sigalg =
    1664          13 :             _gnutls_x509_get_signature_algorithm(crl->crl,
    1665             :                                                  "signatureAlgorithm");
    1666          13 :         if (sigalg < 0) {
    1667           0 :                 gnutls_assert();
    1668           0 :                 if (verify)
    1669           0 :                         *verify |= GNUTLS_CERT_INVALID;
    1670           0 :                 goto cleanup;
    1671             :         }
    1672             : 
    1673             :         /* issuer is not in trusted certificate
    1674             :          * authorities.
    1675             :          */
    1676          13 :         if (issuer == NULL) {
    1677           2 :                 gnutls_assert();
    1678           2 :                 if (verify)
    1679           2 :                         *verify |=
    1680             :                             GNUTLS_CERT_SIGNER_NOT_FOUND |
    1681             :                             GNUTLS_CERT_INVALID;
    1682             :         } else {
    1683          11 :                 if (!(flags & GNUTLS_VERIFY_DISABLE_CA_SIGN)) {
    1684          11 :                         if (gnutls_x509_crt_get_ca_status(issuer, NULL) != 1) {
    1685           0 :                                 gnutls_assert();
    1686           0 :                                 if (verify)
    1687           0 :                                         *verify |=
    1688             :                                             GNUTLS_CERT_SIGNER_NOT_CA |
    1689             :                                             GNUTLS_CERT_INVALID;
    1690             :                         }
    1691             : 
    1692          11 :                         result =
    1693          11 :                             gnutls_x509_crt_get_key_usage(issuer, &usage, NULL);
    1694          11 :                         if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
    1695          11 :                                 if (result < 0) {
    1696           0 :                                         gnutls_assert();
    1697           0 :                                         if (verify)
    1698           0 :                                                 *verify |= GNUTLS_CERT_INVALID;
    1699          11 :                                 } else if (!(usage & GNUTLS_KEY_CRL_SIGN)) {
    1700           4 :                                         gnutls_assert();
    1701           4 :                                         if (verify)
    1702           4 :                                                 *verify |=
    1703             :                                                     GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE
    1704             :                                                     | GNUTLS_CERT_INVALID;
    1705             :                                 }
    1706             :                         }
    1707             :                 }
    1708             : 
    1709          11 :                 result =
    1710          11 :                     _gnutls_x509_verify_data(sigalg,
    1711             :                                              &crl_signed_data, &crl_signature,
    1712             :                                              NULL,
    1713             :                                              issuer, flags);
    1714          11 :                 if (result == GNUTLS_E_PK_SIG_VERIFY_FAILED) {
    1715           2 :                         gnutls_assert();
    1716             :                         /* error. ignore it */
    1717           2 :                         if (verify)
    1718           2 :                                 *verify |= GNUTLS_CERT_SIGNATURE_FAILURE;
    1719             :                         result = 0;
    1720           9 :                 } else if (result == GNUTLS_E_CONSTRAINT_ERROR) {
    1721           0 :                         if (verify)
    1722           0 :                                 *verify |= GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE;
    1723             :                         result = 0;
    1724           9 :                 } else if (result < 0) {
    1725           0 :                         gnutls_assert();
    1726           0 :                         if (verify)
    1727           0 :                                 *verify |= GNUTLS_CERT_INVALID;
    1728           0 :                         goto cleanup;
    1729             :                 } else if (result >= 0) {
    1730             :                         result = 0; /* everything ok */
    1731             :                 }
    1732             :         }
    1733             : 
    1734             :         {
    1735          13 :                 sigalg = gnutls_x509_crl_get_signature_algorithm(crl);
    1736             : 
    1737          13 :                 if (((sigalg == GNUTLS_SIGN_RSA_MD2) &&
    1738          13 :                      !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2)) ||
    1739           0 :                     ((sigalg == GNUTLS_SIGN_RSA_MD5) &&
    1740           0 :                      !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5))) {
    1741           0 :                         if (verify)
    1742           0 :                                 *verify |= GNUTLS_CERT_INSECURE_ALGORITHM;
    1743             :                         result = 0;
    1744             :                 }
    1745             :         }
    1746             : 
    1747          13 :         if (gnutls_x509_crl_get_this_update(crl) > now && verify)
    1748           0 :                 *verify |= GNUTLS_CERT_REVOCATION_DATA_ISSUED_IN_FUTURE;
    1749             : 
    1750          13 :         nextu = gnutls_x509_crl_get_next_update(crl);
    1751          13 :         if (nextu != -1 && nextu < now && verify)
    1752           0 :                 *verify |= GNUTLS_CERT_REVOCATION_DATA_SUPERSEDED;
    1753             : 
    1754             : 
    1755          13 :       cleanup:
    1756          13 :         if (verify && *verify != 0)
    1757           8 :                 *verify |= GNUTLS_CERT_INVALID;
    1758             : 
    1759          13 :         _gnutls_free_datum(&crl_signed_data);
    1760          13 :         _gnutls_free_datum(&crl_signature);
    1761             : 
    1762          13 :         return result;
    1763             : }

Generated by: LCOV version 1.14