LCOV - code coverage report
Current view: top level - gcr - gcr-trust.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 275 297 92.6 %
Date: 2022-09-04 10:20:22 Functions: 31 31 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 142 278 51.1 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * gnome-keyring
       3                 :            :  *
       4                 :            :  * Copyright (C) 2010 Collabora Ltd
       5                 :            :  *
       6                 :            :  * This program is free software; you can redistribute it and/or modify
       7                 :            :  * it under the terms of the GNU Lesser General Public License as
       8                 :            :  * published by the Free Software Foundation; either version 2.1 of
       9                 :            :  * the License, or (at your option) any later version.
      10                 :            :  *
      11                 :            :  * This program is distributed in the hope that it will be useful, but
      12                 :            :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      13                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14                 :            :  * Lesser General Public License for more details.
      15                 :            :  *
      16                 :            :  * You should have received a copy of the GNU Lesser General Public
      17                 :            :  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
      18                 :            :  *
      19                 :            :  * Author: Stef Walter <stefw@collabora.co.uk>
      20                 :            :  */
      21                 :            : 
      22                 :            : #include "config.h"
      23                 :            : 
      24                 :            : #include "gcr-types.h"
      25                 :            : #include "gcr-internal.h"
      26                 :            : #include "gcr-library.h"
      27                 :            : #include "gcr-trust.h"
      28                 :            : 
      29                 :            : #include "gck/gck.h"
      30                 :            : #include "gck/pkcs11n.h"
      31                 :            : #include "gck/pkcs11i.h"
      32                 :            : #include "gck/pkcs11x.h"
      33                 :            : 
      34                 :            : #include <glib/gi18n-lib.h>
      35                 :            : 
      36                 :            : /**
      37                 :            :  * GCR_PURPOSE_SERVER_AUTH:
      38                 :            :  *
      39                 :            :  * The purpose used to verify the server certificate in a TLS connection. This
      40                 :            :  * is the most common purpose in use.
      41                 :            :  */
      42                 :            : 
      43                 :            : /**
      44                 :            :  * GCR_PURPOSE_CLIENT_AUTH:
      45                 :            :  *
      46                 :            :  * The purpose used to verify the client certificate in a TLS connection.
      47                 :            :  */
      48                 :            : 
      49                 :            : /**
      50                 :            :  * GCR_PURPOSE_CODE_SIGNING:
      51                 :            :  *
      52                 :            :  * The purpose used to verify certificate used for the signature on signed code.
      53                 :            :  */
      54                 :            : 
      55                 :            : /**
      56                 :            :  * GCR_PURPOSE_EMAIL:
      57                 :            :  *
      58                 :            :  * The purpose used to verify certificates that are used in email communication
      59                 :            :  * such as S/MIME.
      60                 :            :  */
      61                 :            : 
      62                 :            : /* ----------------------------------------------------------------------------------
      63                 :            :  * HELPERS
      64                 :            :  */
      65                 :            : 
      66                 :            : static void
      67                 :         25 : prepare_trust_attrs (GcrCertificate *certificate,
      68                 :            :                      CK_X_ASSERTION_TYPE type,
      69                 :            :                      GckBuilder *builder)
      70                 :            : {
      71                 :            :         gconstpointer data;
      72                 :            :         gsize n_data;
      73                 :            : 
      74                 :         25 :         gck_builder_add_ulong (builder, CKA_CLASS, CKO_X_TRUST_ASSERTION);
      75                 :         25 :         gck_builder_add_ulong (builder, CKA_X_ASSERTION_TYPE, type);
      76                 :            : 
      77                 :         25 :         data = gcr_certificate_get_der_data (certificate, &n_data);
      78         [ -  + ]:         25 :         g_return_if_fail (data);
      79                 :         25 :         gck_builder_add_data (builder, CKA_X_CERTIFICATE_VALUE, data, n_data);
      80                 :            : }
      81                 :            : 
      82                 :            : /* ----------------------------------------------------------------------------------
      83                 :            :  * GET PINNED CERTIFICATE
      84                 :            :  */
      85                 :            : 
      86                 :            : static GckAttributes *
      87                 :         10 : prepare_is_certificate_pinned (GcrCertificate *certificate, const gchar *purpose, const gchar *peer)
      88                 :            : {
      89                 :         10 :         GckBuilder builder = GCK_BUILDER_INIT;
      90                 :            : 
      91                 :         10 :         prepare_trust_attrs (certificate, CKT_X_PINNED_CERTIFICATE, &builder);
      92                 :            : 
      93                 :         10 :         gck_builder_add_string (&builder, CKA_X_PURPOSE, purpose);
      94                 :         10 :         gck_builder_add_string (&builder, CKA_X_PEER, peer);
      95                 :            : 
      96                 :         10 :         return gck_builder_end (&builder);
      97                 :            : }
      98                 :            : 
      99                 :            : static gboolean
     100                 :         10 : perform_is_certificate_pinned (GckAttributes *search,
     101                 :            :                                GCancellable *cancellable,
     102                 :            :                                GError **error)
     103                 :            : {
     104                 :            :         GckEnumerator *en;
     105                 :            :         GList *slots;
     106                 :            :         GckObject *object;
     107                 :            : 
     108         [ -  + ]:         10 :         if (!gcr_pkcs11_initialize (cancellable, error))
     109                 :          0 :                 return FALSE;
     110                 :            : 
     111                 :         10 :         slots = gcr_pkcs11_get_trust_lookup_slots ();
     112                 :         10 :         g_debug ("searching for pinned certificate in %d slots",
     113                 :            :                  g_list_length (slots));
     114                 :         10 :         en = gck_slots_enumerate_objects (slots, search, 0);
     115   [ +  -  +  - ]:         10 :         g_clear_list (&slots, g_object_unref);
     116                 :            : 
     117                 :         10 :         object = gck_enumerator_next (en, cancellable, error);
     118                 :         10 :         g_object_unref (en);
     119                 :            : 
     120         [ +  + ]:         10 :         if (object)
     121                 :          5 :                 g_object_unref (object);
     122                 :            : 
     123         [ +  + ]:         10 :         g_debug ("%s certificate anchor", object ? "found" : "did not find");
     124                 :         10 :         return (object != NULL);
     125                 :            : }
     126                 :            : 
     127                 :            : /**
     128                 :            :  * gcr_trust_is_certificate_pinned:
     129                 :            :  * @certificate: a #GcrCertificate to check
     130                 :            :  * @purpose: the purpose string
     131                 :            :  * @peer: the peer for this pinned
     132                 :            :  * @cancellable: a #GCancellable
     133                 :            :  * @error: a #GError, or %NULL
     134                 :            :  *
     135                 :            :  * Check if @certificate is pinned for @purpose to communicate with @peer.
     136                 :            :  * A pinned certificate overrides all other certificate verification.
     137                 :            :  *
     138                 :            :  * This call may block, see gcr_trust_is_certificate_pinned_async() for the
     139                 :            :  * non-blocking version.
     140                 :            :  *
     141                 :            :  * In the case of an error, %FALSE is also returned. Check @error to detect
     142                 :            :  * if an error occurred.
     143                 :            :  *
     144                 :            :  * Returns: %TRUE if the certificate is pinned for the host and purpose
     145                 :            :  */
     146                 :            : gboolean
     147                 :          6 : gcr_trust_is_certificate_pinned (GcrCertificate *certificate, const gchar *purpose,
     148                 :            :                                  const gchar *peer, GCancellable *cancellable, GError **error)
     149                 :            : {
     150                 :            :         GckAttributes *search;
     151                 :            :         gboolean ret;
     152                 :            : 
     153   [ -  +  +  -  :          6 :         g_return_val_if_fail (GCR_IS_CERTIFICATE (certificate), FALSE);
             -  +  -  + ]
     154         [ -  + ]:          6 :         g_return_val_if_fail (purpose, FALSE);
     155         [ -  + ]:          6 :         g_return_val_if_fail (peer, FALSE);
     156                 :            : 
     157                 :          6 :         search = prepare_is_certificate_pinned (certificate, purpose, peer);
     158         [ -  + ]:          6 :         g_return_val_if_fail (search, FALSE);
     159                 :            : 
     160                 :          6 :         ret = perform_is_certificate_pinned (search, cancellable, error);
     161                 :          6 :         gck_attributes_unref (search);
     162                 :            : 
     163                 :          6 :         return ret;
     164                 :            : }
     165                 :            : 
     166                 :            : static void
     167                 :          4 : thread_is_certificate_pinned (GTask *task, gpointer object,
     168                 :            :                               gpointer task_data, GCancellable *cancellable)
     169                 :            : {
     170                 :          4 :         GckAttributes *attrs = task_data;
     171                 :          4 :         GError *error = NULL;
     172                 :            :         gboolean found;
     173                 :            : 
     174                 :          4 :         found = perform_is_certificate_pinned (attrs, cancellable, &error);
     175         [ +  - ]:          4 :         if (error == NULL)
     176                 :          4 :                 g_task_return_boolean (task, found);
     177                 :            :         else
     178                 :          0 :                 g_task_return_error (task, g_steal_pointer (&error));
     179                 :          4 : }
     180                 :            : 
     181                 :            : /**
     182                 :            :  * gcr_trust_is_certificate_pinned_async:
     183                 :            :  * @certificate: a #GcrCertificate to check
     184                 :            :  * @purpose: the purpose string
     185                 :            :  * @peer: the peer for this pinned
     186                 :            :  * @cancellable: a #GCancellable
     187                 :            :  * @callback: a #GAsyncReadyCallback to call when the operation completes
     188                 :            :  * @user_data: the data to pass to callback function
     189                 :            :  *
     190                 :            :  * Check if @certificate is pinned for @purpose to communicate with @peer. A
     191                 :            :  * pinned certificate overrides all other certificate verification.
     192                 :            :  *
     193                 :            :  * When the operation is finished, callback will be called. You can then call
     194                 :            :  * [func@Gcr.trust_is_certificate_pinned_finish] to get the result of the
     195                 :            :  * operation.
     196                 :            :  */
     197                 :            : void
     198                 :          4 : gcr_trust_is_certificate_pinned_async (GcrCertificate *certificate, const gchar *purpose,
     199                 :            :                                        const gchar *peer, GCancellable *cancellable,
     200                 :            :                                        GAsyncReadyCallback callback, gpointer user_data)
     201                 :            : {
     202                 :            :         GTask *task;
     203                 :            :         GckAttributes *attrs;
     204                 :            : 
     205   [ -  +  +  -  :          4 :         g_return_if_fail (GCR_IS_CERTIFICATE (certificate));
             -  +  -  + ]
     206         [ -  + ]:          4 :         g_return_if_fail (purpose);
     207         [ -  + ]:          4 :         g_return_if_fail (peer);
     208                 :            : 
     209                 :          4 :         task = g_task_new (NULL, cancellable, callback, user_data);
     210         [ +  - ]:          4 :         g_task_set_source_tag (task, gcr_trust_is_certificate_pinned_async);
     211                 :            : 
     212                 :          4 :         attrs = prepare_is_certificate_pinned (certificate, purpose, peer);
     213         [ -  + ]:          4 :         g_return_if_fail (attrs);
     214                 :          4 :         g_task_set_task_data (task, attrs, gck_attributes_unref);
     215                 :            : 
     216                 :          4 :         g_task_run_in_thread (task, thread_is_certificate_pinned);
     217                 :            : 
     218         [ +  - ]:          4 :         g_clear_object (&task);
     219                 :            : }
     220                 :            : 
     221                 :            : /**
     222                 :            :  * gcr_trust_is_certificate_pinned_finish:
     223                 :            :  * @result: the #GAsyncResult passed to the callback
     224                 :            :  * @error: a #GError, or %NULL
     225                 :            :  *
     226                 :            :  * Finishes an asynchronous operation started by
     227                 :            :  * gcr_trust_is_certificate_pinned_async().
     228                 :            :  *
     229                 :            :  * In the case of an error, %FALSE is also returned. Check @error to detect
     230                 :            :  * if an error occurred.
     231                 :            :  *
     232                 :            :  * Returns: %TRUE if the certificate is pinned.
     233                 :            :  */
     234                 :            : gboolean
     235                 :          4 : gcr_trust_is_certificate_pinned_finish (GAsyncResult *result, GError **error)
     236                 :            : {
     237   [ +  -  -  + ]:          4 :         g_return_val_if_fail (!error || !*error, FALSE);
     238         [ -  + ]:          4 :         g_return_val_if_fail (g_task_is_valid (result, NULL), FALSE);
     239                 :            : 
     240                 :          4 :         return g_task_propagate_boolean (G_TASK (result), error);
     241                 :            : }
     242                 :            : 
     243                 :            : /* ----------------------------------------------------------------------------------
     244                 :            :  * ADD PINNED CERTIFICATE
     245                 :            :  */
     246                 :            : 
     247                 :            : static GckAttributes *
     248                 :          5 : prepare_add_pinned_certificate (GcrCertificate *certificate, const gchar *purpose, const gchar *peer)
     249                 :            : {
     250                 :          5 :         GckBuilder builder = GCK_BUILDER_INIT;
     251                 :            : 
     252                 :          5 :         prepare_trust_attrs (certificate, CKT_X_PINNED_CERTIFICATE, &builder);
     253                 :            : 
     254                 :          5 :         gck_builder_add_string (&builder, CKA_X_PURPOSE, purpose);
     255                 :          5 :         gck_builder_add_string (&builder, CKA_X_PEER, peer);
     256                 :          5 :         gck_builder_add_boolean (&builder, CKA_TOKEN, TRUE);
     257                 :            : 
     258                 :          5 :         return gck_builder_end (&builder);
     259                 :            : }
     260                 :            : 
     261                 :            : static gboolean
     262                 :          5 : perform_add_pinned_certificate (GckAttributes *search,
     263                 :            :                                 GCancellable *cancellable,
     264                 :            :                                 GError **error)
     265                 :            : {
     266                 :          5 :         GckBuilder builder = GCK_BUILDER_INIT;
     267                 :          5 :         gboolean ret = FALSE;
     268                 :          5 :         GError *lerr = NULL;
     269                 :            :         GckObject *object;
     270                 :            :         GckSession *session;
     271                 :            :         GckSlot *slot;
     272                 :            :         GckEnumerator *en;
     273                 :            :         GList *slots;
     274                 :            : 
     275         [ -  + ]:          5 :         if (!gcr_pkcs11_initialize (cancellable, error))
     276                 :          0 :                 return FALSE;
     277                 :            : 
     278                 :          5 :         slots = gcr_pkcs11_get_trust_lookup_slots ();
     279                 :          5 :         en = gck_slots_enumerate_objects (slots, search, CKF_RW_SESSION);
     280         [ +  - ]:          5 :         g_clear_list (&slots, g_object_unref);
     281                 :            : 
     282                 :          5 :         object = gck_enumerator_next (en, cancellable, &lerr);
     283                 :          5 :         g_object_unref (en);
     284                 :            : 
     285         [ -  + ]:          5 :         if (lerr != NULL) {
     286                 :          0 :                 g_propagate_error (error, lerr);
     287                 :          0 :                 return FALSE;
     288                 :            :         }
     289                 :            : 
     290                 :            :         /* It already exists */
     291         [ -  + ]:          5 :         if (object) {
     292                 :          0 :                 g_object_unref (object);
     293                 :          0 :                 return TRUE;
     294                 :            :         }
     295                 :            : 
     296                 :          5 :         gck_builder_add_all (&builder, search);
     297                 :            : 
     298                 :            :         /* TODO: Add relevant label */
     299                 :            : 
     300                 :            :         /* Find an appropriate token */
     301                 :          5 :         slot = gcr_pkcs11_get_trust_store_slot ();
     302         [ -  + ]:          5 :         if (slot == NULL) {
     303                 :          0 :                 g_set_error (&lerr, GCK_ERROR, CKR_FUNCTION_FAILED,
     304                 :            :                              /* Translators: A pinned certificate is an exception which
     305                 :            :                                 trusts a given certificate explicitly for a purpose and
     306                 :            :                                 communication with a certain peer. */
     307                 :            :                              _("Couldn’t find a place to store the pinned certificate"));
     308                 :          0 :                 ret = FALSE;
     309                 :            :         } else {
     310                 :          5 :                 session = gck_slot_open_session (slot, CKF_RW_SESSION, NULL, NULL, &lerr);
     311         [ +  - ]:          5 :                 if (session != NULL) {
     312                 :          5 :                         GckAttributes *attrs = gck_builder_end (&builder);
     313                 :          5 :                         object = gck_session_create_object (session, attrs,
     314                 :            :                                                             cancellable, &lerr);
     315         [ +  + ]:          5 :                         if (object != NULL) {
     316                 :          4 :                                 g_object_unref (object);
     317                 :          4 :                                 ret = TRUE;
     318                 :            :                         }
     319                 :            : 
     320                 :          5 :                         g_object_unref (session);
     321                 :          5 :                         gck_attributes_unref (attrs);
     322                 :            :                 }
     323                 :            : 
     324                 :          5 :                 g_object_unref (slot);
     325                 :            :         }
     326                 :            : 
     327                 :          5 :         gck_builder_clear (&builder);
     328                 :            : 
     329         [ +  + ]:          5 :         if (!ret)
     330                 :          1 :                 g_propagate_error (error, lerr);
     331                 :            : 
     332                 :          5 :         return ret;
     333                 :            : }
     334                 :            : 
     335                 :            : /**
     336                 :            :  * gcr_trust_add_pinned_certificate:
     337                 :            :  * @certificate: a #GcrCertificate
     338                 :            :  * @purpose: the purpose string
     339                 :            :  * @peer: the peer for this pinned certificate
     340                 :            :  * @cancellable: a #GCancellable
     341                 :            :  * @error: a #GError, or %NULL
     342                 :            :  *
     343                 :            :  * Add a pinned @certificate for connections to @peer for @purpose. A pinned
     344                 :            :  * certificate overrides all other certificate verification and should be
     345                 :            :  * used with care.
     346                 :            :  *
     347                 :            :  * If the same pinned certificate already exists, then this operation
     348                 :            :  * does not add another, and succeeds without error.
     349                 :            :  *
     350                 :            :  * This call may block, see gcr_trust_add_pinned_certificate_async() for the
     351                 :            :  * non-blocking version.
     352                 :            :  *
     353                 :            :  * Returns: %TRUE if the pinned certificate is recorded successfully
     354                 :            :  */
     355                 :            : gboolean
     356                 :          3 : gcr_trust_add_pinned_certificate (GcrCertificate *certificate, const gchar *purpose, const gchar *peer,
     357                 :            :                                   GCancellable *cancellable, GError **error)
     358                 :            : {
     359                 :            :         GckAttributes *search;
     360                 :            :         gboolean ret;
     361                 :            : 
     362   [ -  +  +  -  :          3 :         g_return_val_if_fail (GCR_IS_CERTIFICATE (certificate), FALSE);
             -  +  -  + ]
     363         [ -  + ]:          3 :         g_return_val_if_fail (purpose, FALSE);
     364         [ -  + ]:          3 :         g_return_val_if_fail (peer, FALSE);
     365                 :            : 
     366                 :          3 :         search = prepare_add_pinned_certificate (certificate, purpose, peer);
     367         [ -  + ]:          3 :         g_return_val_if_fail (search, FALSE);
     368                 :            : 
     369                 :          3 :         ret = perform_add_pinned_certificate (search, cancellable, error);
     370                 :          3 :         gck_attributes_unref (search);
     371                 :            : 
     372                 :          3 :         return ret;
     373                 :            : }
     374                 :            : 
     375                 :            : static void
     376                 :          2 : thread_add_pinned_certificate (GTask *task, gpointer object,
     377                 :            :                                gpointer task_data, GCancellable *cancellable)
     378                 :            : {
     379                 :          2 :         GckAttributes *attrs = task_data;
     380                 :          2 :         GError *error = NULL;
     381                 :            : 
     382                 :          2 :         perform_add_pinned_certificate (attrs, cancellable, &error);
     383         [ +  - ]:          2 :         if (error == NULL)
     384                 :          2 :                 g_task_return_boolean (task, TRUE);
     385                 :            :         else
     386                 :          0 :                 g_task_return_error (task, g_steal_pointer (&error));
     387                 :          2 : }
     388                 :            : 
     389                 :            : /**
     390                 :            :  * gcr_trust_add_pinned_certificate_async:
     391                 :            :  * @certificate: a #GcrCertificate
     392                 :            :  * @purpose: the purpose string
     393                 :            :  * @peer: the peer for this pinned certificate
     394                 :            :  * @cancellable: a #GCancellable
     395                 :            :  * @callback: a #GAsyncReadyCallback to call when the operation completes
     396                 :            :  * @user_data: the data to pass to callback function
     397                 :            :  *
     398                 :            :  * Add a pinned certificate for communication with @peer for @purpose. A pinned
     399                 :            :  * certificate overrides all other certificate verification and should be used
     400                 :            :  * with care.
     401                 :            :  *
     402                 :            :  * If the same pinned certificate already exists, then this operation
     403                 :            :  * does not add another, and succeeds without error.
     404                 :            :  *
     405                 :            :  * When the operation is finished, callback will be called. You can then call
     406                 :            :  * [func@Gcr.trust_add_pinned_certificate_finish] to get the result of the
     407                 :            :  * operation.
     408                 :            :  */
     409                 :            : void
     410                 :          2 : gcr_trust_add_pinned_certificate_async (GcrCertificate *certificate, const gchar *purpose,
     411                 :            :                                         const gchar *peer, GCancellable *cancellable,
     412                 :            :                                         GAsyncReadyCallback callback, gpointer user_data)
     413                 :            : {
     414                 :            :         GTask *task;
     415                 :            :         GckAttributes *attrs;
     416                 :            : 
     417   [ -  +  +  -  :          2 :         g_return_if_fail (GCR_IS_CERTIFICATE (certificate));
             -  +  -  + ]
     418         [ -  + ]:          2 :         g_return_if_fail (purpose);
     419         [ -  + ]:          2 :         g_return_if_fail (peer);
     420                 :            : 
     421                 :          2 :         task = g_task_new (NULL, cancellable, callback, user_data);
     422         [ +  - ]:          2 :         g_task_set_source_tag (task, gcr_trust_add_pinned_certificate_async);
     423                 :            : 
     424                 :          2 :         attrs = prepare_add_pinned_certificate (certificate, purpose, peer);
     425         [ -  + ]:          2 :         g_return_if_fail (attrs);
     426                 :          2 :         g_task_set_task_data (task, attrs, gck_attributes_unref);
     427                 :            : 
     428                 :          2 :         g_task_run_in_thread (task, thread_add_pinned_certificate);
     429                 :            : 
     430         [ +  - ]:          2 :         g_clear_object (&task);
     431                 :            : }
     432                 :            : 
     433                 :            : /**
     434                 :            :  * gcr_trust_add_pinned_certificate_finish:
     435                 :            :  * @result: the #GAsyncResult passed to the callback
     436                 :            :  * @error: a #GError, or %NULL
     437                 :            :  *
     438                 :            :  * Finishes an asynchronous operation started by
     439                 :            :  * gcr_trust_add_pinned_certificate_async().
     440                 :            :  *
     441                 :            :  * Returns: %TRUE if the pinned certificate is recorded successfully
     442                 :            :  */
     443                 :            : gboolean
     444                 :          2 : gcr_trust_add_pinned_certificate_finish (GAsyncResult *result, GError **error)
     445                 :            : {
     446   [ +  -  -  + ]:          2 :         g_return_val_if_fail (!error || !*error, FALSE);
     447         [ -  + ]:          2 :         g_return_val_if_fail (g_task_is_valid (result, NULL), FALSE);
     448                 :            : 
     449                 :          2 :         return g_task_propagate_boolean (G_TASK (result), error);
     450                 :            : }
     451                 :            : 
     452                 :            : /* -----------------------------------------------------------------------
     453                 :            :  * REMOVE PINNED CERTIFICATE
     454                 :            :  */
     455                 :            : 
     456                 :            : static GckAttributes *
     457                 :          2 : prepare_remove_pinned_certificate (GcrCertificate *certificate, const gchar *purpose,
     458                 :            :                                    const gchar *peer)
     459                 :            : {
     460                 :          2 :         GckBuilder builder = GCK_BUILDER_INIT;
     461                 :            : 
     462                 :          2 :         prepare_trust_attrs (certificate, CKT_X_PINNED_CERTIFICATE, &builder);
     463                 :          2 :         gck_builder_add_string (&builder, CKA_X_PURPOSE, purpose);
     464                 :          2 :         gck_builder_add_string (&builder, CKA_X_PEER, peer);
     465                 :            : 
     466                 :          2 :         return gck_builder_end (&builder);
     467                 :            : }
     468                 :            : 
     469                 :            : static gboolean
     470                 :          2 : perform_remove_pinned_certificate (GckAttributes *attrs,
     471                 :            :                                    GCancellable *cancellable,
     472                 :            :                                    GError **error)
     473                 :            : {
     474                 :            :         GList *objects, *l;
     475                 :          2 :         GError *lerr = NULL;
     476                 :            :         GckEnumerator *en;
     477                 :            :         GList *slots;
     478                 :            : 
     479         [ -  + ]:          2 :         if (!gcr_pkcs11_initialize (cancellable, error))
     480                 :          0 :                 return FALSE;
     481                 :            : 
     482                 :          2 :         slots = gcr_pkcs11_get_trust_lookup_slots ();
     483                 :          2 :         en = gck_slots_enumerate_objects (slots, attrs, CKF_RW_SESSION);
     484         [ +  - ]:          2 :         g_clear_list (&slots, g_object_unref);
     485                 :            : 
     486                 :            :         /* We need an error below */
     487   [ +  -  +  - ]:          2 :         if (error && !*error)
     488                 :          2 :                 *error = lerr;
     489                 :            : 
     490                 :          2 :         objects = gck_enumerator_next_n (en, -1, cancellable, error);
     491                 :          2 :         g_object_unref (en);
     492                 :            : 
     493         [ -  + ]:          2 :         if (*error)
     494                 :          0 :                 return FALSE;
     495                 :            : 
     496   [ +  -  +  + ]:          4 :         for (l = objects; l; l = g_list_next (l)) {
     497         [ -  + ]:          2 :                 if (!gck_object_destroy (l->data, cancellable, error)) {
     498                 :            : 
     499                 :            :                         /* In case there's a race condition */
     500         [ #  # ]:          0 :                         if (g_error_matches (*error, GCK_ERROR, CKR_OBJECT_HANDLE_INVALID)) {
     501                 :          0 :                                 g_clear_error (error);
     502                 :          0 :                                 continue;
     503                 :            :                         }
     504                 :            : 
     505         [ #  # ]:          0 :                         g_clear_list (&objects, g_object_unref);
     506                 :          0 :                         return FALSE;
     507                 :            :                 }
     508                 :            :         }
     509                 :            : 
     510         [ +  - ]:          2 :         g_clear_list (&objects, g_object_unref);
     511                 :          2 :         return TRUE;
     512                 :            : }
     513                 :            : 
     514                 :            : /**
     515                 :            :  * gcr_trust_remove_pinned_certificate:
     516                 :            :  * @certificate: a #GcrCertificate
     517                 :            :  * @purpose: the purpose string
     518                 :            :  * @peer: the peer for this pinned certificate
     519                 :            :  * @cancellable: a #GCancellable
     520                 :            :  * @error: a #GError, or %NULL
     521                 :            :  *
     522                 :            :  * Remove a pinned certificate for communication with @peer for @purpose.
     523                 :            :  *
     524                 :            :  * If the same pinned certificate does not exist, or was already removed,
     525                 :            :  * then this operation succeeds without error.
     526                 :            :  *
     527                 :            :  * This call may block, see gcr_trust_remove_pinned_certificate_async() for the
     528                 :            :  * non-blocking version.
     529                 :            :  *
     530                 :            :  * Returns: %TRUE if the pinned certificate no longer exists
     531                 :            :  */
     532                 :            : gboolean
     533                 :          1 : gcr_trust_remove_pinned_certificate (GcrCertificate *certificate, const gchar *purpose, const gchar *peer,
     534                 :            :                                      GCancellable *cancellable, GError **error)
     535                 :            : {
     536                 :            :         GckAttributes *search;
     537                 :            :         gboolean ret;
     538                 :            : 
     539   [ -  +  +  -  :          1 :         g_return_val_if_fail (GCR_IS_CERTIFICATE (certificate), FALSE);
             -  +  -  + ]
     540         [ -  + ]:          1 :         g_return_val_if_fail (purpose, FALSE);
     541         [ -  + ]:          1 :         g_return_val_if_fail (peer, FALSE);
     542                 :            : 
     543                 :          1 :         search = prepare_remove_pinned_certificate (certificate, purpose, peer);
     544         [ -  + ]:          1 :         g_return_val_if_fail (search, FALSE);
     545                 :            : 
     546                 :          1 :         ret = perform_remove_pinned_certificate (search, cancellable, error);
     547                 :          1 :         gck_attributes_unref (search);
     548                 :            : 
     549                 :          1 :         return ret;
     550                 :            : }
     551                 :            : 
     552                 :            : static void
     553                 :          1 : thread_remove_pinned_certificate (GTask *task, gpointer object,
     554                 :            :                                   gpointer task_data, GCancellable *cancellable)
     555                 :            : {
     556                 :          1 :         GckAttributes *attrs = task_data;
     557                 :          1 :         GError *error = NULL;
     558                 :            : 
     559                 :          1 :         perform_remove_pinned_certificate (attrs, cancellable, &error);
     560                 :            : 
     561         [ +  - ]:          1 :         if (error == NULL)
     562                 :          1 :                 g_task_return_boolean (task, TRUE);
     563                 :            :         else
     564                 :          0 :                 g_task_return_error (task, g_steal_pointer (&error));
     565                 :          1 : }
     566                 :            : 
     567                 :            : /**
     568                 :            :  * gcr_trust_remove_pinned_certificate_async:
     569                 :            :  * @certificate: a #GcrCertificate
     570                 :            :  * @purpose: the purpose string
     571                 :            :  * @peer: the peer for this pinned certificate
     572                 :            :  * @cancellable: a #GCancellable
     573                 :            :  * @callback: a #GAsyncReadyCallback to call when the operation completes
     574                 :            :  * @user_data: the data to pass to callback function
     575                 :            :  *
     576                 :            :  * Remove a pinned certificate for communication with @peer for @purpose.
     577                 :            :  *
     578                 :            :  * If the same pinned certificate does not exist, or was already removed,
     579                 :            :  * then this operation succeeds without error.
     580                 :            :  *
     581                 :            :  * When the operation is finished, callback will be called. You can then call
     582                 :            :  * gcr_trust_remove_pinned_certificate_finish() to get the result of the
     583                 :            :  * operation.
     584                 :            :  */
     585                 :            : void
     586                 :          1 : gcr_trust_remove_pinned_certificate_async (GcrCertificate *certificate,
     587                 :            :                                            const gchar *purpose,
     588                 :            :                                            const gchar *peer,
     589                 :            :                                            GCancellable *cancellable,
     590                 :            :                                            GAsyncReadyCallback callback,
     591                 :            :                                            gpointer user_data)
     592                 :            : {
     593                 :            :         GTask *task;
     594                 :            :         GckAttributes *attrs;
     595                 :            : 
     596   [ -  +  +  -  :          1 :         g_return_if_fail (GCR_IS_CERTIFICATE (certificate));
             -  +  -  + ]
     597         [ -  + ]:          1 :         g_return_if_fail (purpose);
     598         [ -  + ]:          1 :         g_return_if_fail (peer);
     599                 :            : 
     600                 :          1 :         task = g_task_new (NULL, cancellable, callback, user_data);
     601         [ +  - ]:          1 :         g_task_set_source_tag (task, gcr_trust_remove_pinned_certificate_async);
     602                 :            : 
     603                 :          1 :         attrs = prepare_remove_pinned_certificate (certificate, purpose, peer);
     604         [ -  + ]:          1 :         g_return_if_fail (attrs);
     605                 :          1 :         g_task_set_task_data (task, attrs, gck_attributes_unref);
     606                 :            : 
     607                 :          1 :         g_task_run_in_thread (task, thread_remove_pinned_certificate);
     608                 :            : 
     609         [ +  - ]:          1 :         g_clear_object (&task);
     610                 :            : }
     611                 :            : 
     612                 :            : /**
     613                 :            :  * gcr_trust_remove_pinned_certificate_finish:
     614                 :            :  * @result: the #GAsyncResult passed to the callback
     615                 :            :  * @error: a #GError, or %NULL
     616                 :            :  *
     617                 :            :  * Finishes an asynchronous operation started by
     618                 :            :  * gcr_trust_remove_pinned_certificate_async().
     619                 :            :  *
     620                 :            :  * Returns: %TRUE if the pinned certificate no longer exists
     621                 :            :  */
     622                 :            : gboolean
     623                 :          1 : gcr_trust_remove_pinned_certificate_finish (GAsyncResult *result, GError **error)
     624                 :            : {
     625   [ +  -  -  + ]:          1 :         g_return_val_if_fail (!error || !*error, FALSE);
     626         [ -  + ]:          1 :         g_return_val_if_fail (g_task_is_valid (result, NULL), FALSE);
     627                 :            : 
     628                 :          1 :         return g_task_propagate_boolean (G_TASK (result), error);
     629                 :            : }
     630                 :            : 
     631                 :            : /* ----------------------------------------------------------------------------------
     632                 :            :  * CERTIFICATE ROOT
     633                 :            :  */
     634                 :            : 
     635                 :            : static GckAttributes *
     636                 :          8 : prepare_is_certificate_anchored (GcrCertificate *certificate, const gchar *purpose)
     637                 :            : {
     638                 :          8 :         GckBuilder builder = GCK_BUILDER_INIT;
     639                 :            : 
     640                 :          8 :         prepare_trust_attrs (certificate, CKT_X_ANCHORED_CERTIFICATE, &builder);
     641                 :          8 :         gck_builder_add_string (&builder, CKA_X_PURPOSE, purpose);
     642                 :            : 
     643                 :          8 :         return gck_builder_end (&builder);
     644                 :            : }
     645                 :            : 
     646                 :            : static gboolean
     647                 :          8 : perform_is_certificate_anchored (GckAttributes *attrs,
     648                 :            :                                  GCancellable *cancellable,
     649                 :            :                                  GError **error)
     650                 :            : {
     651                 :            :         GckEnumerator *en;
     652                 :            :         GList *slots;
     653                 :            :         GckObject *object;
     654                 :            : 
     655         [ -  + ]:          8 :         if (!gcr_pkcs11_initialize (cancellable, error))
     656                 :          0 :                 return FALSE;
     657                 :            : 
     658                 :          8 :         slots = gcr_pkcs11_get_trust_lookup_slots ();
     659                 :          8 :         g_debug ("searching for certificate anchor in %d slots",
     660                 :            :                  g_list_length (slots));
     661                 :          8 :         en = gck_slots_enumerate_objects (slots, attrs, 0);
     662         [ +  - ]:          8 :         g_clear_list (&slots, g_object_unref);
     663                 :            : 
     664                 :          8 :         object = gck_enumerator_next (en, cancellable, error);
     665                 :          8 :         g_object_unref (en);
     666                 :            : 
     667         [ +  + ]:          8 :         if (object != NULL)
     668                 :          4 :                 g_object_unref (object);
     669                 :            : 
     670         [ +  + ]:          8 :         g_debug ("%s certificate anchor", object ? "found" : "did not find");
     671                 :          8 :         return (object != NULL);
     672                 :            : }
     673                 :            : 
     674                 :            : /**
     675                 :            :  * gcr_trust_is_certificate_anchored:
     676                 :            :  * @certificate: a #GcrCertificate to check
     677                 :            :  * @purpose: the purpose string
     678                 :            :  * @cancellable: a #GCancellable
     679                 :            :  * @error: a #GError, or %NULL
     680                 :            :  *
     681                 :            :  * Check if the @certificate is a trust anchor for the given @purpose. A trust
     682                 :            :  * anchor is used to verify the signatures on other certificates when verifying
     683                 :            :  * a certificate chain. Also known as a trusted certificate authority.
     684                 :            :  *
     685                 :            :  * This call may block, see [func@Gcr.trust_is_certificate_anchored_async] for
     686                 :            :  * the non-blocking version.
     687                 :            :  *
     688                 :            :  * In the case of an error, %FALSE is also returned. Check @error to detect
     689                 :            :  * if an error occurred.
     690                 :            :  *
     691                 :            :  * Returns: %TRUE if the certificate is a trust anchor
     692                 :            :  */
     693                 :            : gboolean
     694                 :          7 : gcr_trust_is_certificate_anchored (GcrCertificate *certificate, const gchar *purpose,
     695                 :            :                                    GCancellable *cancellable, GError **error)
     696                 :            : {
     697                 :            :         GckAttributes *search;
     698                 :            :         gboolean ret;
     699                 :            : 
     700   [ -  +  +  -  :          7 :         g_return_val_if_fail (GCR_IS_CERTIFICATE (certificate), FALSE);
             -  +  -  + ]
     701         [ -  + ]:          7 :         g_return_val_if_fail (purpose, FALSE);
     702                 :            : 
     703                 :          7 :         search = prepare_is_certificate_anchored (certificate, purpose);
     704         [ -  + ]:          7 :         g_return_val_if_fail (search, FALSE);
     705                 :            : 
     706                 :          7 :         ret = perform_is_certificate_anchored (search, cancellable, error);
     707                 :          7 :         gck_attributes_unref (search);
     708                 :            : 
     709                 :          7 :         return ret;
     710                 :            : }
     711                 :            : 
     712                 :            : static void
     713                 :          1 : thread_is_certificate_anchored (GTask *task, gpointer object,
     714                 :            :                                 gpointer task_data, GCancellable *cancellable)
     715                 :            : {
     716                 :          1 :         GckAttributes *attrs = task_data;
     717                 :          1 :         GError *error = NULL;
     718                 :            :         gboolean found;
     719                 :            : 
     720                 :          1 :         found = perform_is_certificate_anchored (attrs, cancellable, &error);
     721         [ +  - ]:          1 :         if (error == NULL)
     722                 :          1 :                 g_task_return_boolean (task, found);
     723                 :            :         else
     724                 :          0 :                 g_task_return_error (task, g_steal_pointer (&error));
     725                 :          1 : }
     726                 :            : 
     727                 :            : /**
     728                 :            :  * gcr_trust_is_certificate_anchored_async:
     729                 :            :  * @certificate: a #GcrCertificate to check
     730                 :            :  * @purpose: the purpose string
     731                 :            :  * @cancellable: a #GCancellable
     732                 :            :  * @callback: a #GAsyncReadyCallback to call when the operation completes
     733                 :            :  * @user_data: the data to pass to callback function
     734                 :            :  *
     735                 :            :  * Check if the @certificate is a trust anchor for the given @purpose. A trust
     736                 :            :  * anchor is used to verify the signatures on other certificates when verifying
     737                 :            :  * a certificate chain. Also known as a trusted certificate authority.
     738                 :            :  *
     739                 :            :  * When the operation is finished, callback will be called. You can then call
     740                 :            :  * gcr_trust_is_certificate_anchored_finish() to get the result of the operation.
     741                 :            :  */
     742                 :            : void
     743                 :          1 : gcr_trust_is_certificate_anchored_async (GcrCertificate *certificate, const gchar *purpose,
     744                 :            :                                          GCancellable *cancellable, GAsyncReadyCallback callback,
     745                 :            :                                          gpointer user_data)
     746                 :            : {
     747                 :            :         GTask *task;
     748                 :            :         GckAttributes *attrs;
     749                 :            : 
     750   [ -  +  +  -  :          1 :         g_return_if_fail (GCR_IS_CERTIFICATE (certificate));
             -  +  -  + ]
     751         [ -  + ]:          1 :         g_return_if_fail (purpose);
     752                 :            : 
     753                 :          1 :         task = g_task_new (NULL, cancellable, callback, user_data);
     754         [ +  - ]:          1 :         g_task_set_source_tag (task, gcr_trust_is_certificate_anchored_async);
     755                 :            : 
     756                 :          1 :         attrs = prepare_is_certificate_anchored (certificate, purpose);
     757         [ -  + ]:          1 :         g_return_if_fail (attrs);
     758                 :          1 :         g_task_set_task_data (task, attrs, gck_attributes_unref);
     759                 :            : 
     760                 :          1 :         g_task_run_in_thread (task, thread_is_certificate_anchored);
     761                 :            : 
     762         [ +  - ]:          1 :         g_clear_object (&task);
     763                 :            : }
     764                 :            : 
     765                 :            : /**
     766                 :            :  * gcr_trust_is_certificate_anchored_finish:
     767                 :            :  * @result: the #GAsyncResult passed to the callback
     768                 :            :  * @error: a #GError, or %NULL
     769                 :            :  *
     770                 :            :  * Finishes an asynchronous operation started by
     771                 :            :  * gcr_trust_is_certificate_anchored_async().
     772                 :            :  *
     773                 :            :  * In the case of an error, %FALSE is also returned. Check @error to detect
     774                 :            :  * if an error occurred.
     775                 :            :  *
     776                 :            :  * Returns: %TRUE if the certificate is a trust anchor
     777                 :            :  */
     778                 :            : gboolean
     779                 :          1 : gcr_trust_is_certificate_anchored_finish (GAsyncResult *result, GError **error)
     780                 :            : {
     781   [ +  -  -  + ]:          1 :         g_return_val_if_fail (!error || !*error, FALSE);
     782         [ -  + ]:          1 :         g_return_val_if_fail (g_task_is_valid (result, NULL), FALSE);
     783                 :            : 
     784                 :          1 :         return g_task_propagate_boolean (G_TASK (result), error);
     785                 :            : }
     786                 :            : 
     787                 :            : /* ----------------------------------------------------------------------------------
     788                 :            :  * DISTRUSTED CERTIFICATE
     789                 :            :  */
     790                 :            : 
     791                 :            : static GckAttributes *
     792                 :          3 : prepare_is_certificate_distrusted (unsigned char *serial_nr,
     793                 :            :                                    size_t         serial_nr_len,
     794                 :            :                                    unsigned char *issuer,
     795                 :            :                                    size_t         issuer_len)
     796                 :            : {
     797                 :          3 :     GckBuilder builder = GCK_BUILDER_INIT;
     798                 :            : 
     799                 :          3 :     gck_builder_add_ulong (&builder, CKA_CLASS, CKO_X_TRUST_ASSERTION);
     800                 :          3 :     gck_builder_add_ulong (&builder, CKA_X_ASSERTION_TYPE, CKT_X_DISTRUSTED_CERTIFICATE);
     801                 :          3 :     gck_builder_add_data (&builder, CKA_SERIAL_NUMBER, serial_nr, serial_nr_len);
     802                 :          3 :     gck_builder_add_data (&builder, CKA_ISSUER, issuer, issuer_len);
     803                 :            : 
     804                 :          3 :     return gck_builder_end (&builder);
     805                 :            : }
     806                 :            : 
     807                 :            : static gboolean
     808                 :          3 : perform_is_certificate_distrusted (GckAttributes *attrs,
     809                 :            :                                    GCancellable  *cancellable,
     810                 :            :                                    GError       **error)
     811                 :            : {
     812                 :            :     GckEnumerator *en;
     813                 :            :     GList *slots;
     814                 :            :     GckObject *object;
     815                 :            : 
     816         [ -  + ]:          3 :     if (!gcr_pkcs11_initialize (cancellable, error))
     817                 :          0 :         return FALSE;
     818                 :            : 
     819                 :          3 :     slots = gcr_pkcs11_get_trust_lookup_slots ();
     820                 :          3 :     g_debug ("searching for certificate distrust assertion in %d slots",
     821                 :            :              g_list_length (slots));
     822                 :          3 :     en = gck_slots_enumerate_objects (slots, attrs, 0);
     823         [ +  - ]:          3 :     g_clear_list (&slots, g_object_unref);
     824                 :            : 
     825                 :          3 :     object = gck_enumerator_next (en, cancellable, error);
     826                 :          3 :     g_object_unref (en);
     827                 :            : 
     828         [ +  + ]:          3 :     if (object != NULL)
     829                 :          1 :         g_object_unref (object);
     830                 :            : 
     831         [ +  + ]:          3 :     g_debug ("%s certificate distrust", object ? "found" : "did not find");
     832                 :          3 :     return (object != NULL);
     833                 :            : }
     834                 :            : 
     835                 :            : /**
     836                 :            :  * gcr_trust_is_certificate_distrusted:
     837                 :            :  * @serial_nr: (array length=serial_nr_len): The serial number of the certificate
     838                 :            :  * @serial_nr_len: The nr of bytes in @serial_nr
     839                 :            :  * @issuer: (array length=issuer_len): The raw issuer
     840                 :            :  * @issuer_len: The nr of bytes in @issuer
     841                 :            :  * @cancellable: (nullable): a #GCancellable or %NULL
     842                 :            :  * @error: a #GError, or %NULL
     843                 :            :  *
     844                 :            :  * Checks whether the certificate that can be uniquely identified with the
     845                 :            :  * given @serial_nr and @issuer is marked as distrusted (for example by the
     846                 :            :  * user, or because it's part of a CRL).
     847                 :            :  *
     848                 :            :  * Since we can't directly use [iface@Certificate] to fetch these values, you
     849                 :            :  * need to call these with the raw serial number and issuer as provided by the
     850                 :            :  * PKCS#11 fields `CKA_SERIAL_NR` and `CKA_ISSUER`.
     851                 :            :  *
     852                 :            :  * Returns: %TRUE if the certificate is marked as distrusted
     853                 :            :  */
     854                 :            : gboolean
     855                 :          2 : gcr_trust_is_certificate_distrusted (unsigned char *serial_nr,
     856                 :            :                                      size_t         serial_nr_len,
     857                 :            :                                      unsigned char *issuer,
     858                 :            :                                      size_t         issuer_len,
     859                 :            :                                      GCancellable  *cancellable,
     860                 :            :                                      GError       **error)
     861                 :            : {
     862                 :            :     GckAttributes *search;
     863                 :            :     gboolean ret;
     864                 :            : 
     865         [ -  + ]:          2 :     g_return_val_if_fail (serial_nr, FALSE);
     866         [ -  + ]:          2 :     g_return_val_if_fail (serial_nr_len > 0, FALSE);
     867         [ -  + ]:          2 :     g_return_val_if_fail (issuer, FALSE);
     868         [ -  + ]:          2 :     g_return_val_if_fail (issuer_len > 0, FALSE);
     869   [ +  -  -  -  :          2 :     g_return_val_if_fail (G_IS_CANCELLABLE (cancellable) || !cancellable, FALSE);
          -  -  +  -  -  
                      + ]
     870   [ +  -  -  + ]:          2 :     g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
     871                 :            : 
     872                 :          2 :     search = prepare_is_certificate_distrusted (serial_nr, serial_nr_len, issuer, issuer_len);
     873         [ -  + ]:          2 :     g_return_val_if_fail (search, FALSE);
     874                 :            : 
     875                 :          2 :     ret = perform_is_certificate_distrusted (search, cancellable, error);
     876                 :          2 :     gck_attributes_unref (search);
     877                 :            : 
     878                 :          2 :     return ret;
     879                 :            : }
     880                 :            : 
     881                 :            : static void
     882                 :          1 : thread_is_certificate_distrusted (GTask        *task,
     883                 :            :                                   void         *object,
     884                 :            :                                   void         *task_data,
     885                 :            :                                   GCancellable *cancellable)
     886                 :            : {
     887                 :          1 :     GckAttributes *attrs = task_data;
     888                 :          1 :     GError *error = NULL;
     889                 :            :     gboolean found;
     890                 :            : 
     891                 :          1 :     found = perform_is_certificate_distrusted (attrs, cancellable, &error);
     892         [ +  - ]:          1 :     if (error == NULL)
     893                 :          1 :         g_task_return_boolean (task, found);
     894                 :            :     else
     895                 :          0 :         g_task_return_error (task, g_steal_pointer (&error));
     896                 :          1 : }
     897                 :            : 
     898                 :            : /**
     899                 :            :  * gcr_trust_is_certificate_distrusted_async:
     900                 :            :  * @serial_nr: (array length=serial_nr_len): The serial number of the certificate
     901                 :            :  * @serial_nr_len: The nr of bytes in @serial_nr
     902                 :            :  * @issuer: (array length=issuer_len): The raw issuer
     903                 :            :  * @issuer_len: The number of bytes in @issuer
     904                 :            :  * @cancellable: (nullable): a #GCancellable or %NULL
     905                 :            :  * @callback: a #GAsyncReadyCallback to call when the operation completes
     906                 :            :  * @user_data: the data to pass to callback function
     907                 :            :  *
     908                 :            :  * Asynchronously checks whether the certificate that can be uniquely
     909                 :            :  * identified with the given @serial_nr and @issuer is marked as distrusted
     910                 :            :  * (for example by the user, or because it's part of a CRL).
     911                 :            :  *
     912                 :            :  * Since we can't directly use [iface@Certificate] to fetch these values, you
     913                 :            :  * need to call these with the raw serial number and issuer as provided by the
     914                 :            :  * PKCS#11 fields `CKA_SERIAL_NR` and `CKA_ISSUER`.
     915                 :            :  *
     916                 :            :  * When the operation is finished, @callback will be called. You can then call
     917                 :            :  * [func@trust_is_certificate_distrusted_finish] to get the result of the
     918                 :            :  * operation.
     919                 :            :  */
     920                 :            : void
     921                 :          1 : gcr_trust_is_certificate_distrusted_async (unsigned char      *serial_nr,
     922                 :            :                                            size_t              serial_nr_len,
     923                 :            :                                            unsigned char      *issuer,
     924                 :            :                                            size_t              issuer_len,
     925                 :            :                                            GCancellable       *cancellable,
     926                 :            :                                            GAsyncReadyCallback callback,
     927                 :            :                                            void               *user_data)
     928                 :            : {
     929                 :            :     GTask *task;
     930                 :            :     GckAttributes *attrs;
     931                 :            : 
     932         [ -  + ]:          1 :     g_return_if_fail (serial_nr);
     933         [ -  + ]:          1 :     g_return_if_fail (serial_nr_len > 0);
     934         [ -  + ]:          1 :     g_return_if_fail (issuer);
     935         [ -  + ]:          1 :     g_return_if_fail (issuer_len > 0);
     936   [ +  -  -  -  :          1 :     g_return_if_fail (G_IS_CANCELLABLE (cancellable) || !cancellable);
          -  -  +  -  -  
                      + ]
     937                 :            : 
     938                 :          1 :     task = g_task_new (NULL, cancellable, callback, user_data);
     939         [ +  - ]:          1 :     g_task_set_source_tag (task, gcr_trust_is_certificate_distrusted_async);
     940                 :            : 
     941                 :          1 :     attrs = prepare_is_certificate_distrusted (serial_nr, serial_nr_len, issuer, issuer_len);
     942         [ -  + ]:          1 :     g_return_if_fail (attrs);
     943                 :          1 :     g_task_set_task_data (task, attrs, gck_attributes_unref);
     944                 :            : 
     945                 :          1 :     g_task_run_in_thread (task, thread_is_certificate_distrusted);
     946                 :            : 
     947         [ +  - ]:          1 :     g_clear_object (&task);
     948                 :            : }
     949                 :            : 
     950                 :            : /**
     951                 :            :  * gcr_trust_is_certificate_distrusted_finish:
     952                 :            :  * @result: the #GAsyncResult passed to the callback
     953                 :            :  * @error: a #GError, or %NULL
     954                 :            :  *
     955                 :            :  * Finishes an asynchronous operation started by
     956                 :            :  * [func@trust_is_certificate_distrusted_async].
     957                 :            :  *
     958                 :            :  * In the case of an error, %FALSE is also returned. Check @error to detect
     959                 :            :  * if an error occurred.
     960                 :            :  *
     961                 :            :  * Returns: %TRUE if the certificate is a trust anchor
     962                 :            :  */
     963                 :            : gboolean
     964                 :          1 : gcr_trust_is_certificate_distrusted_finish (GAsyncResult *result,
     965                 :            :                                             GError      **error)
     966                 :            : {
     967   [ +  -  -  + ]:          1 :     g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
     968         [ -  + ]:          1 :     g_return_val_if_fail (g_task_is_valid (result, NULL), FALSE);
     969                 :            : 
     970                 :          1 :     return g_task_propagate_boolean (G_TASK (result), error);
     971                 :            : }

Generated by: LCOV version 1.14