LCOV - code coverage report
Current view: top level - src/libvalent/device - valent-certificate.c (source / functions) Coverage Total Hit
Test: Code Coverage Lines: 86.1 % 165 142
Test Date: 2024-05-12 19:03:18 Functions: 100.0 % 8 8
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 49.1 % 116 57

             Branch data     Line data    Source code
       1                 :             : // SPDX-License-Identifier: GPL-3.0-or-later
       2                 :             : // SPDX-FileCopyrightText: Andy Holmes <andrew.g.r.holmes@gmail.com>
       3                 :             : 
       4                 :             : #define G_LOG_DOMAIN "valent-certificate"
       5                 :             : 
       6                 :             : #include "config.h"
       7                 :             : 
       8                 :             : #include <time.h>
       9                 :             : 
      10                 :             : #include <gio/gio.h>
      11                 :             : #include <gnutls/gnutls.h>
      12                 :             : #include <gnutls/abstract.h>
      13                 :             : #include <gnutls/x509.h>
      14                 :             : 
      15                 :             : #include <libvalent-core.h>
      16                 :             : #include "valent-certificate.h"
      17                 :             : #include "valent-device.h"
      18                 :             : 
      19                 :             : #define DEFAULT_EXPIRATION (60L*60L*24L*10L*365L)
      20                 :             : #define DEFAULT_KEY_SIZE   4096
      21                 :             : 
      22                 :             : #define SHA256_HEX_LEN 64
      23                 :             : #define SHA256_STR_LEN 96
      24                 :             : 
      25                 :             : 
      26                 :             : /**
      27                 :             :  * valent_certificate_generate:
      28                 :             :  * @cert_path: (type filename): file path to the certificate
      29                 :             :  * @key_path: (type filename): file path to the private key
      30                 :             :  * @common_name: common name for the certificate
      31                 :             :  * @error: (nullable): a `GError`
      32                 :             :  *
      33                 :             :  * Generate a private key and certificate for @common_name, saving them at
      34                 :             :  * @key_path and @cert_path respectively.
      35                 :             :  *
      36                 :             :  * Returns: %TRUE if successful, or %FALSE with @error set
      37                 :             :  *
      38                 :             :  * Since: 1.0
      39                 :             :  */
      40                 :             : static gboolean
      41                 :          24 : valent_certificate_generate (const char  *cert_path,
      42                 :             :                              const char  *key_path,
      43                 :             :                              const char  *common_name,
      44                 :             :                              GError     **error)
      45                 :             : {
      46                 :          48 :   g_autofree char *dn = NULL;
      47                 :          24 :   gnutls_x509_privkey_t privkey = NULL;
      48                 :          24 :   gnutls_x509_crt_t crt = NULL;
      49                 :          24 :   gnutls_datum_t out;
      50                 :          24 :   time_t timestamp;
      51                 :          24 :   unsigned int serial;
      52                 :          24 :   int rc;
      53                 :          24 :   gboolean ret = FALSE;
      54                 :             : 
      55                 :          24 :   VALENT_ENTRY;
      56                 :             : 
      57                 :             :   /*
      58                 :             :    * Private Key
      59                 :             :    */
      60         [ +  - ]:          24 :   if ((rc = gnutls_x509_privkey_init (&privkey)) != GNUTLS_E_SUCCESS ||
      61         [ +  - ]:          24 :       (rc = gnutls_x509_privkey_generate (privkey,
      62                 :             :                                           GNUTLS_PK_RSA,
      63                 :             :                                           DEFAULT_KEY_SIZE,
      64                 :          24 :                                           0)) != GNUTLS_E_SUCCESS ||
      65         [ -  + ]:          24 :       (rc = gnutls_x509_privkey_export2 (privkey,
      66                 :             :                                          GNUTLS_X509_FMT_PEM,
      67                 :             :                                          &out)) != GNUTLS_E_SUCCESS)
      68                 :             :     {
      69                 :           0 :       g_set_error (error,
      70                 :             :                    G_IO_ERROR,
      71                 :             :                    G_IO_ERROR_FAILED,
      72                 :             :                    "Generating private key: %s",
      73                 :             :                    gnutls_strerror (rc));
      74                 :           0 :       VALENT_GOTO (out);
      75                 :             :     }
      76                 :             : 
      77                 :             :   /* Output the private key PEM to file */
      78                 :          48 :   ret = g_file_set_contents_full (key_path,
      79                 :          24 :                                   (const char *)out.data,
      80                 :          24 :                                   out.size,
      81                 :             :                                   G_FILE_SET_CONTENTS_DURABLE,
      82                 :             :                                   0600,
      83                 :             :                                   error);
      84                 :          24 :   gnutls_free (out.data);
      85                 :             : 
      86         [ -  + ]:          24 :   if (!ret)
      87                 :           0 :     VALENT_GOTO (out);
      88                 :             : 
      89                 :             :   /*
      90                 :             :    * TLS Certificate
      91                 :             :    */
      92         [ +  - ]:          24 :   if ((rc = gnutls_x509_crt_init (&crt)) != GNUTLS_E_SUCCESS ||
      93         [ +  - ]:          24 :       (rc = gnutls_x509_crt_set_key (crt, privkey)) != GNUTLS_E_SUCCESS ||
      94         [ -  + ]:          24 :       (rc = gnutls_x509_crt_set_version (crt, 3)) != GNUTLS_E_SUCCESS)
      95                 :             :     {
      96                 :           0 :       g_set_error (error,
      97                 :             :                    G_IO_ERROR,
      98                 :             :                    G_IO_ERROR_FAILED,
      99                 :             :                    "Generating certificate: %s",
     100                 :             :                    gnutls_strerror (rc));
     101                 :           0 :       VALENT_GOTO (out);
     102                 :             :     }
     103                 :             : 
     104                 :             :   /* Expiry (10 years) */
     105                 :          24 :   timestamp = time (NULL);
     106                 :             : 
     107         [ +  - ]:          24 :   if ((rc = gnutls_x509_crt_set_activation_time (crt, timestamp)) != GNUTLS_E_SUCCESS ||
     108         [ -  + ]:          24 :       (rc = gnutls_x509_crt_set_expiration_time (crt, timestamp + DEFAULT_EXPIRATION)) != GNUTLS_E_SUCCESS)
     109                 :             :     {
     110                 :           0 :       g_set_error (error,
     111                 :             :                    G_IO_ERROR,
     112                 :             :                    G_IO_ERROR_FAILED,
     113                 :             :                    "Generating certificate: %s",
     114                 :             :                    gnutls_strerror (rc));
     115                 :           0 :       VALENT_GOTO (out);
     116                 :             :     }
     117                 :             : 
     118                 :             :   /* Serial Number */
     119                 :          24 :   serial = GUINT32_TO_BE (10);
     120                 :          24 :   gnutls_x509_crt_set_serial (crt, &serial, sizeof (unsigned int));
     121                 :             : 
     122                 :             :   /* Distinguished Name (RFC4514) */
     123                 :          24 :   dn = g_strdup_printf ("O=%s,OU=%s,CN=%s", "Valent", "Valent", common_name);
     124                 :             : 
     125         [ -  + ]:          24 :   if ((rc = gnutls_x509_crt_set_dn (crt, dn, NULL)) != GNUTLS_E_SUCCESS)
     126                 :             :     {
     127                 :           0 :       g_set_error (error,
     128                 :             :                    G_IO_ERROR,
     129                 :             :                    G_IO_ERROR_FAILED,
     130                 :             :                    "Generating certificate: %s",
     131                 :             :                    gnutls_strerror (rc));
     132                 :           0 :       VALENT_GOTO (out);
     133                 :             :     }
     134                 :             : 
     135                 :             :   /* Sign and export the certificate */
     136         [ +  - ]:          24 :   if ((rc = gnutls_x509_crt_sign2 (crt, crt, privkey, GNUTLS_DIG_SHA256, 0)) != GNUTLS_E_SUCCESS ||
     137         [ -  + ]:          24 :       (rc = gnutls_x509_crt_export2 (crt, GNUTLS_X509_FMT_PEM, &out)) != GNUTLS_E_SUCCESS)
     138                 :             :     {
     139                 :           0 :       g_set_error (error,
     140                 :             :                    G_IO_ERROR,
     141                 :             :                    G_IO_ERROR_FAILED,
     142                 :             :                    "Signing certificate: %s",
     143                 :             :                    gnutls_strerror (rc));
     144                 :           0 :       VALENT_GOTO (out);
     145                 :             :     }
     146                 :             : 
     147                 :             :   /* Output the certificate PEM to file */
     148                 :          48 :   ret = g_file_set_contents_full (cert_path,
     149                 :          24 :                                   (const char *)out.data,
     150                 :          24 :                                   out.size,
     151                 :             :                                   G_FILE_SET_CONTENTS_DURABLE,
     152                 :             :                                   0600,
     153                 :             :                                   error);
     154                 :          24 :   gnutls_free (out.data);
     155                 :             : 
     156                 :          24 :   out:
     157                 :          24 :     gnutls_x509_crt_deinit (crt);
     158                 :          24 :     gnutls_x509_privkey_deinit (privkey);
     159                 :             : 
     160                 :          24 :   VALENT_RETURN (ret);
     161                 :             : }
     162                 :             : 
     163                 :             : static void
     164                 :           1 : valent_certificate_new_task (GTask        *task,
     165                 :             :                              gpointer      source_object,
     166                 :             :                              gpointer      task_data,
     167                 :             :                              GCancellable *cancellable)
     168                 :             : {
     169                 :           1 :   g_autoptr (GTlsCertificate) certificate = NULL;
     170                 :           1 :   const char *path = task_data;
     171                 :           1 :   GError *error = NULL;
     172                 :             : 
     173         [ -  + ]:           1 :   if ((certificate = valent_certificate_new_sync (path, &error)) == NULL)
     174                 :           0 :     return g_task_return_error (task, error);
     175                 :             : 
     176                 :           1 :   g_task_return_pointer (task, g_steal_pointer (&certificate), g_object_unref);
     177                 :             : }
     178                 :             : 
     179                 :             : /**
     180                 :             :  * valent_certificate_new:
     181                 :             :  * @path: (type filename): a directory path
     182                 :             :  * @cancellable: (nullable): `GCancellable`
     183                 :             :  * @callback: (scope async): a `GAsyncReadyCallback`
     184                 :             :  * @user_data: (closure): user supplied data
     185                 :             :  *
     186                 :             :  * Get a TLS certificate and private key pair.
     187                 :             :  *
     188                 :             :  * This ensures a TLS certificate with the filename `certificate.pem` and
     189                 :             :  * private key with filename `private.pem` exist in a directory at @path.
     190                 :             :  *
     191                 :             :  * If either one doesn't exist, a new certificate and private key pair will be
     192                 :             :  * generated. The common name will be set to a string returned by
     193                 :             :  * [func@GLib.uuid_string_random].
     194                 :             :  *
     195                 :             :  * Get the result with [func@Valent.certificate_new_finish].
     196                 :             :  *
     197                 :             :  * Since: 1.0
     198                 :             :  */
     199                 :             : void
     200                 :           1 : valent_certificate_new (const char          *path,
     201                 :             :                         GCancellable        *cancellable,
     202                 :             :                         GAsyncReadyCallback  callback,
     203                 :             :                         gpointer             user_data)
     204                 :             : {
     205                 :           2 :   g_autoptr (GTask) task = NULL;
     206                 :             : 
     207   [ +  -  +  - ]:           1 :   g_return_if_fail (path != NULL && *path != '\0');
     208   [ -  +  -  -  :           1 :   g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
             -  -  -  - ]
     209                 :             : 
     210                 :           1 :   task = g_task_new (NULL, cancellable, callback, user_data);
     211         [ +  - ]:           1 :   g_task_set_source_tag (task, valent_certificate_new);
     212         [ -  + ]:           2 :   g_task_set_task_data (task, g_strdup (path), g_free);
     213         [ +  - ]:           1 :   g_task_run_in_thread (task, valent_certificate_new_task);
     214                 :             : }
     215                 :             : 
     216                 :             : /**
     217                 :             :  * valent_certificate_new_finish:
     218                 :             :  * @result: a `GAsyncResult` provided to callback
     219                 :             :  * @error: (nullable): a `GError`
     220                 :             :  *
     221                 :             :  * Finish an operation started by [func@Valent.certificate_new].
     222                 :             :  *
     223                 :             :  * If either generating or loading the certificate failed, %NULL will be
     224                 :             :  * returned with @error set.
     225                 :             :  *
     226                 :             :  * Returns: (transfer full) (nullable): a `GTlsCertificate`
     227                 :             :  *
     228                 :             :  * Since: 1.0
     229                 :             :  */
     230                 :             : GTlsCertificate *
     231                 :           1 : valent_certificate_new_finish (GAsyncResult  *result,
     232                 :             :                                GError       **error)
     233                 :             : {
     234         [ +  - ]:           1 :   g_return_val_if_fail (g_task_is_valid (result, NULL), NULL);
     235                 :             : 
     236                 :           1 :   return g_task_propagate_pointer (G_TASK (result), error);
     237                 :             : }
     238                 :             : 
     239                 :             : /**
     240                 :             :  * valent_certificate_new_sync:
     241                 :             :  * @path: (type filename): a directory path
     242                 :             :  * @error: (nullable): a `GError`
     243                 :             :  *
     244                 :             :  * Get a TLS certificate and private key pair.
     245                 :             :  *
     246                 :             :  * This ensures a TLS certificate with the filename `certificate.pem` and
     247                 :             :  * private key with filename `private.pem` exist in a directory at @path.
     248                 :             :  *
     249                 :             :  * If either one doesn't exist, a new certificate and private key pair will be
     250                 :             :  * generated. The common name will be set to a string returned by
     251                 :             :  * [func@Valent.Device.generate_id].
     252                 :             :  *
     253                 :             :  * If either generating or loading the certificate fails, %NULL will be returned
     254                 :             :  * with @error set.
     255                 :             :  *
     256                 :             :  * Returns: (transfer full) (nullable): a `GTlsCertificate`
     257                 :             :  *
     258                 :             :  * Since: 1.0
     259                 :             :  */
     260                 :             : GTlsCertificate *
     261                 :          24 : valent_certificate_new_sync (const char  *path,
     262                 :             :                              GError     **error)
     263                 :             : {
     264                 :          48 :   g_autofree char *cert_path = NULL;
     265                 :          24 :   g_autofree char *key_path = NULL;
     266                 :             : 
     267   [ +  -  +  - ]:          24 :   g_return_val_if_fail (path != NULL && *path != '\0', NULL);
     268   [ +  +  -  + ]:          24 :   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
     269                 :             : 
     270                 :          24 :   cert_path = g_build_filename (path, "certificate.pem", NULL);
     271                 :          24 :   key_path = g_build_filename (path, "private.pem", NULL);
     272                 :             : 
     273   [ -  +  -  - ]:          24 :   if (!g_file_test (cert_path, G_FILE_TEST_IS_REGULAR) ||
     274                 :           0 :       !g_file_test (key_path, G_FILE_TEST_IS_REGULAR))
     275                 :             :     {
     276                 :          24 :       g_autofree char *cn = NULL;
     277                 :             : 
     278                 :          24 :       cn = valent_device_generate_id ();
     279                 :             : 
     280         [ -  + ]:          24 :       if (!valent_certificate_generate (cert_path, key_path, cn, error))
     281                 :           0 :         return FALSE;
     282                 :             :     }
     283                 :             : 
     284                 :          24 :   return g_tls_certificate_new_from_files (cert_path, key_path, error);
     285                 :             : }
     286                 :             : 
     287                 :             : /**
     288                 :             :  * valent_certificate_get_common_name:
     289                 :             :  * @certificate: a `GTlsCertificate`
     290                 :             :  *
     291                 :             :  * Get the common name from @certificate, which by convention in KDE Connect is
     292                 :             :  * the single source of truth for a device's ID.
     293                 :             :  *
     294                 :             :  * Returns: (transfer none) (nullable): the certificate ID
     295                 :             :  *
     296                 :             :  * Since: 1.0
     297                 :             :  */
     298                 :             : const char *
     299                 :          49 : valent_certificate_get_common_name (GTlsCertificate *certificate)
     300                 :             : {
     301                 :          98 :   g_autoptr (GByteArray) certificate_der = NULL;
     302                 :          49 :   gnutls_x509_crt_t crt;
     303                 :          49 :   gnutls_datum_t crt_der;
     304                 :          49 :   char buf[64] = { 0, };
     305                 :          49 :   size_t buf_size = 64;
     306                 :          49 :   const char *device_id;
     307                 :          49 :   int rc;
     308                 :             : 
     309   [ +  -  +  -  :          49 :   g_return_val_if_fail (G_IS_TLS_CERTIFICATE (certificate), NULL);
             +  -  -  + ]
     310                 :             : 
     311                 :             :   /* Check */
     312                 :          49 :   device_id = g_object_get_data (G_OBJECT (certificate),
     313                 :             :                                  "valent-certificate-cn");
     314                 :             : 
     315         [ +  + ]:          49 :   if G_LIKELY (device_id != NULL)
     316                 :             :     return device_id;
     317                 :             : 
     318                 :             :   /* Extract the common name */
     319                 :          29 :   g_object_get (certificate, "certificate", &certificate_der, NULL);
     320                 :          29 :   crt_der.data = certificate_der->data;
     321                 :          29 :   crt_der.size = certificate_der->len;
     322                 :             : 
     323         [ +  - ]:          29 :   if ((rc = gnutls_x509_crt_init (&crt)) != GNUTLS_E_SUCCESS ||
     324         [ +  - ]:          29 :       (rc = gnutls_x509_crt_import (crt, &crt_der, 0)) != GNUTLS_E_SUCCESS ||
     325         [ -  + ]:          29 :       (rc = gnutls_x509_crt_get_dn_by_oid (crt,
     326                 :             :                                            GNUTLS_OID_X520_COMMON_NAME,
     327                 :             :                                            0,
     328                 :             :                                            0,
     329                 :             :                                            &buf,
     330                 :             :                                            &buf_size)) != GNUTLS_E_SUCCESS)
     331                 :             :     {
     332                 :           0 :       g_warning ("%s(): %s", G_STRFUNC, gnutls_strerror (rc));
     333                 :           0 :       gnutls_x509_crt_deinit (crt);
     334                 :             : 
     335                 :           0 :       return NULL;
     336                 :             :     }
     337                 :             : 
     338                 :          29 :   gnutls_x509_crt_deinit (crt);
     339                 :             : 
     340                 :             :   /* Intern the id as private data */
     341                 :          29 :   g_object_set_data_full (G_OBJECT (certificate),
     342                 :             :                           "valent-certificate-cn",
     343                 :          29 :                           g_strndup (buf, buf_size),
     344                 :             :                           g_free);
     345                 :             : 
     346                 :          29 :   return g_object_get_data (G_OBJECT (certificate), "valent-certificate-cn");
     347                 :             : }
     348                 :             : 
     349                 :             : /**
     350                 :             :  * valent_certificate_get_fingerprint:
     351                 :             :  * @certificate: a `GTlsCertificate`
     352                 :             :  *
     353                 :             :  * Get a SHA256 fingerprint hash of @certificate.
     354                 :             :  *
     355                 :             :  * Returns: (transfer none): a SHA256 hash
     356                 :             :  *
     357                 :             :  * Since: 1.0
     358                 :             :  */
     359                 :             : const char *
     360                 :           1 : valent_certificate_get_fingerprint (GTlsCertificate *certificate)
     361                 :             : {
     362                 :           2 :   g_autoptr (GByteArray) certificate_der = NULL;
     363         [ +  - ]:           1 :   g_autoptr (GChecksum) checksum = NULL;
     364                 :           1 :   const char *check;
     365                 :           1 :   const char *fingerprint;
     366                 :           1 :   char buf[SHA256_STR_LEN] = { 0, };
     367                 :           1 :   unsigned int i = 0;
     368                 :           1 :   unsigned int o = 0;
     369                 :             : 
     370   [ +  -  +  -  :           1 :   g_return_val_if_fail (G_IS_TLS_CERTIFICATE (certificate), NULL);
             +  -  -  + ]
     371                 :             : 
     372                 :           1 :   fingerprint = g_object_get_data (G_OBJECT (certificate),
     373                 :             :                                    "valent-certificate-fp");
     374                 :             : 
     375         [ +  - ]:           1 :   if G_LIKELY (fingerprint != NULL)
     376                 :             :     return fingerprint;
     377                 :             : 
     378                 :           1 :   g_object_get (certificate, "certificate", &certificate_der, NULL);
     379                 :           1 :   checksum = g_checksum_new (G_CHECKSUM_SHA256);
     380                 :           1 :   g_checksum_update (checksum, certificate_der->data, certificate_der->len);
     381                 :             : 
     382                 :           1 :   check = g_checksum_get_string (checksum);
     383                 :             : 
     384         [ +  + ]:          33 :   while (i < SHA256_HEX_LEN)
     385                 :             :     {
     386                 :          32 :       buf[o++] = check[i++];
     387                 :          32 :       buf[o++] = check[i++];
     388                 :          32 :       buf[o++] = ':';
     389                 :             :     }
     390                 :           1 :   buf[SHA256_STR_LEN - 1] = '\0';
     391                 :             : 
     392                 :             :   /* Intern the hash as private data */
     393         [ -  + ]:           1 :   g_object_set_data_full (G_OBJECT (certificate),
     394                 :             :                           "valent-certificate-fp",
     395                 :           1 :                           g_strdup (buf),
     396                 :             :                           g_free);
     397                 :             : 
     398                 :           1 :   return g_object_get_data (G_OBJECT (certificate), "valent-certificate-fp");
     399                 :             : }
     400                 :             : 
     401                 :             : /**
     402                 :             :  * valent_certificate_get_public_key:
     403                 :             :  * @certificate: a `GTlsCertificate`
     404                 :             :  *
     405                 :             :  * Get the public key of @certificate.
     406                 :             :  *
     407                 :             :  * Returns: (transfer none): a DER-encoded publickey
     408                 :             :  *
     409                 :             :  * Since: 1.0
     410                 :             :  */
     411                 :             : GByteArray *
     412                 :           5 : valent_certificate_get_public_key (GTlsCertificate *certificate)
     413                 :             : {
     414                 :          10 :   g_autoptr (GByteArray) certificate_der = NULL;
     415         [ +  - ]:           5 :   g_autoptr (GByteArray) pubkey = NULL;
     416                 :           5 :   size_t size;
     417                 :           5 :   gnutls_x509_crt_t crt = NULL;
     418                 :           5 :   gnutls_datum_t crt_der;
     419                 :           5 :   gnutls_pubkey_t crt_pk = NULL;
     420                 :           5 :   int rc;
     421                 :             : 
     422   [ +  -  +  -  :           5 :   g_return_val_if_fail (G_IS_TLS_CERTIFICATE (certificate), NULL);
             +  -  -  + ]
     423                 :             : 
     424                 :           5 :   pubkey = g_object_get_data (G_OBJECT (certificate),
     425                 :             :                               "valent-certificate-pk");
     426                 :             : 
     427         [ +  - ]:           5 :   if (pubkey != NULL)
     428                 :             :     return g_steal_pointer (&pubkey);
     429                 :             : 
     430                 :           5 :   g_object_get (certificate, "certificate", &certificate_der, NULL);
     431                 :           5 :   crt_der.data = certificate_der->data;
     432                 :           5 :   crt_der.size = certificate_der->len;
     433                 :             : 
     434                 :             :   /* Load the certificate */
     435         [ +  - ]:           5 :   if ((rc = gnutls_x509_crt_init (&crt)) != GNUTLS_E_SUCCESS ||
     436         [ -  + ]:           5 :       (rc = gnutls_x509_crt_import (crt, &crt_der, GNUTLS_X509_FMT_DER)) != GNUTLS_E_SUCCESS)
     437                 :             :     {
     438                 :           0 :       g_warning ("%s(): %s", G_STRFUNC, gnutls_strerror (rc));
     439                 :           0 :       VALENT_GOTO (out);
     440                 :             :     }
     441                 :             : 
     442                 :             :   /* Load the public key */
     443         [ +  - ]:           5 :   if ((rc = gnutls_pubkey_init (&crt_pk)) != GNUTLS_E_SUCCESS ||
     444         [ -  + ]:           5 :       (rc = gnutls_pubkey_import_x509 (crt_pk, crt, 0)) != GNUTLS_E_SUCCESS)
     445                 :             :     {
     446                 :           0 :       g_warning ("%s(): %s", G_STRFUNC, gnutls_strerror (rc));
     447                 :           0 :       VALENT_GOTO (out);
     448                 :             :     }
     449                 :             : 
     450                 :             :   /* Read the public key */
     451                 :           5 :   rc = gnutls_pubkey_export (crt_pk, GNUTLS_X509_FMT_DER, NULL, &size);
     452                 :             : 
     453         [ +  - ]:           5 :   if (rc == GNUTLS_E_SUCCESS || rc == GNUTLS_E_SHORT_MEMORY_BUFFER)
     454                 :             :     {
     455                 :           5 :       pubkey = g_byte_array_sized_new (size);
     456                 :           5 :       pubkey->len = size;
     457                 :          10 :       rc = gnutls_pubkey_export (crt_pk,
     458                 :             :                                  GNUTLS_X509_FMT_DER,
     459                 :           5 :                                  pubkey->data, &size);
     460                 :             : 
     461                 :             :       /* Intern the DER as private data */
     462         [ +  - ]:           5 :       if (rc == GNUTLS_E_SUCCESS)
     463                 :             :         {
     464                 :           5 :           g_object_set_data_full (G_OBJECT (certificate),
     465                 :             :                                   "valent-certificate-pk",
     466                 :             :                                   g_steal_pointer (&pubkey),
     467                 :             :                                   (GDestroyNotify)g_byte_array_unref);
     468                 :             :         }
     469                 :             :       else
     470                 :           0 :         g_warning ("%s(): %s", G_STRFUNC, gnutls_strerror (rc));
     471                 :             :     }
     472                 :             :   else
     473                 :           0 :     g_warning ("%s(): %s", G_STRFUNC, gnutls_strerror (rc));
     474                 :             : 
     475                 :           5 :   out:
     476                 :           5 :     gnutls_x509_crt_deinit (crt);
     477                 :           5 :     gnutls_pubkey_deinit (crt_pk);
     478                 :             : 
     479                 :           5 :   return g_object_get_data (G_OBJECT (certificate), "valent-certificate-pk");
     480                 :             : }
     481                 :             : 
        

Generated by: LCOV version 2.0-1