LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib/x509 - tls_features.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 61 76 80.3 %
Date: 2020-10-30 04:50:48 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2003-2016 Free Software Foundation, Inc.
       3             :  *
       4             :  * Authors: Nikos Mavrogiannopoulos, Simon Josefsson, Howard Chu
       5             :  *
       6             :  * This file is part of GnuTLS.
       7             :  *
       8             :  * The GnuTLS is free software; you can redistribute it and/or
       9             :  * modify it under the terms of the GNU Lesser General Public License
      10             :  * as published by the Free Software Foundation; either version 2.1 of
      11             :  * the License, or (at your option) any later version.
      12             :  *
      13             :  * This library is distributed in the hope that it will be useful, but
      14             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :  * Lesser General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU Lesser General Public License
      19             :  * along with this program.  If not, see <https://www.gnu.org/licenses/>
      20             :  *
      21             :  */
      22             : 
      23             : #include "gnutls_int.h"
      24             : #include <datum.h>
      25             : #include <global.h>
      26             : #include "errors.h"
      27             : #include <common.h>
      28             : #include <gnutls/x509-ext.h>
      29             : #include <x509.h>
      30             : #include <x509_b64.h>
      31             : #include <x509_int.h>
      32             : #include <libtasn1.h>
      33             : #include <pk.h>
      34             : #include <pkcs11_int.h>
      35             : #include "urls.h"
      36             : 
      37             : /**
      38             :  * gnutls_x509_tlsfeatures_init:
      39             :  * @f: The TLS features
      40             :  *
      41             :  * This function will initialize a X.509 TLS features extension structure
      42             :  *
      43             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
      44             :  *   otherwise a negative error value.
      45             :  *
      46             :  * Since: 3.5.1
      47             :  **/
      48        1879 : int gnutls_x509_tlsfeatures_init(gnutls_x509_tlsfeatures_t *f)
      49             : {
      50        1879 :         *f = gnutls_calloc(1, sizeof(struct gnutls_x509_tlsfeatures_st));
      51        1879 :         if (*f == NULL)
      52           0 :                 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
      53             : 
      54             :         return 0;
      55             : }
      56             : 
      57             : /**
      58             :  * gnutls_x509_tlsfeatures_deinit:
      59             :  * @f: The TLS features
      60             :  *
      61             :  * This function will deinitialize a X.509 TLS features extension structure
      62             :  *
      63             :  * Since: 3.5.1
      64             :  **/
      65        1879 : void gnutls_x509_tlsfeatures_deinit(gnutls_x509_tlsfeatures_t f)
      66             : {
      67        1879 :         gnutls_free(f);
      68        1879 : }
      69             : 
      70             : /**
      71             :  * gnutls_x509_tlsfeatures_get:
      72             :  * @f: The TLS features
      73             :  * @idx: The index of the feature to get
      74             :  * @feature: If the function succeeds, the feature will be stored in this variable
      75             :  *
      76             :  * This function will get a feature from the X.509 TLS features
      77             :  * extension structure.
      78             :  *
      79             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
      80             :  *   otherwise a negative error value.
      81             :  *
      82             :  * Since: 3.5.1
      83             :  **/
      84          40 : int gnutls_x509_tlsfeatures_get(gnutls_x509_tlsfeatures_t f, unsigned idx, unsigned int *feature)
      85             : {
      86          40 :         if (f == NULL) {
      87           0 :                 gnutls_assert();
      88           0 :                 return GNUTLS_E_INVALID_REQUEST;
      89             :         }
      90             : 
      91          40 :         if (idx >= f->size) {
      92          12 :                 return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
      93             :         }
      94             : 
      95          29 :         *feature = f->feature[idx];
      96          29 :         return 0;
      97             : }
      98             : 
      99             : /**
     100             :  * gnutls_x509_crt_get_tlsfeatures:
     101             :  * @crt: A X.509 certificate
     102             :  * @features: If the function succeeds, the
     103             :  *   features will be stored in this variable.
     104             :  * @flags: zero or %GNUTLS_EXT_FLAG_APPEND
     105             :  * @critical: the extension status
     106             :  *
     107             :  * This function will get the X.509 TLS features
     108             :  * extension structure from the certificate. The
     109             :  * returned structure needs to be freed using
     110             :  * gnutls_x509_tlsfeatures_deinit().
     111             :  *
     112             :  * When the @flags is set to %GNUTLS_EXT_FLAG_APPEND,
     113             :  * then if the @features structure is empty this function will behave
     114             :  * identically as if the flag was not set. Otherwise if there are elements 
     115             :  * in the @features structure then they will be merged with.
     116             :  *
     117             :  * Note that @features must be initialized prior to calling this function.
     118             :  *
     119             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
     120             :  *   otherwise a negative error value.
     121             :  *
     122             :  * Since: 3.5.1
     123             :  **/
     124        1762 : int gnutls_x509_crt_get_tlsfeatures(gnutls_x509_crt_t crt,
     125             :                                     gnutls_x509_tlsfeatures_t features,
     126             :                                     unsigned int flags,
     127             :                                     unsigned int *critical)
     128             : {
     129        1762 :         int ret;
     130        1762 :         gnutls_datum_t der;
     131             : 
     132        1762 :         if (crt == NULL) {
     133           0 :                 gnutls_assert();
     134           0 :                 return GNUTLS_E_INVALID_REQUEST;
     135             :         }
     136             : 
     137        3524 :         if ((ret =
     138        1762 :                  _gnutls_x509_crt_get_extension(crt, GNUTLS_X509EXT_OID_TLSFEATURES, 0,
     139             :                                                 &der, critical)) < 0)
     140             :         {
     141             :                 return ret;
     142             :         }
     143             : 
     144          61 :         if (der.size == 0 || der.data == NULL) {
     145           0 :                 gnutls_assert();
     146           0 :                 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
     147             :         }
     148             : 
     149          61 :         ret = gnutls_x509_ext_import_tlsfeatures(&der, features, flags);
     150          61 :         if (ret < 0) {
     151           0 :                 gnutls_assert();
     152           0 :                 goto cleanup;
     153             :         }
     154             : 
     155             :         ret = 0;
     156          61 :  cleanup:
     157          61 :         gnutls_free(der.data);
     158          61 :         return ret;
     159             : }
     160             : 
     161             : /**
     162             :  * gnutls_x509_crt_set_tlsfeatures:
     163             :  * @crt: A X.509 certificate
     164             :  * @features: If the function succeeds, the
     165             :  *   features will be added to the certificate.
     166             :  *
     167             :  * This function will set the certificates
     168             :  * X.509 TLS extension from the given structure.
     169             :  *
     170             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
     171             :  *   otherwise a negative error value.
     172             :  *
     173             :  * Since: 3.5.1
     174             :  **/
     175           2 : int gnutls_x509_crt_set_tlsfeatures(gnutls_x509_crt_t crt,
     176             :                                     gnutls_x509_tlsfeatures_t features)
     177             : {
     178           2 :         int ret;
     179           2 :         gnutls_datum_t der;
     180             : 
     181           2 :         if (crt == NULL || features == NULL) {
     182           0 :                 gnutls_assert();
     183           0 :                 return GNUTLS_E_INVALID_REQUEST;
     184             :         }
     185             : 
     186           2 :         ret = gnutls_x509_ext_export_tlsfeatures(features, &der);
     187           2 :         if (ret < 0) {
     188           0 :                 gnutls_assert();
     189           0 :                 return ret;
     190             :         }
     191             : 
     192           2 :         ret = _gnutls_x509_crt_set_extension(crt, GNUTLS_X509EXT_OID_TLSFEATURES, &der, 0);
     193             : 
     194           2 :         _gnutls_free_datum(&der);
     195             : 
     196           2 :         if (ret < 0) {
     197           0 :                 gnutls_assert();
     198             :         }
     199             : 
     200             :         return ret;
     201             : }
     202             : 
     203             : /**
     204             :  * gnutls_x509_tls_features_check_crt:
     205             :  * @feat: a set of TLSFeatures
     206             :  * @cert: the certificate to be checked
     207             :  *
     208             :  * This function will check the provided certificate against the TLSFeatures
     209             :  * set in @feat using the RFC7633 p.4.2.2 rules. It will check whether the certificate
     210             :  * contains the features in @feat or a superset.
     211             :  *
     212             :  * Returns: non-zero if the provided certificate complies, and zero otherwise.
     213             :  *
     214             :  * Since: 3.5.1
     215             :  **/
     216        1143 : unsigned gnutls_x509_tlsfeatures_check_crt(gnutls_x509_tlsfeatures_t feat,
     217             :                                            gnutls_x509_crt_t cert)
     218             : {
     219        1143 :         int ret;
     220        1143 :         gnutls_x509_tlsfeatures_t cfeat;
     221        1143 :         unsigned i, j, uret, found;
     222             : 
     223        1143 :         if (feat->size == 0)
     224             :                 return 1; /* shortcut; no constraints to check */
     225             : 
     226          31 :         ret = gnutls_x509_tlsfeatures_init(&cfeat);
     227          31 :         if (ret < 0)
     228           0 :                 return gnutls_assert_val(0);
     229             : 
     230          31 :         ret = gnutls_x509_crt_get_tlsfeatures(cert, cfeat, 0, NULL);
     231          31 :         if (ret < 0) {
     232           6 :                 gnutls_assert();
     233           6 :                 uret = 0;
     234           6 :                 goto cleanup;
     235             :         }
     236             : 
     237             :         /* if cert's features cannot be a superset */
     238          25 :         if (feat->size > cfeat->size) {
     239           8 :                 _gnutls_debug_log("certificate has %u, while issuer has %u tlsfeatures\n", cfeat->size, feat->size);
     240           8 :                 gnutls_assert();
     241           8 :                 uret = 0;
     242           8 :                 goto cleanup;
     243             :         }
     244             : 
     245          78 :         for (i=0;i<feat->size;i++) {
     246         165 :                 found = 0;
     247         165 :                 for (j=0;j<cfeat->size;j++) {
     248         164 :                         if (feat->feature[i] == cfeat->feature[j]) {
     249             :                                 found = 1;
     250             :                                 break;
     251             :                         }
     252             :                 }
     253             : 
     254          62 :                 if (found == 0) {
     255           1 :                         _gnutls_debug_log("feature %d was not found in cert\n", (int)feat->feature[i]);
     256           1 :                         uret = 0;
     257           1 :                         goto cleanup;
     258             :                 }
     259             :         }
     260             : 
     261             :         uret = 1;
     262          31 :  cleanup:
     263          31 :         gnutls_x509_tlsfeatures_deinit(cfeat);
     264          31 :         return uret;
     265             : }

Generated by: LCOV version 1.14