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

Generated by: LCOV version 2.0-1