LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib - cert-cred-x509.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 364 556 65.5 %
Date: 2020-10-30 04:50:48 Functions: 28 31 90.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2002-2016 Free Software Foundation, Inc.
       3             :  * Copyright (C) 2016-2017 Red Hat, Inc.
       4             :  *
       5             :  * Author: Nikos Mavrogiannopoulos
       6             :  *
       7             :  * This file is part of GnuTLS.
       8             :  *
       9             :  * The GnuTLS is free software; you can redistribute it and/or
      10             :  * modify it under the terms of the GNU Lesser General Public License
      11             :  * as published by the Free Software Foundation; either version 2.1 of
      12             :  * the License, or (at your option) any later version.
      13             :  *
      14             :  * This library is distributed in the hope that it will be useful, but
      15             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17             :  * Lesser General Public License for more details.
      18             :  *
      19             :  * You should have received a copy of the GNU Lesser General Public License
      20             :  * along with this program.  If not, see <https://www.gnu.org/licenses/>
      21             :  *
      22             :  */
      23             : 
      24             : #include "gnutls_int.h"
      25             : #include "auth.h"
      26             : #include "errors.h"
      27             : #include <auth/cert.h>
      28             : #include "dh.h"
      29             : #include "num.h"
      30             : #include "datum.h"
      31             : #include <pk.h>
      32             : #include <algorithms.h>
      33             : #include <global.h>
      34             : #include <record.h>
      35             : #include <tls-sig.h>
      36             : #include <state.h>
      37             : #include <pk.h>
      38             : #include "str.h"
      39             : #include <debug.h>
      40             : #include <x509_b64.h>
      41             : #include <x509.h>
      42             : #include "x509/common.h"
      43             : #include "x509/x509_int.h"
      44             : #include <str_array.h>
      45             : #include <gnutls/x509.h>
      46             : #include "read-file.h"
      47             : #include "system-keys.h"
      48             : #include "urls.h"
      49             : #include "cert-cred.h"
      50             : #ifdef _WIN32
      51             : #include <wincrypt.h>
      52             : #endif
      53             : 
      54             : /*
      55             :  * This file includes functions related to adding certificates and other
      56             :  * related objects in a certificate credentials structure.
      57             :  */
      58             : 
      59             : 
      60             : /* Returns the name of the certificate of a null name
      61             :  */
      62       11274 : int _gnutls_get_x509_name(gnutls_x509_crt_t crt, gnutls_str_array_t * names)
      63             : {
      64       11274 :         size_t max_size;
      65       11274 :         int i, ret = 0, ret2;
      66       11274 :         char name[MAX_CN];
      67       11274 :         unsigned have_dns_name = 0;
      68             : 
      69       31821 :         for (i = 0; !(ret < 0); i++) {
      70       20547 :                 max_size = sizeof(name);
      71             : 
      72       20547 :                 ret =
      73       20547 :                     gnutls_x509_crt_get_subject_alt_name(crt, i, name,
      74             :                                                          &max_size, NULL);
      75       20547 :                 if (ret == GNUTLS_SAN_DNSNAME) {
      76        8975 :                         have_dns_name = 1;
      77             : 
      78        8975 :                         ret2 =
      79        8975 :                             _gnutls_str_array_append_idna(names, name,
      80             :                                                   max_size);
      81        8975 :                         if (ret2 < 0) {
      82           0 :                                 _gnutls_str_array_clear(names);
      83           0 :                                 return gnutls_assert_val(ret2);
      84             :                         }
      85             :                 }
      86             :         }
      87             : 
      88       11274 :         if (have_dns_name == 0) {
      89        2622 :                 max_size = sizeof(name);
      90        2622 :                 ret =
      91        2622 :                     gnutls_x509_crt_get_dn_by_oid(crt, OID_X520_COMMON_NAME, 0, 0,
      92             :                                                   name, &max_size);
      93        2622 :                 if (ret >= 0) {
      94        2582 :                         ret = _gnutls_str_array_append_idna(names, name, max_size);
      95        2582 :                         if (ret < 0) {
      96           0 :                                 _gnutls_str_array_clear(names);
      97           0 :                                 return gnutls_assert_val(ret);
      98             :                         }
      99             :                 }
     100             :         }
     101             : 
     102             :         return 0;
     103             : }
     104             : 
     105             : /* Reads a DER encoded certificate list from memory and stores it to a
     106             :  * gnutls_cert structure. Returns the number of certificates parsed.
     107             :  */
     108             : static int
     109        8835 : parse_der_cert_mem(gnutls_certificate_credentials_t res,
     110             :                    gnutls_privkey_t key,
     111             :                    const void *input_cert, int input_cert_size)
     112             : {
     113        8835 :         gnutls_datum_t tmp;
     114        8835 :         gnutls_x509_crt_t crt;
     115        8835 :         gnutls_pcert_st *ccert;
     116        8835 :         int ret;
     117        8835 :         gnutls_str_array_t names;
     118             : 
     119        8835 :         _gnutls_str_array_init(&names);
     120             : 
     121        8835 :         ccert = gnutls_malloc(sizeof(*ccert));
     122        8835 :         if (ccert == NULL) {
     123           0 :                 gnutls_assert();
     124           0 :                 return GNUTLS_E_MEMORY_ERROR;
     125             :         }
     126             : 
     127        8835 :         ret = gnutls_x509_crt_init(&crt);
     128        8835 :         if (ret < 0) {
     129           0 :                 gnutls_assert();
     130           0 :                 goto cleanup;
     131             :         }
     132             : 
     133        8835 :         tmp.data = (uint8_t *) input_cert;
     134        8835 :         tmp.size = input_cert_size;
     135             : 
     136        8835 :         ret = gnutls_x509_crt_import(crt, &tmp, GNUTLS_X509_FMT_DER);
     137        8835 :         if (ret < 0) {
     138           0 :                 gnutls_assert();
     139           0 :                 gnutls_x509_crt_deinit(crt);
     140           0 :                 goto cleanup;
     141             :         }
     142             : 
     143        8835 :         ret = _gnutls_get_x509_name(crt, &names);
     144        8835 :         if (ret < 0) {
     145           0 :                 gnutls_assert();
     146           0 :                 gnutls_x509_crt_deinit(crt);
     147           0 :                 goto cleanup;
     148             :         }
     149             : 
     150        8835 :         ret = gnutls_pcert_import_x509(ccert, crt, 0);
     151        8835 :         gnutls_x509_crt_deinit(crt);
     152             : 
     153        8835 :         if (ret < 0) {
     154           0 :                 gnutls_assert();
     155           0 :                 goto cleanup;
     156             :         }
     157             : 
     158        8835 :         ret = _gnutls_certificate_credential_append_keypair(res, key, names, ccert, 1);
     159        8835 :         if (ret < 0) {
     160           0 :                 gnutls_assert();
     161           0 :                 goto cleanup;
     162             :         }
     163             : 
     164             :         return ret;
     165             : 
     166           0 :       cleanup:
     167           0 :         _gnutls_str_array_clear(&names);
     168           0 :         gnutls_free(ccert);
     169           0 :         return ret;
     170             : }
     171             : 
     172             : /* Reads a base64 encoded certificate list from memory and stores it to
     173             :  * a gnutls_cert structure. Returns the number of certificate parsed.
     174             :  */
     175             : static int
     176        2357 : parse_pem_cert_mem(gnutls_certificate_credentials_t res,
     177             :                    gnutls_privkey_t key,
     178             :                    const char *input_cert, int input_cert_size)
     179             : {
     180        2357 :         int size;
     181        2357 :         const char *ptr;
     182        2357 :         gnutls_datum_t tmp;
     183        2357 :         int ret, count, i;
     184        2357 :         unsigned ncerts = 0;
     185        2357 :         gnutls_pcert_st *pcerts = NULL;
     186        2357 :         gnutls_str_array_t names;
     187        2357 :         gnutls_x509_crt_t unsorted[DEFAULT_MAX_VERIFY_DEPTH];
     188             : 
     189        2357 :         _gnutls_str_array_init(&names);
     190             : 
     191             :         /* move to the certificate
     192             :          */
     193        2357 :         ptr = memmem(input_cert, input_cert_size,
     194             :                      PEM_CERT_SEP, sizeof(PEM_CERT_SEP) - 1);
     195        2357 :         if (ptr == NULL)
     196           0 :                 ptr = memmem(input_cert, input_cert_size,
     197             :                              PEM_CERT_SEP2, sizeof(PEM_CERT_SEP2) - 1);
     198             : 
     199        2357 :         if (ptr == NULL) {
     200           0 :                 gnutls_assert();
     201           0 :                 return GNUTLS_E_BASE64_DECODING_ERROR;
     202             :         }
     203        2357 :         size = input_cert_size - (ptr - input_cert);
     204             : 
     205        2357 :         count = 0;
     206             : 
     207        3431 :         do {
     208        3431 :                 tmp.data = (void *) ptr;
     209        3431 :                 tmp.size = size;
     210             : 
     211        3431 :                 ret = gnutls_x509_crt_init(&unsorted[count]);
     212        3431 :                 if (ret < 0) {
     213           0 :                         gnutls_assert();
     214           0 :                         goto cleanup;
     215             :                 }
     216             : 
     217        3431 :                 ret = gnutls_x509_crt_import(unsorted[count], &tmp, GNUTLS_X509_FMT_PEM);
     218        3431 :                 if (ret < 0) {
     219           0 :                         gnutls_assert();
     220           0 :                         goto cleanup;
     221             :                 }
     222        3431 :                 count++;
     223             : 
     224             :                 /* now we move ptr after the pem header
     225             :                  */
     226        3431 :                 ptr++;
     227        3431 :                 size--;
     228             : 
     229             :                 /* find the next certificate (if any)
     230             :                  */
     231             : 
     232        3431 :                 if (size > 0) {
     233        3431 :                         char *ptr3;
     234             : 
     235        3431 :                         ptr3 =
     236        3431 :                             memmem(ptr, size, PEM_CERT_SEP,
     237             :                                    sizeof(PEM_CERT_SEP) - 1);
     238        3431 :                         if (ptr3 == NULL)
     239        2357 :                                 ptr3 = memmem(ptr, size, PEM_CERT_SEP2,
     240             :                                               sizeof(PEM_CERT_SEP2) - 1);
     241             : 
     242        3431 :                         ptr = ptr3;
     243        3431 :                         size = input_cert_size - (ptr - input_cert);
     244             :                 } else
     245             :                         ptr = NULL;
     246             : 
     247             :         }
     248        3431 :         while (ptr != NULL && count < DEFAULT_MAX_VERIFY_DEPTH);
     249             : 
     250        2357 :         ret =
     251        2357 :             _gnutls_get_x509_name(unsorted[0], &names);
     252        2357 :         if (ret < 0) {
     253           0 :                 gnutls_assert();
     254           0 :                 goto cleanup;
     255             :         }
     256             : 
     257        2357 :         pcerts = gnutls_malloc(sizeof(gnutls_pcert_st) * count);
     258        2357 :         if (pcerts == NULL) {
     259           0 :                 gnutls_assert();
     260           0 :                 return GNUTLS_E_MEMORY_ERROR;
     261             :         }
     262             : 
     263        2357 :         ncerts = count;
     264        2357 :         ret =
     265        2357 :             gnutls_pcert_import_x509_list(pcerts, unsorted, &ncerts, GNUTLS_X509_CRT_LIST_SORT);
     266        2357 :         if (ret < 0) {
     267           0 :                 gnutls_free(pcerts);
     268           0 :                 gnutls_assert();
     269           0 :                 goto cleanup;
     270             :         }
     271             : 
     272        2357 :         ret =
     273        2357 :             _gnutls_certificate_credential_append_keypair(res, key, names, pcerts, ncerts);
     274        2357 :         if (ret < 0) {
     275           0 :                 gnutls_assert();
     276           0 :                 goto cleanup;
     277             :         }
     278             : 
     279        5788 :         for (i = 0; i < count; i++)
     280        3431 :                 gnutls_x509_crt_deinit(unsorted[i]);
     281             : 
     282        2357 :         return ncerts;
     283             : 
     284           0 :       cleanup:
     285           0 :         _gnutls_str_array_clear(&names);
     286           0 :         for (i = 0; i < count; i++)
     287           0 :                 gnutls_x509_crt_deinit(unsorted[i]);
     288           0 :         if (pcerts) {
     289           0 :                 for (i = 0; i < count; i++)
     290           0 :                         gnutls_pcert_deinit(&pcerts[i]);
     291           0 :                 gnutls_free(pcerts);
     292             :         }
     293             :         return ret;
     294             : }
     295             : 
     296             : 
     297             : 
     298             : /* Reads a DER or PEM certificate from memory
     299             :  */
     300             : static int
     301       11192 : read_cert_mem(gnutls_certificate_credentials_t res,
     302             :               gnutls_privkey_t key,
     303             :               const void *cert,
     304             :               int cert_size, gnutls_x509_crt_fmt_t type)
     305             : {
     306       11192 :         int ret;
     307             : 
     308       11192 :         if (type == GNUTLS_X509_FMT_DER)
     309        8835 :                 ret = parse_der_cert_mem(res, key, cert, cert_size);
     310             :         else
     311        2357 :                 ret = parse_pem_cert_mem(res, key, cert, cert_size);
     312             : 
     313       11192 :         if (ret < 0) {
     314           0 :                 gnutls_assert();
     315           0 :                 return ret;
     316             :         }
     317             : 
     318             :         return ret;
     319             : }
     320             : 
     321           1 : static int tmp_pin_cb(void *userdata, int attempt, const char *token_url,
     322             :                       const char *token_label, unsigned int flags,
     323             :                       char *pin, size_t pin_max)
     324             : {
     325           1 :         const char *tmp_pin = userdata;
     326             : 
     327           1 :         if (attempt == 0) {
     328           1 :                 snprintf(pin, pin_max, "%s", tmp_pin);
     329           1 :                 return 0;
     330             :         }
     331             : 
     332             :         return -1;
     333             : }
     334             : 
     335             : /* Reads a PEM encoded PKCS-1 RSA/DSA private key from memory.  Type
     336             :  * indicates the certificate format.
     337             :  *
     338             :  * It returns the private key read in @rkey.
     339             :  */
     340             : int
     341       11247 : _gnutls_read_key_mem(gnutls_certificate_credentials_t res,
     342             :              const void *key, int key_size, gnutls_x509_crt_fmt_t type,
     343             :              const char *pass, unsigned int flags,
     344             :              gnutls_privkey_t *rkey)
     345             : {
     346       11247 :         int ret;
     347       11247 :         gnutls_datum_t tmp;
     348       11247 :         gnutls_privkey_t privkey;
     349             : 
     350       11247 :         if (key) {
     351       11247 :                 tmp.data = (uint8_t *) key;
     352       11247 :                 tmp.size = key_size;
     353             : 
     354       11247 :                 ret = gnutls_privkey_init(&privkey);
     355       11247 :                 if (ret < 0) {
     356           0 :                         gnutls_assert();
     357           0 :                         return ret;
     358             :                 }
     359             : 
     360       11247 :                 if (res->pin.cb) {
     361           0 :                         gnutls_privkey_set_pin_function(privkey,
     362             :                                                         res->pin.cb,
     363             :                                                         res->pin.data);
     364       11247 :                 } else if (pass != NULL) {
     365           0 :                         snprintf(res->pin_tmp, sizeof(res->pin_tmp), "%s",
     366             :                                  pass);
     367           0 :                         gnutls_privkey_set_pin_function(privkey,
     368             :                                                         tmp_pin_cb,
     369             :                                                         res->pin_tmp);
     370             :                 }
     371             : 
     372       11247 :                 ret =
     373       11247 :                     gnutls_privkey_import_x509_raw(privkey, &tmp, type,
     374             :                                                    pass, flags);
     375       11247 :                 if (ret < 0) {
     376           0 :                         gnutls_assert();
     377           0 :                         gnutls_privkey_deinit(privkey);
     378           0 :                         return ret;
     379             :                 }
     380             : 
     381       11247 :                 *rkey = privkey;
     382             :         } else {
     383           0 :                 gnutls_assert();
     384           0 :                 return GNUTLS_E_INVALID_REQUEST;
     385             :         }
     386             : 
     387       11247 :         return 0;
     388             : }
     389             : 
     390             : 
     391             : /* Reads a private key from a token.
     392             :  */
     393             : static int
     394           4 : read_key_url(gnutls_certificate_credentials_t res, const char *url, gnutls_privkey_t *rkey)
     395             : {
     396           4 :         int ret;
     397           4 :         gnutls_privkey_t pkey = NULL;
     398             : 
     399             :         /* allocate space for the pkey list
     400             :          */
     401           4 :         ret = gnutls_privkey_init(&pkey);
     402           4 :         if (ret < 0) {
     403           0 :                 gnutls_assert();
     404           0 :                 goto cleanup;
     405             :         }
     406             : 
     407           4 :         if (res->pin.cb)
     408           1 :                 gnutls_privkey_set_pin_function(pkey, res->pin.cb,
     409             :                                                 res->pin.data);
     410             : 
     411           4 :         ret = gnutls_privkey_import_url(pkey, url, 0);
     412           4 :         if (ret < 0) {
     413           0 :                 gnutls_assert();
     414           0 :                 goto cleanup;
     415             :         }
     416             : 
     417           4 :         *rkey = pkey;
     418             : 
     419           4 :         return 0;
     420             : 
     421           0 :       cleanup:
     422           0 :         if (pkey)
     423           0 :                 gnutls_privkey_deinit(pkey);
     424             : 
     425             :         return ret;
     426             : }
     427             : 
     428             : 
     429             : #define MAX_PKCS11_CERT_CHAIN 8
     430             : /* Reads a certificate key from a token.
     431             :  */
     432             : static int
     433           4 : read_cert_url(gnutls_certificate_credentials_t res, gnutls_privkey_t key, const char *url)
     434             : {
     435           4 :         int ret;
     436           4 :         gnutls_x509_crt_t crt = NULL;
     437           4 :         gnutls_pcert_st *ccert = NULL;
     438           4 :         gnutls_str_array_t names;
     439           4 :         gnutls_datum_t t = {NULL, 0};
     440           4 :         unsigned i, count = 0;
     441             : 
     442           4 :         _gnutls_str_array_init(&names);
     443             : 
     444           4 :         ccert = gnutls_malloc(sizeof(*ccert)*MAX_PKCS11_CERT_CHAIN);
     445           4 :         if (ccert == NULL) {
     446           0 :                 gnutls_assert();
     447           0 :                 ret = GNUTLS_E_MEMORY_ERROR;
     448           0 :                 goto cleanup;
     449             :         }
     450             : 
     451           4 :         ret = gnutls_x509_crt_init(&crt);
     452           4 :         if (ret < 0) {
     453           0 :                 gnutls_assert();
     454           0 :                 goto cleanup;
     455             :         }
     456             : 
     457           4 :         if (res->pin.cb)
     458           1 :                 gnutls_x509_crt_set_pin_function(crt, res->pin.cb,
     459             :                                                  res->pin.data);
     460             : 
     461           4 :         ret = gnutls_x509_crt_import_url(crt, url, 0);
     462           4 :         if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
     463           0 :                 ret =
     464           0 :                     gnutls_x509_crt_import_url(crt, url,
     465             :                                                GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
     466           4 :         if (ret < 0) {
     467           0 :                 gnutls_assert();
     468           0 :                 goto cleanup;
     469             :         }
     470             : 
     471           4 :         ret = _gnutls_get_x509_name(crt, &names);
     472           4 :         if (ret < 0) {
     473           0 :                 gnutls_assert();
     474           0 :                 goto cleanup;
     475             :         }
     476             : 
     477             :         /* Try to load the whole certificate chain from the PKCS #11 token */
     478           6 :         for (i=0;i<MAX_PKCS11_CERT_CHAIN;i++) {
     479           6 :                 ret = gnutls_x509_crt_check_issuer(crt, crt);
     480           6 :                 if (i > 0 && ret != 0) {
     481             :                         /* self signed */
     482             :                         break;
     483             :                 }
     484             : 
     485           4 :                 ret = gnutls_pcert_import_x509(&ccert[i], crt, 0);
     486           4 :                 if (ret < 0) {
     487           0 :                         gnutls_assert();
     488           0 :                         goto cleanup;
     489             :                 }
     490           4 :                 count++;
     491             : 
     492           4 :                 ret = _gnutls_get_raw_issuer(url, crt, &t, 0);
     493           4 :                 if (ret < 0)
     494             :                         break;
     495             : 
     496           2 :                 gnutls_x509_crt_deinit(crt);
     497           2 :                 crt = NULL;
     498           2 :                 ret = gnutls_x509_crt_init(&crt);
     499           2 :                 if (ret < 0) {
     500           0 :                         gnutls_assert();
     501           0 :                         goto cleanup;
     502             :                 }
     503             : 
     504           2 :                 ret = gnutls_x509_crt_import(crt, &t, GNUTLS_X509_FMT_DER);
     505           2 :                 if (ret < 0) {
     506           0 :                         gnutls_assert();
     507           0 :                         goto cleanup;
     508             :                 }
     509           2 :                 gnutls_free(t.data);
     510             :         }
     511             : 
     512           4 :         ret = _gnutls_certificate_credential_append_keypair(res, key, names, ccert, count);
     513           4 :         if (ret < 0) {
     514           0 :                 gnutls_assert();
     515           0 :                 goto cleanup;
     516             :         }
     517             : 
     518           4 :         if (crt != NULL)
     519           4 :                 gnutls_x509_crt_deinit(crt);
     520             : 
     521             :         return 0;
     522           0 : cleanup:
     523           0 :         if (crt != NULL)
     524           0 :                 gnutls_x509_crt_deinit(crt);
     525           0 :         gnutls_free(t.data);
     526           0 :         _gnutls_str_array_clear(&names);
     527           0 :         gnutls_free(ccert);
     528           0 :         return ret;
     529             : }
     530             : 
     531             : /* Reads a certificate file
     532             :  */
     533             : static int
     534         368 : read_cert_file(gnutls_certificate_credentials_t res,
     535             :                gnutls_privkey_t key,
     536             :                const char *certfile, gnutls_x509_crt_fmt_t type)
     537             : {
     538         368 :         int ret;
     539         368 :         size_t size;
     540         368 :         char *data;
     541             : 
     542         368 :         if (gnutls_url_is_supported(certfile)) {
     543           4 :                 return read_cert_url(res, key, certfile);
     544             :         }
     545             : 
     546         364 :         data = read_file(certfile, RF_BINARY, &size);
     547             : 
     548         364 :         if (data == NULL) {
     549           2 :                 gnutls_assert();
     550           2 :                 return GNUTLS_E_FILE_ERROR;
     551             :         }
     552             : 
     553         362 :         ret = read_cert_mem(res, key, data, size, type);
     554         362 :         free(data);
     555             : 
     556         362 :         return ret;
     557             : 
     558             : }
     559             : 
     560             : 
     561             : 
     562             : /* Reads PKCS-1 RSA private key file or a DSA file (in the format openssl
     563             :  * stores it).
     564             :  */
     565             : int
     566         372 : _gnutls_read_key_file(gnutls_certificate_credentials_t res,
     567             :               const char *keyfile, gnutls_x509_crt_fmt_t type,
     568             :               const char *pass, unsigned int flags,
     569             :               gnutls_privkey_t *rkey)
     570             : {
     571         372 :         int ret;
     572         372 :         size_t size;
     573         372 :         char *data;
     574             : 
     575         372 :         if (_gnutls_url_is_known(keyfile)) {
     576           4 :                 if (gnutls_url_is_supported(keyfile)) {
     577             :                         /* if no PIN function is specified, and we have a PIN,
     578             :                          * specify one */
     579           4 :                         if (pass != NULL && res->pin.cb == NULL) {
     580           1 :                                 snprintf(res->pin_tmp, sizeof(res->pin_tmp), "%s", pass);
     581           1 :                                 gnutls_certificate_set_pin_function(res, tmp_pin_cb, res->pin_tmp);
     582             :                         }
     583             : 
     584           4 :                         return read_key_url(res, keyfile, rkey);
     585             :                 } else
     586           0 :                         return
     587           0 :                             gnutls_assert_val
     588             :                             (GNUTLS_E_UNIMPLEMENTED_FEATURE);
     589             :         }
     590             : 
     591         368 :         data = read_file(keyfile, RF_BINARY | RF_SENSITIVE, &size);
     592             : 
     593         368 :         if (data == NULL) {
     594           0 :                 gnutls_assert();
     595           0 :                 return GNUTLS_E_FILE_ERROR;
     596             :         }
     597             : 
     598         368 :         ret = _gnutls_read_key_mem(res, data, size, type, pass, flags, rkey);
     599         368 :         zeroize_key(data, size);
     600         368 :         free(data);
     601             : 
     602         368 :         return ret;
     603             : }
     604             : 
     605             : /**
     606             :  * gnutls_certificate_set_x509_key_mem:
     607             :  * @res: is a #gnutls_certificate_credentials_t type.
     608             :  * @cert: contains a certificate list (path) for the specified private key
     609             :  * @key: is the private key, or %NULL
     610             :  * @type: is PEM or DER
     611             :  *
     612             :  * This function sets a certificate/private key pair in the
     613             :  * gnutls_certificate_credentials_t type. This function may be called
     614             :  * more than once, in case multiple keys/certificates exist for the
     615             :  * server.
     616             :  *
     617             :  * Note that the keyUsage (2.5.29.15) PKIX extension in X.509 certificates
     618             :  * is supported. This means that certificates intended for signing cannot
     619             :  * be used for ciphersuites that require encryption.
     620             :  *
     621             :  * If the certificate and the private key are given in PEM encoding
     622             :  * then the strings that hold their values must be null terminated.
     623             :  *
     624             :  * The @key may be %NULL if you are using a sign callback, see
     625             :  * gnutls_sign_callback_set().
     626             :  *
     627             :  * Note that, this function by default returns zero on success and a negative value on error.
     628             :  * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
     629             :  * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair.
     630             :  *
     631             :  * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
     632             :  *
     633             :  **/
     634             : int
     635       10820 : gnutls_certificate_set_x509_key_mem(gnutls_certificate_credentials_t res,
     636             :                                     const gnutls_datum_t * cert,
     637             :                                     const gnutls_datum_t * key,
     638             :                                     gnutls_x509_crt_fmt_t type)
     639             : {
     640       10820 :         return gnutls_certificate_set_x509_key_mem2(res, cert, key, type,
     641             :                                                     NULL, 0);
     642             : }
     643             : 
     644             : /**
     645             :  * gnutls_certificate_set_x509_key_mem2:
     646             :  * @res: is a #gnutls_certificate_credentials_t type.
     647             :  * @cert: contains a certificate list (path) for the specified private key
     648             :  * @key: is the private key, or %NULL
     649             :  * @type: is PEM or DER
     650             :  * @pass: is the key's password
     651             :  * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
     652             :  *
     653             :  * This function sets a certificate/private key pair in the
     654             :  * gnutls_certificate_credentials_t type. This function may be called
     655             :  * more than once, in case multiple keys/certificates exist for the
     656             :  * server.
     657             :  *
     658             :  * Note that the keyUsage (2.5.29.15) PKIX extension in X.509 certificates
     659             :  * is supported. This means that certificates intended for signing cannot
     660             :  * be used for ciphersuites that require encryption.
     661             :  *
     662             :  * If the certificate and the private key are given in PEM encoding
     663             :  * then the strings that hold their values must be null terminated.
     664             :  *
     665             :  * The @key may be %NULL if you are using a sign callback, see
     666             :  * gnutls_sign_callback_set().
     667             :  *
     668             :  * Note that, this function by default returns zero on success and a negative value on error.
     669             :  * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
     670             :  * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair.
     671             :  *
     672             :  * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
     673             :  **/
     674             : int
     675       10830 : gnutls_certificate_set_x509_key_mem2(gnutls_certificate_credentials_t res,
     676             :                                      const gnutls_datum_t * cert,
     677             :                                      const gnutls_datum_t * key,
     678             :                                      gnutls_x509_crt_fmt_t type,
     679             :                                      const char *pass, unsigned int flags)
     680             : {
     681       10830 :         int ret;
     682       10830 :         gnutls_privkey_t rkey;
     683             : 
     684             :         /* this should be first
     685             :          */
     686       21660 :         if ((ret = _gnutls_read_key_mem(res, key ? key->data : NULL,
     687       10830 :                                 key ? key->size : 0, type, pass,
     688             :                                 flags, &rkey)) < 0)
     689             :                 return ret;
     690             : 
     691       10830 :         if ((ret = read_cert_mem(res, rkey, cert->data, cert->size, type)) < 0) {
     692           0 :                 gnutls_privkey_deinit(rkey);
     693           0 :                 return ret;
     694             :         }
     695             : 
     696       10830 :         res->ncerts++;
     697             : 
     698       10830 :         if (key && (ret = _gnutls_check_key_cert_match(res)) < 0) {
     699           1 :                 gnutls_assert();
     700           1 :                 return ret;
     701             :         }
     702             : 
     703       10829 :         CRED_RET_SUCCESS(res);
     704             : }
     705             : 
     706             : 
     707             : /**
     708             :  * gnutls_certificate_set_x509_key:
     709             :  * @res: is a #gnutls_certificate_credentials_t type.
     710             :  * @cert_list: contains a certificate list (path) for the specified private key
     711             :  * @cert_list_size: holds the size of the certificate list
     712             :  * @key: is a #gnutls_x509_privkey_t key
     713             :  *
     714             :  * This function sets a certificate/private key pair in the
     715             :  * gnutls_certificate_credentials_t type.  This function may be
     716             :  * called more than once, in case multiple keys/certificates exist for
     717             :  * the server.  For clients that wants to send more than their own end
     718             :  * entity certificate (e.g., also an intermediate CA cert) then put
     719             :  * the certificate chain in @cert_list.
     720             :  *
     721             :  * Note that the certificates and keys provided, can be safely deinitialized
     722             :  * after this function is called.
     723             :  *
     724             :  * If that function fails to load the @res type is at an undefined state, it must
     725             :  * not be reused to load other keys or certificates.
     726             :  *
     727             :  * Note that, this function by default returns zero on success and a negative value on error.
     728             :  * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
     729             :  * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair.
     730             :  *
     731             :  * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
     732             :  *
     733             :  * Since: 2.4.0
     734             :  **/
     735             : int
     736          33 : gnutls_certificate_set_x509_key(gnutls_certificate_credentials_t res,
     737             :                                 gnutls_x509_crt_t * cert_list,
     738             :                                 int cert_list_size,
     739             :                                 gnutls_x509_privkey_t key)
     740             : {
     741          33 :         int ret;
     742          33 :         gnutls_privkey_t pkey;
     743          33 :         gnutls_pcert_st *pcerts = NULL;
     744          33 :         gnutls_str_array_t names;
     745             : 
     746          33 :         _gnutls_str_array_init(&names);
     747             : 
     748             :         /* this should be first
     749             :          */
     750          33 :         ret = gnutls_privkey_init(&pkey);
     751          33 :         if (ret < 0) {
     752           0 :                 gnutls_assert();
     753           0 :                 return ret;
     754             :         }
     755             : 
     756          33 :         if (res->pin.cb)
     757           0 :                 gnutls_privkey_set_pin_function(pkey, res->pin.cb,
     758             :                                                 res->pin.data);
     759             : 
     760          33 :         ret =
     761          33 :             gnutls_privkey_import_x509(pkey, key,
     762             :                                        GNUTLS_PRIVKEY_IMPORT_COPY);
     763          33 :         if (ret < 0) {
     764           0 :                 gnutls_assert();
     765           0 :                 return ret;
     766             :         }
     767             : 
     768             :         /* load certificates */
     769          33 :         pcerts = gnutls_malloc(sizeof(gnutls_pcert_st) * cert_list_size);
     770          33 :         if (pcerts == NULL) {
     771           0 :                 gnutls_assert();
     772           0 :                 return GNUTLS_E_MEMORY_ERROR;
     773             :         }
     774             : 
     775          33 :         ret = _gnutls_get_x509_name(cert_list[0], &names);
     776          33 :         if (ret < 0) {
     777           0 :                 gnutls_assert();
     778           0 :                 goto cleanup;
     779             :         }
     780             : 
     781          33 :         ret =
     782          33 :                 gnutls_pcert_import_x509_list(pcerts, cert_list, (unsigned int*)&cert_list_size,
     783             :                                               GNUTLS_X509_CRT_LIST_SORT);
     784          33 :         if (ret < 0) {
     785           0 :                 gnutls_assert();
     786           0 :                 goto cleanup;
     787             :         }
     788             : 
     789          33 :         ret =
     790          33 :             _gnutls_certificate_credential_append_keypair(res, pkey, names, pcerts,
     791             :                                                    cert_list_size);
     792          33 :         if (ret < 0) {
     793           0 :                 gnutls_assert();
     794           0 :                 goto cleanup;
     795             :         }
     796             : 
     797          33 :         res->ncerts++;
     798             : 
     799             :         /* after this point we do not deinitialize anything on failure to avoid
     800             :          * double freeing. We intentionally keep everything as the credentials state
     801             :          * is documented to be on undefined state. */
     802          33 :         if ((ret = _gnutls_check_key_cert_match(res)) < 0) {
     803           1 :                 gnutls_assert();
     804           1 :                 return ret;
     805             :         }
     806             : 
     807          32 :         CRED_RET_SUCCESS(res);
     808             : 
     809           0 :       cleanup:
     810           0 :         gnutls_free(pcerts);
     811           0 :         _gnutls_str_array_clear(&names);
     812             :         return ret;
     813             : }
     814             : 
     815             : /**
     816             :  * gnutls_certificate_get_x509_key:
     817             :  * @res: is a #gnutls_certificate_credentials_t type.
     818             :  * @index: The index of the key to obtain.
     819             :  * @key: Location to store the key.
     820             :  *
     821             :  * Obtains a X.509 private key that has been stored in @res with one of
     822             :  * gnutls_certificate_set_x509_key(), gnutls_certificate_set_key(),
     823             :  * gnutls_certificate_set_x509_key_file(),
     824             :  * gnutls_certificate_set_x509_key_file2(),
     825             :  * gnutls_certificate_set_x509_key_mem(), or
     826             :  * gnutls_certificate_set_x509_key_mem2(). The returned key must be deallocated
     827             :  * with gnutls_x509_privkey_deinit() when no longer needed.
     828             :  *
     829             :  * The @index matches the return value of gnutls_certificate_set_x509_key() and friends
     830             :  * functions, when the %GNUTLS_CERTIFICATE_API_V2 flag is set.
     831             :  *
     832             :  * If there is no key with the given index,
     833             :  * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned. If the key with the
     834             :  * given index is not a X.509 key, %GNUTLS_E_INVALID_REQUEST is returned.
     835             :  *
     836             :  * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
     837             :  *
     838             :  * Since: 3.4.0
     839             :  */
     840             : int
     841           1 : gnutls_certificate_get_x509_key(gnutls_certificate_credentials_t res,
     842             :                                 unsigned index,
     843             :                                 gnutls_x509_privkey_t *key)
     844             : {
     845           1 :         if (index >= res->ncerts) {
     846           0 :                 gnutls_assert();
     847           0 :                 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
     848             :         }
     849             : 
     850           1 :         return gnutls_privkey_export_x509(res->certs[index].pkey, key);
     851             : }
     852             : 
     853             : /**
     854             :  * gnutls_certificate_get_x509_crt:
     855             :  * @res: is a #gnutls_certificate_credentials_t type.
     856             :  * @index: The index of the certificate list to obtain.
     857             :  * @crt_list: Where to store the certificate list.
     858             :  * @crt_list_size: Will hold the number of certificates.
     859             :  *
     860             :  * Obtains a X.509 certificate list that has been stored in @res with one of
     861             :  * gnutls_certificate_set_x509_key(), gnutls_certificate_set_key(),
     862             :  * gnutls_certificate_set_x509_key_file(),
     863             :  * gnutls_certificate_set_x509_key_file2(),
     864             :  * gnutls_certificate_set_x509_key_mem(), or
     865             :  * gnutls_certificate_set_x509_key_mem2(). Each certificate in the returned
     866             :  * certificate list must be deallocated with gnutls_x509_crt_deinit(), and the
     867             :  * list itself must be freed with gnutls_free().
     868             :  *
     869             :  * The @index matches the return value of gnutls_certificate_set_x509_key() and friends
     870             :  * functions, when the %GNUTLS_CERTIFICATE_API_V2 flag is set.
     871             :  *
     872             :  * If there is no certificate with the given index,
     873             :  * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned. If the certificate
     874             :  * with the given index is not a X.509 certificate, %GNUTLS_E_INVALID_REQUEST
     875             :  * is returned. The returned certificates must be deinitialized after
     876             :  * use, and the @crt_list pointer must be freed using gnutls_free().
     877             :  *
     878             :  * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
     879             :  *
     880             :  * Since: 3.4.0
     881             :  */
     882             : int
     883           1 : gnutls_certificate_get_x509_crt(gnutls_certificate_credentials_t res,
     884             :                                 unsigned index,
     885             :                                 gnutls_x509_crt_t **crt_list,
     886             :                                 unsigned *crt_list_size)
     887             : {
     888           1 :         int ret;
     889           1 :         unsigned i;
     890             : 
     891           1 :         if (index >= res->ncerts) {
     892           0 :                 gnutls_assert();
     893           0 :                 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
     894             :         }
     895             : 
     896           1 :         *crt_list_size = res->certs[index].cert_list_length;
     897           2 :         *crt_list = gnutls_malloc(
     898           1 :                 res->certs[index].cert_list_length * sizeof (gnutls_x509_crt_t));
     899           1 :         if (*crt_list == NULL) {
     900           0 :                 gnutls_assert();
     901           0 :                 return GNUTLS_E_MEMORY_ERROR;
     902             :         }
     903             : 
     904           3 :         for (i = 0; i < res->certs[index].cert_list_length; ++i) {
     905           2 :                 ret = gnutls_pcert_export_x509(&res->certs[index].cert_list[i], &(*crt_list)[i]);
     906           2 :                 if (ret < 0) {
     907           0 :                         while (i--)
     908           0 :                                 gnutls_x509_crt_deinit((*crt_list)[i]);
     909           0 :                         gnutls_free(*crt_list);
     910             : 
     911           0 :                         return gnutls_assert_val(ret);
     912             :                 }
     913             :         }
     914             : 
     915             :         return 0;
     916             : }
     917             : 
     918             : /**
     919             :  * gnutls_certificate_set_trust_list:
     920             :  * @res: is a #gnutls_certificate_credentials_t type.
     921             :  * @tlist: is a #gnutls_x509_trust_list_t type
     922             :  * @flags: must be zero
     923             :  *
     924             :  * This function sets a trust list in the gnutls_certificate_credentials_t type.
     925             :  *
     926             :  * Note that the @tlist will become part of the credentials
     927             :  * structure and must not be deallocated. It will be automatically deallocated
     928             :  * when the @res structure is deinitialized.
     929             :  *
     930             :  * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
     931             :  *
     932             :  * Since: 3.2.2
     933             :  **/
     934             : void
     935         274 : gnutls_certificate_set_trust_list(gnutls_certificate_credentials_t res,
     936             :                                   gnutls_x509_trust_list_t tlist,
     937             :                                   unsigned flags)
     938             : {
     939         274 :         gnutls_x509_trust_list_deinit(res->tlist, 1);
     940             : 
     941         274 :         res->tlist = tlist;
     942         274 : }
     943             : 
     944             : /**
     945             :  * gnutls_certificate_get_trust_list:
     946             :  * @res: is a #gnutls_certificate_credentials_t type.
     947             :  * @tlist: Location where to store the trust list.
     948             :  *
     949             :  * Obtains the list of trusted certificates stored in @res and writes a
     950             :  * pointer to it to the location @tlist. The pointer will point to memory
     951             :  * internal to @res, and must not be deinitialized. It will be automatically
     952             :  * deallocated when the @res structure is deinitialized.
     953             :  *
     954             :  * Since: 3.4.0
     955             :  **/
     956             : void
     957           1 : gnutls_certificate_get_trust_list(gnutls_certificate_credentials_t res,
     958             :                                   gnutls_x509_trust_list_t *tlist)
     959             : {
     960           1 :         *tlist = res->tlist;
     961           1 : }
     962             : 
     963             : /**
     964             :  * gnutls_certificate_set_x509_key_file:
     965             :  * @res: is a #gnutls_certificate_credentials_t type.
     966             :  * @certfile: is a file that containing the certificate list (path) for
     967             :  *   the specified private key, in PKCS7 format, or a list of certificates
     968             :  * @keyfile: is a file that contains the private key
     969             :  * @type: is PEM or DER
     970             :  *
     971             :  * This function sets a certificate/private key pair in the
     972             :  * gnutls_certificate_credentials_t type.  This function may be
     973             :  * called more than once, in case multiple keys/certificates exist for
     974             :  * the server.  For clients that need to send more than its own end
     975             :  * entity certificate, e.g., also an intermediate CA cert, then the
     976             :  * @certfile must contain the ordered certificate chain.
     977             :  *
     978             :  * Note that the names in the certificate provided will be considered
     979             :  * when selecting the appropriate certificate to use (in case of multiple
     980             :  * certificate/key pairs).
     981             :  *
     982             :  * This function can also accept URLs at @keyfile and @certfile. In that case it
     983             :  * will use the private key and certificate indicated by the URLs. Note
     984             :  * that the supported URLs are the ones indicated by gnutls_url_is_supported().
     985             :  *
     986             :  * In case the @certfile is provided as a PKCS #11 URL, then the certificate, and its
     987             :  * present issuers in the token are imported (i.e., forming the required trust chain).
     988             :  *
     989             :  * If that function fails to load the @res structure is at an undefined state, it must
     990             :  * not be reused to load other keys or certificates.
     991             :  *
     992             :  * Note that, this function by default returns zero on success and a negative value on error.
     993             :  * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
     994             :  * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair.
     995             :  *
     996             :  * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
     997             :  *
     998             :  * Since: 3.1.11
     999             :  **/
    1000             : int
    1001         303 : gnutls_certificate_set_x509_key_file(gnutls_certificate_credentials_t res,
    1002             :                                      const char *certfile,
    1003             :                                      const char *keyfile,
    1004             :                                      gnutls_x509_crt_fmt_t type)
    1005             : {
    1006         303 :         return gnutls_certificate_set_x509_key_file2(res, certfile,
    1007             :                                                      keyfile, type, NULL,
    1008             :                                                      0);
    1009             : }
    1010             : 
    1011             : /**
    1012             :  * gnutls_certificate_set_x509_key_file2:
    1013             :  * @res: is a #gnutls_certificate_credentials_t type.
    1014             :  * @certfile: is a file that containing the certificate list (path) for
    1015             :  *   the specified private key, in PKCS7 format, or a list of certificates
    1016             :  * @keyfile: is a file that contains the private key
    1017             :  * @type: is PEM or DER
    1018             :  * @pass: is the password of the key
    1019             :  * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
    1020             :  *
    1021             :  * This function sets a certificate/private key pair in the
    1022             :  * gnutls_certificate_credentials_t type.  This function may be
    1023             :  * called more than once, in case multiple keys/certificates exist for
    1024             :  * the server.  For clients that need to send more than its own end
    1025             :  * entity certificate, e.g., also an intermediate CA cert, then the
    1026             :  * @certfile must contain the ordered certificate chain.
    1027             :  *
    1028             :  * Note that the names in the certificate provided will be considered
    1029             :  * when selecting the appropriate certificate to use (in case of multiple
    1030             :  * certificate/key pairs).
    1031             :  *
    1032             :  * This function can also accept URLs at @keyfile and @certfile. In that case it
    1033             :  * will use the private key and certificate indicated by the URLs. Note
    1034             :  * that the supported URLs are the ones indicated by gnutls_url_is_supported().
    1035             :  * Before GnuTLS 3.4.0 when a URL was specified, the @pass part was ignored and a
    1036             :  * PIN callback had to be registered, this is no longer the case in current releases.
    1037             :  *
    1038             :  * In case the @certfile is provided as a PKCS #11 URL, then the certificate, and its
    1039             :  * present issuers in the token are imported (i.e., forming the required trust chain).
    1040             :  *
    1041             :  * If that function fails to load the @res structure is at an undefined state, it must
    1042             :  * not be reused to load other keys or certificates.
    1043             :  *
    1044             :  * Note that, this function by default returns zero on success and a negative value on error.
    1045             :  * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
    1046             :  * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair.
    1047             :  *
    1048             :  * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
    1049             :  *
    1050             :  **/
    1051             : int
    1052         368 : gnutls_certificate_set_x509_key_file2(gnutls_certificate_credentials_t res,
    1053             :                                       const char *certfile,
    1054             :                                       const char *keyfile,
    1055             :                                       gnutls_x509_crt_fmt_t type,
    1056             :                                       const char *pass, unsigned int flags)
    1057             : {
    1058         368 :         int ret;
    1059         368 :         gnutls_privkey_t rkey;
    1060             : 
    1061             :         /* this should be first
    1062             :          */
    1063         368 :         if ((ret = _gnutls_read_key_file(res, keyfile, type, pass, flags, &rkey)) < 0)
    1064             :                 return ret;
    1065             : 
    1066         368 :         if ((ret = read_cert_file(res, rkey, certfile, type)) < 0) {
    1067           2 :                 gnutls_privkey_deinit(rkey);
    1068           2 :                 return ret;
    1069             :         }
    1070             : 
    1071         366 :         res->ncerts++;
    1072             : 
    1073         366 :         if ((ret = _gnutls_check_key_cert_match(res)) < 0) {
    1074           0 :                 gnutls_assert();
    1075           0 :                 return ret;
    1076             :         }
    1077             : 
    1078         366 :         CRED_RET_SUCCESS(res);
    1079             : }
    1080             : 
    1081             : /**
    1082             :  * gnutls_certificate_set_x509_trust_mem:
    1083             :  * @res: is a #gnutls_certificate_credentials_t type.
    1084             :  * @ca: is a list of trusted CAs or a DER certificate
    1085             :  * @type: is DER or PEM
    1086             :  *
    1087             :  * This function adds the trusted CAs in order to verify client or
    1088             :  * server certificates. In case of a client this is not required to be
    1089             :  * called if the certificates are not verified using
    1090             :  * gnutls_certificate_verify_peers2().  This function may be called
    1091             :  * multiple times.
    1092             :  *
    1093             :  * In case of a server the CAs set here will be sent to the client if
    1094             :  * a certificate request is sent. This can be disabled using
    1095             :  * gnutls_certificate_send_x509_rdn_sequence().
    1096             :  *
    1097             :  * Returns: the number of certificates processed or a negative error code
    1098             :  * on error.
    1099             :  **/
    1100             : int
    1101         339 : gnutls_certificate_set_x509_trust_mem(gnutls_certificate_credentials_t res,
    1102             :                                       const gnutls_datum_t * ca,
    1103             :                                       gnutls_x509_crt_fmt_t type)
    1104             : {
    1105         339 : int ret;
    1106             : 
    1107         339 :         ret = gnutls_x509_trust_list_add_trust_mem(res->tlist, ca, NULL,
    1108             :                                         type, GNUTLS_TL_USE_IN_TLS, 0);
    1109         339 :         if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
    1110           1 :                 return 0;
    1111             : 
    1112             :         return ret;
    1113             : }
    1114             : 
    1115             : /**
    1116             :  * gnutls_certificate_set_x509_trust:
    1117             :  * @res: is a #gnutls_certificate_credentials_t type.
    1118             :  * @ca_list: is a list of trusted CAs
    1119             :  * @ca_list_size: holds the size of the CA list
    1120             :  *
    1121             :  * This function adds the trusted CAs in order to verify client
    1122             :  * or server certificates. In case of a client this is not required
    1123             :  * to be called if the certificates are not verified using
    1124             :  * gnutls_certificate_verify_peers2().
    1125             :  * This function may be called multiple times.
    1126             :  *
    1127             :  * In case of a server the CAs set here will be sent to the client if
    1128             :  * a certificate request is sent. This can be disabled using
    1129             :  * gnutls_certificate_send_x509_rdn_sequence().
    1130             :  *
    1131             :  * Returns: the number of certificates processed or a negative error code
    1132             :  * on error.
    1133             :  *
    1134             :  * Since: 2.4.0
    1135             :  **/
    1136             : int
    1137           0 : gnutls_certificate_set_x509_trust(gnutls_certificate_credentials_t res,
    1138             :                                   gnutls_x509_crt_t * ca_list,
    1139             :                                   int ca_list_size)
    1140             : {
    1141           0 :         int ret, i, j;
    1142           0 :         gnutls_x509_crt_t *new_list = gnutls_malloc(ca_list_size * sizeof(gnutls_x509_crt_t));
    1143             : 
    1144           0 :         if (!new_list)
    1145             :                 return GNUTLS_E_MEMORY_ERROR;
    1146             : 
    1147           0 :         for (i = 0; i < ca_list_size; i++) {
    1148           0 :                 ret = gnutls_x509_crt_init(&new_list[i]);
    1149           0 :                 if (ret < 0) {
    1150           0 :                         gnutls_assert();
    1151           0 :                         goto cleanup;
    1152             :                 }
    1153             : 
    1154           0 :                 ret = _gnutls_x509_crt_cpy(new_list[i], ca_list[i]);
    1155           0 :                 if (ret < 0) {
    1156           0 :                         gnutls_assert();
    1157           0 :                         goto cleanup;
    1158             :                 }
    1159             :         }
    1160             : 
    1161           0 :         ret =
    1162           0 :             gnutls_x509_trust_list_add_cas(res->tlist, new_list,
    1163             :                                            ca_list_size, GNUTLS_TL_USE_IN_TLS);
    1164           0 :         if (ret < 0) {
    1165           0 :                 gnutls_assert();
    1166           0 :                 goto cleanup;
    1167             :         }
    1168             : 
    1169           0 :         gnutls_free(new_list);
    1170           0 :         return ret;
    1171             : 
    1172           0 :       cleanup:
    1173           0 :         for (j = 0; j < i; j++)
    1174           0 :                 gnutls_x509_crt_deinit(new_list[j]);
    1175           0 :         gnutls_free(new_list);
    1176             : 
    1177           0 :         return ret;
    1178             : }
    1179             : 
    1180             : 
    1181             : /**
    1182             :  * gnutls_certificate_set_x509_trust_file:
    1183             :  * @cred: is a #gnutls_certificate_credentials_t type.
    1184             :  * @cafile: is a file containing the list of trusted CAs (DER or PEM list)
    1185             :  * @type: is PEM or DER
    1186             :  *
    1187             :  * This function adds the trusted CAs in order to verify client or
    1188             :  * server certificates. In case of a client this is not required to
    1189             :  * be called if the certificates are not verified using
    1190             :  * gnutls_certificate_verify_peers2().  This function may be called
    1191             :  * multiple times.
    1192             :  *
    1193             :  * In case of a server the names of the CAs set here will be sent to
    1194             :  * the client if a certificate request is sent. This can be disabled
    1195             :  * using gnutls_certificate_send_x509_rdn_sequence().
    1196             :  *
    1197             :  * This function can also accept URLs. In that case it
    1198             :  * will import all certificates that are marked as trusted. Note
    1199             :  * that the supported URLs are the ones indicated by gnutls_url_is_supported().
    1200             :  *
    1201             :  * Returns: the number of certificates processed
    1202             :  **/
    1203             : int
    1204         668 : gnutls_certificate_set_x509_trust_file(gnutls_certificate_credentials_t
    1205             :                                        cred, const char *cafile,
    1206             :                                        gnutls_x509_crt_fmt_t type)
    1207             : {
    1208         668 : int ret;
    1209             : 
    1210         668 :         ret = gnutls_x509_trust_list_add_trust_file(cred->tlist, cafile, NULL,
    1211             :                                                 type, GNUTLS_TL_USE_IN_TLS, 0);
    1212         668 :         if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
    1213         115 :                 return 0;
    1214             : 
    1215             :         return ret;
    1216             : }
    1217             : 
    1218             : /**
    1219             :  * gnutls_certificate_set_x509_trust_dir:
    1220             :  * @cred: is a #gnutls_certificate_credentials_t type.
    1221             :  * @ca_dir: is a directory containing the list of trusted CAs (DER or PEM list)
    1222             :  * @type: is PEM or DER
    1223             :  *
    1224             :  * This function adds the trusted CAs present in the directory in order to
    1225             :  * verify client or server certificates. This function is identical
    1226             :  * to gnutls_certificate_set_x509_trust_file() but loads all certificates
    1227             :  * in a directory.
    1228             :  *
    1229             :  * Returns: the number of certificates processed
    1230             :  *
    1231             :  * Since: 3.3.6
    1232             :  *
    1233             :  **/
    1234             : int
    1235           0 : gnutls_certificate_set_x509_trust_dir(gnutls_certificate_credentials_t cred,
    1236             :                                       const char *ca_dir,
    1237             :                                       gnutls_x509_crt_fmt_t type)
    1238             : {
    1239           0 : int ret;
    1240             : 
    1241           0 :         ret = gnutls_x509_trust_list_add_trust_dir(cred->tlist, ca_dir, NULL,
    1242             :                                                 type, GNUTLS_TL_USE_IN_TLS, 0);
    1243           0 :         if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
    1244           0 :                 return 0;
    1245             : 
    1246             :         return ret;
    1247             : }
    1248             : 
    1249             : /**
    1250             :  * gnutls_certificate_set_x509_system_trust:
    1251             :  * @cred: is a #gnutls_certificate_credentials_t type.
    1252             :  *
    1253             :  * This function adds the system's default trusted CAs in order to
    1254             :  * verify client or server certificates.
    1255             :  *
    1256             :  * In the case the system is currently unsupported %GNUTLS_E_UNIMPLEMENTED_FEATURE
    1257             :  * is returned.
    1258             :  *
    1259             :  * Returns: the number of certificates processed or a negative error code
    1260             :  * on error.
    1261             :  *
    1262             :  * Since: 3.0.20
    1263             :  **/
    1264             : int
    1265           1 : gnutls_certificate_set_x509_system_trust(gnutls_certificate_credentials_t
    1266             :                                          cred)
    1267             : {
    1268           1 :         return gnutls_x509_trust_list_add_system_trust(cred->tlist,
    1269             :                                         GNUTLS_TL_USE_IN_TLS, 0);
    1270             : }
    1271             : 
    1272             : /**
    1273             :  * gnutls_certificate_set_x509_crl_mem:
    1274             :  * @res: is a #gnutls_certificate_credentials_t type.
    1275             :  * @CRL: is a list of trusted CRLs. They should have been verified before.
    1276             :  * @type: is DER or PEM
    1277             :  *
    1278             :  * This function adds the trusted CRLs in order to verify client or
    1279             :  * server certificates.  In case of a client this is not required to
    1280             :  * be called if the certificates are not verified using
    1281             :  * gnutls_certificate_verify_peers2().  This function may be called
    1282             :  * multiple times.
    1283             :  *
    1284             :  * Returns: number of CRLs processed, or a negative error code on error.
    1285             :  **/
    1286             : int
    1287           1 : gnutls_certificate_set_x509_crl_mem(gnutls_certificate_credentials_t res,
    1288             :                                     const gnutls_datum_t * CRL,
    1289             :                                     gnutls_x509_crt_fmt_t type)
    1290             : {
    1291           1 :         unsigned flags = GNUTLS_TL_USE_IN_TLS;
    1292           1 :         int ret;
    1293             : 
    1294           1 :         if (res->flags & GNUTLS_CERTIFICATE_VERIFY_CRLS)
    1295           0 :                 flags |= GNUTLS_TL_VERIFY_CRL|GNUTLS_TL_FAIL_ON_INVALID_CRL;
    1296             : 
    1297           1 :         ret = gnutls_x509_trust_list_add_trust_mem(res->tlist, NULL, CRL,
    1298             :                                         type, flags, 0);
    1299           1 :         if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
    1300           0 :                 return 0;
    1301             : 
    1302             :         return ret;
    1303             : }
    1304             : 
    1305             : /**
    1306             :  * gnutls_certificate_set_x509_crl:
    1307             :  * @res: is a #gnutls_certificate_credentials_t type.
    1308             :  * @crl_list: is a list of trusted CRLs. They should have been verified before.
    1309             :  * @crl_list_size: holds the size of the crl_list
    1310             :  *
    1311             :  * This function adds the trusted CRLs in order to verify client or
    1312             :  * server certificates.  In case of a client this is not required to
    1313             :  * be called if the certificates are not verified using
    1314             :  * gnutls_certificate_verify_peers2().  This function may be called
    1315             :  * multiple times.
    1316             :  *
    1317             :  * Returns: number of CRLs processed, or a negative error code on error.
    1318             :  *
    1319             :  * Since: 2.4.0
    1320             :  **/
    1321             : int
    1322           1 : gnutls_certificate_set_x509_crl(gnutls_certificate_credentials_t res,
    1323             :                                 gnutls_x509_crl_t * crl_list,
    1324             :                                 int crl_list_size)
    1325             : {
    1326           1 :         int ret, i, j;
    1327           1 :         gnutls_x509_crl_t *new_crl = gnutls_malloc(crl_list_size * sizeof(gnutls_x509_crl_t));
    1328           1 :         unsigned flags = GNUTLS_TL_USE_IN_TLS;
    1329             : 
    1330           1 :         if (res->flags & GNUTLS_CERTIFICATE_VERIFY_CRLS)
    1331           0 :                 flags |= GNUTLS_TL_VERIFY_CRL|GNUTLS_TL_FAIL_ON_INVALID_CRL;
    1332             : 
    1333           1 :         if (!new_crl)
    1334             :                 return GNUTLS_E_MEMORY_ERROR;
    1335             : 
    1336           2 :         for (i = 0; i < crl_list_size; i++) {
    1337           1 :                 ret = gnutls_x509_crl_init(&new_crl[i]);
    1338           1 :                 if (ret < 0) {
    1339           0 :                         gnutls_assert();
    1340           0 :                         goto cleanup;
    1341             :                 }
    1342             : 
    1343           1 :                 ret = _gnutls_x509_crl_cpy(new_crl[i], crl_list[i]);
    1344           1 :                 if (ret < 0) {
    1345           0 :                         gnutls_assert();
    1346           0 :                         goto cleanup;
    1347             :                 }
    1348             :         }
    1349             : 
    1350           1 :         ret =
    1351           1 :             gnutls_x509_trust_list_add_crls(res->tlist, new_crl,
    1352             :                                     crl_list_size, flags, 0);
    1353           1 :         if (ret < 0) {
    1354           0 :                 gnutls_assert();
    1355           0 :                 goto cleanup;
    1356             :         }
    1357             : 
    1358           1 :         free(new_crl);
    1359           1 :         return ret;
    1360             : 
    1361           0 :       cleanup:
    1362           0 :         for (j = 0; j < i; j++)
    1363           0 :                 gnutls_x509_crl_deinit(new_crl[j]);
    1364           0 :         free(new_crl);
    1365             : 
    1366           0 :         return ret;
    1367             : }
    1368             : 
    1369             : /**
    1370             :  * gnutls_certificate_set_x509_crl_file:
    1371             :  * @res: is a #gnutls_certificate_credentials_t type.
    1372             :  * @crlfile: is a file containing the list of verified CRLs (DER or PEM list)
    1373             :  * @type: is PEM or DER
    1374             :  *
    1375             :  * This function adds the trusted CRLs in order to verify client or server
    1376             :  * certificates.  In case of a client this is not required
    1377             :  * to be called if the certificates are not verified using
    1378             :  * gnutls_certificate_verify_peers2().
    1379             :  * This function may be called multiple times.
    1380             :  *
    1381             :  * Returns: number of CRLs processed or a negative error code on error.
    1382             :  **/
    1383             : int
    1384         478 : gnutls_certificate_set_x509_crl_file(gnutls_certificate_credentials_t res,
    1385             :                                      const char *crlfile,
    1386             :                                      gnutls_x509_crt_fmt_t type)
    1387             : {
    1388         478 :         int ret;
    1389         478 :         unsigned flags = GNUTLS_TL_USE_IN_TLS;
    1390             : 
    1391         478 :         if (res->flags & GNUTLS_CERTIFICATE_VERIFY_CRLS)
    1392           1 :                 flags |= GNUTLS_TL_VERIFY_CRL|GNUTLS_TL_FAIL_ON_INVALID_CRL;
    1393             : 
    1394         478 :         ret = gnutls_x509_trust_list_add_trust_file(res->tlist, NULL, crlfile,
    1395             :                                                 type, flags, 0);
    1396         478 :         if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
    1397           0 :                 return 0;
    1398             : 
    1399             :         return ret;
    1400             : }
    1401             : 
    1402             : #include <gnutls/pkcs12.h>
    1403             : 
    1404             : 
    1405             : /**
    1406             :  * gnutls_certificate_set_x509_simple_pkcs12_file:
    1407             :  * @res: is a #gnutls_certificate_credentials_t type.
    1408             :  * @pkcs12file: filename of file containing PKCS#12 blob.
    1409             :  * @type: is PEM or DER of the @pkcs12file.
    1410             :  * @password: optional password used to decrypt PKCS#12 file, bags and keys.
    1411             :  *
    1412             :  * This function sets a certificate/private key pair and/or a CRL in
    1413             :  * the gnutls_certificate_credentials_t type.  This function may
    1414             :  * be called more than once (in case multiple keys/certificates exist
    1415             :  * for the server).
    1416             :  *
    1417             :  * PKCS#12 files with a MAC, encrypted bags and PKCS #8
    1418             :  * private keys are supported. However,
    1419             :  * only password based security, and the same password for all
    1420             :  * operations, are supported.
    1421             :  *
    1422             :  * PKCS#12 file may contain many keys and/or certificates, and this
    1423             :  * function will try to auto-detect based on the key ID the certificate
    1424             :  * and key pair to use. If the PKCS#12 file contain the issuer of
    1425             :  * the selected certificate, it will be appended to the certificate
    1426             :  * to form a chain.
    1427             :  *
    1428             :  * If more than one private keys are stored in the PKCS#12 file,
    1429             :  * then only one key will be read (and it is undefined which one).
    1430             :  *
    1431             :  * It is believed that the limitations of this function is acceptable
    1432             :  * for most usage, and that any more flexibility would introduce
    1433             :  * complexity that would make it harder to use this functionality at
    1434             :  * all.
    1435             :  *
    1436             :  * Note that, this function by default returns zero on success and a negative value on error.
    1437             :  * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
    1438             :  * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair.
    1439             :  *
    1440             :  * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
    1441             :  *
    1442             :  **/
    1443             : int
    1444           5 :  gnutls_certificate_set_x509_simple_pkcs12_file
    1445             :     (gnutls_certificate_credentials_t res, const char *pkcs12file,
    1446             :      gnutls_x509_crt_fmt_t type, const char *password) {
    1447           5 :         gnutls_datum_t p12blob;
    1448           5 :         size_t size;
    1449           5 :         int ret;
    1450             : 
    1451           5 :         p12blob.data = (void *) read_file(pkcs12file, RF_BINARY | RF_SENSITIVE,
    1452             :                                           &size);
    1453           5 :         p12blob.size = (unsigned int) size;
    1454           5 :         if (p12blob.data == NULL) {
    1455           1 :                 gnutls_assert();
    1456           1 :                 return GNUTLS_E_FILE_ERROR;
    1457             :         }
    1458             : 
    1459           4 :         ret =
    1460           4 :             gnutls_certificate_set_x509_simple_pkcs12_mem(res, &p12blob,
    1461             :                                                           type, password);
    1462           4 :         zeroize_key(p12blob.data, p12blob.size);
    1463           4 :         free(p12blob.data);
    1464           4 :         p12blob.size = 0;
    1465             : 
    1466           4 :         return ret;
    1467             : }
    1468             : 
    1469             : /**
    1470             :  * gnutls_certificate_set_x509_simple_pkcs12_mem:
    1471             :  * @res: is a #gnutls_certificate_credentials_t type.
    1472             :  * @p12blob: the PKCS#12 blob.
    1473             :  * @type: is PEM or DER of the @pkcs12file.
    1474             :  * @password: optional password used to decrypt PKCS#12 file, bags and keys.
    1475             :  *
    1476             :  * This function sets a certificate/private key pair and/or a CRL in
    1477             :  * the gnutls_certificate_credentials_t type.  This function may
    1478             :  * be called more than once (in case multiple keys/certificates exist
    1479             :  * for the server).
    1480             :  *
    1481             :  * Encrypted PKCS#12 bags and PKCS#8 private keys are supported.  However,
    1482             :  * only password based security, and the same password for all
    1483             :  * operations, are supported.
    1484             :  *
    1485             :  * PKCS#12 file may contain many keys and/or certificates, and this
    1486             :  * function will try to auto-detect based on the key ID the certificate
    1487             :  * and key pair to use. If the PKCS#12 file contain the issuer of
    1488             :  * the selected certificate, it will be appended to the certificate
    1489             :  * to form a chain.
    1490             :  *
    1491             :  * If more than one private keys are stored in the PKCS#12 file,
    1492             :  * then only one key will be read (and it is undefined which one).
    1493             :  *
    1494             :  * It is believed that the limitations of this function is acceptable
    1495             :  * for most usage, and that any more flexibility would introduce
    1496             :  * complexity that would make it harder to use this functionality at
    1497             :  * all.
    1498             :  *
    1499             :  * Note that, this function by default returns zero on success and a negative value on error.
    1500             :  * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
    1501             :  * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair.
    1502             :  *
    1503             :  * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
    1504             :  *
    1505             :  * Since: 2.8.0
    1506             :  **/
    1507             : int
    1508           4 :  gnutls_certificate_set_x509_simple_pkcs12_mem
    1509             :     (gnutls_certificate_credentials_t res, const gnutls_datum_t * p12blob,
    1510             :      gnutls_x509_crt_fmt_t type, const char *password) {
    1511           4 :         gnutls_pkcs12_t p12;
    1512           4 :         gnutls_x509_privkey_t key = NULL;
    1513           4 :         gnutls_x509_crt_t *chain = NULL;
    1514           4 :         gnutls_x509_crl_t crl = NULL;
    1515           4 :         unsigned int chain_size = 0, i;
    1516           4 :         int ret, idx;
    1517             : 
    1518           4 :         ret = gnutls_pkcs12_init(&p12);
    1519           4 :         if (ret < 0) {
    1520           0 :                 gnutls_assert();
    1521           0 :                 return ret;
    1522             :         }
    1523             : 
    1524           4 :         ret = gnutls_pkcs12_import(p12, p12blob, type, 0);
    1525           4 :         if (ret < 0) {
    1526           0 :                 gnutls_assert();
    1527           0 :                 gnutls_pkcs12_deinit(p12);
    1528           0 :                 return ret;
    1529             :         }
    1530             : 
    1531           4 :         if (password) {
    1532           4 :                 ret = gnutls_pkcs12_verify_mac(p12, password);
    1533           4 :                 if (ret < 0) {
    1534           0 :                         gnutls_assert();
    1535           0 :                         gnutls_pkcs12_deinit(p12);
    1536           0 :                         return ret;
    1537             :                 }
    1538             :         }
    1539             : 
    1540           4 :         ret =
    1541           4 :             gnutls_pkcs12_simple_parse(p12, password, &key, &chain,
    1542             :                                        &chain_size, NULL, NULL, &crl, 0);
    1543           4 :         gnutls_pkcs12_deinit(p12);
    1544           4 :         if (ret < 0) {
    1545           0 :                 gnutls_assert();
    1546           0 :                 return ret;
    1547             :         }
    1548             : 
    1549           4 :         if (key && chain) {
    1550           4 :                 ret =
    1551           4 :                     gnutls_certificate_set_x509_key(res, chain, chain_size,
    1552             :                                                     key);
    1553           4 :                 if (ret < 0) {
    1554           0 :                         gnutls_assert();
    1555           0 :                         goto done;
    1556             :                 }
    1557             : 
    1558           4 :                 idx = ret;
    1559             :         } else {
    1560           0 :                 gnutls_assert();
    1561           0 :                 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
    1562           0 :                 goto done;
    1563             :         }
    1564             : 
    1565           4 :         if (crl) {
    1566           0 :                 ret = gnutls_certificate_set_x509_crl(res, &crl, 1);
    1567           0 :                 if (ret < 0) {
    1568           0 :                         gnutls_assert();
    1569           0 :                         goto done;
    1570             :                 }
    1571             :         }
    1572             : 
    1573           4 :         if (res->flags & GNUTLS_CERTIFICATE_API_V2)
    1574             :                 ret = idx;
    1575             :         else
    1576           4 :                 ret = 0;
    1577             : 
    1578           4 :       done:
    1579           4 :         if (chain) {
    1580           9 :                 for (i = 0; i < chain_size; i++)
    1581           5 :                         gnutls_x509_crt_deinit(chain[i]);
    1582           4 :                 gnutls_free(chain);
    1583             :         }
    1584           4 :         if (key)
    1585           4 :                 gnutls_x509_privkey_deinit(key);
    1586           4 :         if (crl)
    1587           0 :                 gnutls_x509_crl_deinit(crl);
    1588             : 
    1589             :         return ret;
    1590             : }
    1591             : 
    1592             : 
    1593             : 
    1594             : /**
    1595             :  * gnutls_certificate_free_crls:
    1596             :  * @sc: is a #gnutls_certificate_credentials_t type.
    1597             :  *
    1598             :  * This function will delete all the CRLs associated
    1599             :  * with the given credentials.
    1600             :  **/
    1601           0 : void gnutls_certificate_free_crls(gnutls_certificate_credentials_t sc)
    1602             : {
    1603             :         /* do nothing for now */
    1604           0 :         return;
    1605             : }
    1606             : 
    1607             : /**
    1608             :  * gnutls_certificate_credentials_t:
    1609             :  * @cred: is a #gnutls_certificate_credentials_t type.
    1610             :  * @fn: A PIN callback
    1611             :  * @userdata: Data to be passed in the callback
    1612             :  *
    1613             :  * This function will set a callback function to be used when
    1614             :  * required to access a protected object. This function overrides any other
    1615             :  * global PIN functions.
    1616             :  *
    1617             :  * Note that this function must be called right after initialization
    1618             :  * to have effect.
    1619             :  *
    1620             :  * Since: 3.1.0
    1621             :  **/
    1622         275 : void gnutls_certificate_set_pin_function(gnutls_certificate_credentials_t
    1623             :                                          cred, gnutls_pin_callback_t fn,
    1624             :                                          void *userdata)
    1625             : {
    1626         275 :         cred->pin.cb = fn;
    1627         275 :         cred->pin.data = userdata;
    1628         275 : }

Generated by: LCOV version 1.14