4
* Copyright (C) 2010 Collabora Ltd
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.
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.
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21
* Author: Stef Walter <stefw@collabora.co.uk>
27
#include "gcr-types.h"
28
#include "gcr-internal.h"
29
#include "gcr-library.h"
30
#include "gcr-trust.h"
34
#include "pkcs11/pkcs11n.h"
35
#include "pkcs11/pkcs11i.h"
36
#include "pkcs11/pkcs11x.h"
38
#include <glib/gi18n-lib.h>
42
* @title: Trust Storage and Lookups
43
* @short_description: Store and lookup bits of information used for
44
* verifying certificates.
46
* These functions provide access to stored information about which
47
* certificates the system and user trusts as certificate authority trust
48
* anchors, or overrides to the normal verification of certificates.
50
* Trust anchors are used to verify the certificate authority in a certificate
51
* chain. Trust anchors are always valid for a given purpose. The most common
52
* purpose is the #GCR_PURPOSE_SERVER_AUTH and is used for a client application
53
* to verify that the certificate at the server side of a TLS connection is
54
* authorized to act as such. To check if a certificate is a trust anchor use
55
* gcr_trust_is_certificate_anchored().
57
* Pinned certificates are used when a user overrides the default trust
58
* decision for a given certificate. They're often used with self-signed
59
* certificates. Pinned certificates are always only valid for a single peer
60
* such as the remote host with which TLS is being performed. To lookup
61
* pinned certificates use gcr_trust_is_certificate_pinned().
63
* After the user has requested to override the trust decision
64
* about a given certificate then a pinned certificates can be added by using
65
* the gcr_trust_add_pinned_certificate() function.
67
* These functions do not constitute a viable method for verifying certificates
68
* used in TLS or other locations. Instead they support such verification
69
* by providing some of the needed data for a trust decision.
71
* The storage is provided by pluggable PKCS\#11 modules.
75
* GCR_PURPOSE_SERVER_AUTH:
77
* The purpose used to verify the server certificate in a TLS connection. This
78
* is the most common purpose in use.
82
* GCR_PURPOSE_CLIENT_AUTH:
84
* The purpose used to verify the client certificate in a TLS connection.
88
* GCR_PURPOSE_CODE_SIGNING:
90
* The purpose used to verify certificate used for the signature on signed code.
94
* GCR_PURPOSE_CODE_SIGNING:
96
* The purpose used to verify certificates that are used in email communication
100
/* ----------------------------------------------------------------------------------
104
typedef struct _GcrTrustOperation {
106
GckAttributes *attrs;
111
trust_operation_free (gpointer data)
113
GcrTrustOperation *op = data;
116
/* No reference held */
117
g_assert (GCK_IS_ENUMERATOR (op->en));
120
g_assert (op->attrs);
121
gck_attributes_unref (op->attrs);
124
g_slice_free (GcrTrustOperation, op);
128
trust_operation_init (GckEnumerator *en, GckAttributes *attrs)
130
GcrTrustOperation *op;
132
g_assert (GCK_IS_ENUMERATOR (en));
133
g_assert (!g_object_get_data (G_OBJECT (en), "trust-operation"));
136
op = g_slice_new0 (GcrTrustOperation);
137
op->attrs = gck_attributes_ref (attrs);
139
/* No reference held, GckEnumerator owns */
141
g_object_set_data_full (G_OBJECT (en), "trust-operation", op, trust_operation_free);
144
static GcrTrustOperation*
145
trust_operation_get (GckEnumerator *en)
147
GcrTrustOperation *op = g_object_get_data (G_OBJECT (en), "trust-operation");
149
g_assert (op->en == en);
153
static GckAttributes*
154
prepare_trust_attrs (GcrCertificate *certificate, CK_X_ASSERTION_TYPE type)
156
GckAttributes *attrs;
160
attrs = gck_attributes_new ();
161
gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_X_TRUST_ASSERTION);
162
gck_attributes_add_ulong (attrs, CKA_X_ASSERTION_TYPE, type);
164
data = gcr_certificate_get_der_data (certificate, &n_data);
165
g_return_val_if_fail (data, NULL);
166
gck_attributes_add_data (attrs, CKA_X_CERTIFICATE_VALUE, data, n_data);
171
/* ----------------------------------------------------------------------------------
172
* GET PINNED CERTIFICATE
175
static GckEnumerator*
176
prepare_is_certificate_pinned (GcrCertificate *certificate, const gchar *purpose, const gchar *peer)
178
GckAttributes *attrs;
182
attrs = prepare_trust_attrs (certificate, CKT_X_PINNED_CERTIFICATE);
183
g_return_val_if_fail (attrs, NULL);
185
gck_attributes_add_string (attrs, CKA_X_PURPOSE, purpose);
186
gck_attributes_add_string (attrs, CKA_X_PEER, peer);
188
slots = gcr_pkcs11_get_trust_lookup_slots ();
189
en = gck_slots_enumerate_objects (slots, attrs, 0);
190
trust_operation_init (en, attrs);
191
gck_attributes_unref (attrs);
192
gck_list_unref_free (slots);
198
perform_is_certificate_pinned (GckEnumerator *en, GCancellable *cancellable, GError **error)
200
GcrTrustOperation *op;
203
op = trust_operation_get (en);
205
g_assert (op != NULL);
206
g_assert (op->found == FALSE);
208
object = gck_enumerator_next (en, cancellable, error);
209
op->found = (object != NULL);
212
g_object_unref (object);
218
* gcr_trust_is_certificate_pinned:
219
* @certificate: a #GcrCertificate to check
220
* @purpose: the purpose string
221
* @peer: the peer for this pinned
222
* @cancellable: a #GCancellable
223
* @error: a #GError, or NULL
225
* Check if @certificate is pinned for @purpose to communicate with @peer.
226
* A pinned certificate overrides all other certificate verification.
228
* This call may block, see gcr_trust_is_certificate_pinned_async() for the
229
* non-blocking version.
231
* In the case of an error, %FALSE is also returned. Check @error to detect
232
* if an error occurred.
234
* Returns: %TRUE if the certificate is pinned for the host and purpose
237
gcr_trust_is_certificate_pinned (GcrCertificate *certificate, const gchar *purpose,
238
const gchar *peer, GCancellable *cancellable, GError **error)
243
g_return_val_if_fail (GCR_IS_CERTIFICATE (certificate), FALSE);
244
g_return_val_if_fail (purpose, FALSE);
245
g_return_val_if_fail (peer, FALSE);
249
en = prepare_is_certificate_pinned (certificate, purpose, peer);
250
g_return_val_if_fail (en, FALSE);
252
ret = perform_is_certificate_pinned (en, cancellable, error);
260
thread_is_certificate_pinned (GSimpleAsyncResult *result, GObject *object, GCancellable *cancel)
262
GError *error = NULL;
264
perform_is_certificate_pinned (GCK_ENUMERATOR (object), cancel, &error);
267
g_simple_async_result_set_from_error (result, error);
268
g_clear_error (&error);
273
* gcr_trust_is_certificate_pinned_async:
274
* @certificate: a #GcrCertificate to check
275
* @purpose: the purpose string
276
* @peer: the peer for this pinned
277
* @cancellable: a #GCancellable
278
* @callback: a #GAsyncReadyCallback to call when the operation completes
279
* @user_data: the data to pass to callback function
281
* Check if @certificate is pinned for @purpose to communicate with @peer. A
282
* pinned certificate overrides all other certificate verification.
284
* When the operation is finished, callback will be called. You can then call
285
* gcr_trust_is_certificate_pinned_finish() to get the result of the
289
gcr_trust_is_certificate_pinned_async (GcrCertificate *certificate, const gchar *purpose,
290
const gchar *peer, GCancellable *cancellable,
291
GAsyncReadyCallback callback, gpointer user_data)
293
GSimpleAsyncResult *async;
296
g_return_if_fail (GCR_CERTIFICATE (certificate));
297
g_return_if_fail (purpose);
298
g_return_if_fail (peer);
302
en = prepare_is_certificate_pinned (certificate, purpose, peer);
303
g_return_if_fail (en);
305
async = g_simple_async_result_new (G_OBJECT (en), callback, user_data,
306
gcr_trust_is_certificate_pinned_async);
308
g_simple_async_result_run_in_thread (async, thread_is_certificate_pinned,
309
G_PRIORITY_DEFAULT, cancellable);
311
g_object_unref (async);
316
* gcr_trust_is_certificate_pinned_finish:
317
* @result: the #GAsyncResult passed to the callback
318
* @error: a #GError, or NULL
320
* Finishes an asynchronous operation started by
321
* gcr_trust_is_certificate_pinned_async().
323
* In the case of an error, %FALSE is also returned. Check @error to detect
324
* if an error occurred.
326
* Returns: %TRUE if the certificate is pinned.
329
gcr_trust_is_certificate_pinned_finish (GAsyncResult *result, GError **error)
331
GcrTrustOperation *op;
335
g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
336
g_return_val_if_fail (!error || !*error, FALSE);
340
object = g_async_result_get_source_object (result);
341
g_return_val_if_fail (g_simple_async_result_is_valid (result, object,
342
gcr_trust_is_certificate_pinned_async), FALSE);
344
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
347
op = trust_operation_get (GCK_ENUMERATOR (object));
349
g_object_unref (object);
353
/* ----------------------------------------------------------------------------------
354
* ADD PINNED CERTIFICATE
357
static GckEnumerator*
358
prepare_add_pinned_certificate (GcrCertificate *certificate, const gchar *purpose, const gchar *peer)
360
GckAttributes *attrs;
364
attrs = prepare_trust_attrs (certificate, CKT_X_PINNED_CERTIFICATE);
365
g_return_val_if_fail (attrs, NULL);
367
gck_attributes_add_string (attrs, CKA_X_PURPOSE, purpose);
368
gck_attributes_add_string (attrs, CKA_X_PEER, peer);
369
gck_attributes_add_boolean (attrs, CKA_TOKEN, TRUE);
371
slots = gcr_pkcs11_get_trust_lookup_slots ();
372
en = gck_slots_enumerate_objects (slots, attrs, CKF_RW_SESSION);
373
trust_operation_init (en, attrs);
374
gck_attributes_unref (attrs);
375
gck_list_unref_free (slots);
381
perform_add_pinned_certificate (GckEnumerator *en, GCancellable *cancellable, GError **error)
383
GcrTrustOperation *op;
384
GckAttributes *attrs;
385
gboolean ret = FALSE;
391
op = trust_operation_get (en);
392
g_assert (op != NULL);
394
/* We need an error below */
395
if (error && !*error)
398
object = gck_enumerator_next (en, cancellable, error);
402
/* It already exists */
404
g_object_unref (object);
408
attrs = gck_attributes_new ();
409
gck_attributes_add_all (attrs, op->attrs);
411
/* TODO: Add relevant label */
413
/* Find an appropriate token */
414
slot = gcr_pkcs11_get_trust_store_slot ();
416
g_set_error (error, GCK_ERROR, CKR_FUNCTION_FAILED,
417
/* Translators: A pinned certificate is an exception which
418
trusts a given certificate explicitly for a purpose and
419
communication with a certain peer. */
420
_("Couldn't find a place to store the pinned certificate"));
423
session = gck_slot_open_session (slot, CKF_RW_SESSION, NULL, error);
424
if (session != NULL) {
425
object = gck_session_create_object (session, attrs, cancellable, error);
426
if (object != NULL) {
427
g_object_unref (object);
431
g_object_unref (session);
434
g_object_unref (slot);
437
gck_attributes_unref (attrs);
439
/* Our own local error pointer */
440
g_clear_error (&lerr);
446
* gcr_trust_add_pinned_certificate:
447
* @certificate: a #GcrCertificate
448
* @purpose: the purpose string
449
* @peer: the peer for this pinned certificate
450
* @cancellable: a #GCancellable
451
* @error: a #GError, or NULL
453
* Add a pinned @certificate for connections to @peer for @purpose. A pinned
454
* certificate overrides all other certificate verification and should be
457
* If the same pinned certificate already exists, then this operation
458
* does not add another, and succeeds without error.
460
* This call may block, see gcr_trust_add_pinned_certificate_async() for the
461
* non-blocking version.
463
* Returns: %TRUE if the pinned certificate is recorded successfully
466
gcr_trust_add_pinned_certificate (GcrCertificate *certificate, const gchar *purpose, const gchar *peer,
467
GCancellable *cancellable, GError **error)
472
g_return_val_if_fail (GCR_IS_CERTIFICATE (certificate), FALSE);
473
g_return_val_if_fail (purpose, FALSE);
474
g_return_val_if_fail (peer, FALSE);
478
en = prepare_add_pinned_certificate (certificate, purpose, peer);
479
g_return_val_if_fail (en, FALSE);
481
ret = perform_add_pinned_certificate (en, cancellable, error);
489
thread_add_pinned_certificate (GSimpleAsyncResult *result, GObject *object, GCancellable *cancel)
491
GError *error = NULL;
493
perform_add_pinned_certificate (GCK_ENUMERATOR (object), cancel, &error);
496
g_simple_async_result_set_from_error (result, error);
497
g_clear_error (&error);
502
* gcr_trust_add_pinned_certificate_async:
503
* @certificate: a #GcrCertificate
504
* @purpose: the purpose string
505
* @peer: the peer for this pinned certificate
506
* @cancellable: a #GCancellable
507
* @callback: a #GAsyncReadyCallback to call when the operation completes
508
* @user_data: the data to pass to callback function
510
* Add a pinned certificate for communication with @peer for @purpose. A pinned
511
* certificate overrides all other certificate verification and should be used
514
* If the same pinned certificate already exists, then this operation
515
* does not add another, and succeeds without error.
517
* When the operation is finished, callback will be called. You can then call
518
* gcr_trust_add_pinned_certificate_finish() to get the result of the
522
gcr_trust_add_pinned_certificate_async (GcrCertificate *certificate, const gchar *purpose,
523
const gchar *peer, GCancellable *cancellable,
524
GAsyncReadyCallback callback, gpointer user_data)
526
GSimpleAsyncResult *async;
529
g_return_if_fail (GCR_IS_CERTIFICATE (certificate));
530
g_return_if_fail (purpose);
531
g_return_if_fail (peer);
535
en = prepare_add_pinned_certificate (certificate, purpose, peer);
536
g_return_if_fail (en);
538
async = g_simple_async_result_new (G_OBJECT (en), callback, user_data,
539
gcr_trust_add_pinned_certificate_async);
541
g_simple_async_result_run_in_thread (async, thread_add_pinned_certificate,
542
G_PRIORITY_DEFAULT, cancellable);
544
g_object_unref (async);
549
* gcr_trust_add_pinned_certificate_finish:
550
* @result: the #GAsyncResult passed to the callback
551
* @error: a #GError, or NULL
553
* Finishes an asynchronous operation started by
554
* gcr_trust_add_pinned_certificate_async().
556
* Returns: %TRUE if the pinned certificate is recorded successfully
559
gcr_trust_add_pinned_certificate_finish (GAsyncResult *result, GError **error)
563
g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
564
g_return_val_if_fail (!error || !*error, FALSE);
568
object = g_async_result_get_source_object (result);
569
g_return_val_if_fail (g_simple_async_result_is_valid (result, object,
570
gcr_trust_add_pinned_certificate_async), FALSE);
571
g_object_unref (object);
573
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
579
/* -----------------------------------------------------------------------
580
* REMOVE PINNED CERTIFICATE
583
static GckEnumerator*
584
prepare_remove_pinned_certificate (GcrCertificate *certificate, const gchar *purpose,
587
GckAttributes *attrs;
591
attrs = prepare_trust_attrs (certificate, CKT_X_PINNED_CERTIFICATE);
592
g_return_val_if_fail (attrs, NULL);
594
gck_attributes_add_string (attrs, CKA_X_PURPOSE, purpose);
595
gck_attributes_add_string (attrs, CKA_X_PEER, peer);
597
slots = gcr_pkcs11_get_trust_lookup_slots ();
598
en = gck_slots_enumerate_objects (slots, attrs, CKF_RW_SESSION);
599
trust_operation_init (en, attrs);
600
gck_attributes_unref (attrs);
601
gck_list_unref_free (slots);
607
perform_remove_pinned_certificate (GckEnumerator *en, GCancellable *cancellable, GError **error)
609
GcrTrustOperation *op;
613
op = trust_operation_get (en);
614
g_assert (op != NULL);
616
/* We need an error below */
617
if (error && !*error)
620
objects = gck_enumerator_next_n (en, -1, cancellable, error);
624
for (l = objects; l; l = g_list_next (l)) {
625
if (!gck_object_destroy (l->data, cancellable, error)) {
627
/* In case there's a race condition */
628
if (g_error_matches (*error, GCK_ERROR, CKR_OBJECT_HANDLE_INVALID)) {
629
g_clear_error (error);
633
gck_list_unref_free (objects);
638
gck_list_unref_free (objects);
643
* gcr_trust_remove_pinned_certificate:
644
* @certificate: a #GcrCertificate
645
* @purpose: the purpose string
646
* @peer: the peer for this pinned certificate
647
* @cancellable: a #GCancellable
648
* @error: a #GError, or NULL
650
* Remove a pinned certificate for communication with @peer for @purpose.
652
* If the same pinned certificate does not exist, or was already removed,
653
* then this operation succeeds without error.
655
* This call may block, see gcr_trust_remove_pinned_certificate_async() for the
656
* non-blocking version.
658
* Returns: %TRUE if the pinned certificate no longer exists
661
gcr_trust_remove_pinned_certificate (GcrCertificate *certificate, const gchar *purpose, const gchar *peer,
662
GCancellable *cancellable, GError **error)
667
g_return_val_if_fail (GCR_IS_CERTIFICATE (certificate), FALSE);
668
g_return_val_if_fail (purpose, FALSE);
669
g_return_val_if_fail (peer, FALSE);
673
en = prepare_remove_pinned_certificate (certificate, purpose, peer);
674
g_return_val_if_fail (en, FALSE);
676
ret = perform_remove_pinned_certificate (en, cancellable, error);
684
thread_remove_pinned_certificate (GSimpleAsyncResult *result, GObject *object, GCancellable *cancel)
686
GError *error = NULL;
688
perform_remove_pinned_certificate (GCK_ENUMERATOR (object), cancel, &error);
691
g_simple_async_result_set_from_error (result, error);
692
g_clear_error (&error);
697
* gcr_trust_remove_pinned_certificate_async:
698
* @certificate: a #GcrCertificate
699
* @purpose: the purpose string
700
* @peer: the peer for this pinned certificate
701
* @cancellable: a #GCancellable
702
* @callback: a #GAsyncReadyCallback to call when the operation completes
703
* @user_data: the data to pass to callback function
705
* Remove a pinned certificate for communication with @peer for @purpose.
707
* If the same pinned certificate does not exist, or was already removed,
708
* then this operation succeeds without error.
710
* When the operation is finished, callback will be called. You can then call
711
* gcr_trust_remove_pinned_certificate_finish() to get the result of the
715
gcr_trust_remove_pinned_certificate_async (GcrCertificate *certificate, const gchar *purpose,
716
const gchar *peer, GCancellable *cancellable,
717
GAsyncReadyCallback callback, gpointer user_data)
719
GSimpleAsyncResult *async;
722
g_return_if_fail (GCR_IS_CERTIFICATE (certificate));
723
g_return_if_fail (purpose);
724
g_return_if_fail (peer);
728
en = prepare_remove_pinned_certificate (certificate, purpose, peer);
729
g_return_if_fail (en);
731
async = g_simple_async_result_new (G_OBJECT (en), callback, user_data,
732
gcr_trust_remove_pinned_certificate_async);
734
g_simple_async_result_run_in_thread (async, thread_remove_pinned_certificate,
735
G_PRIORITY_DEFAULT, cancellable);
737
g_object_unref (async);
742
* gcr_trust_remove_pinned_certificate_finish:
743
* @result: the #GAsyncResult passed to the callback
744
* @error: a #GError, or NULL
746
* Finishes an asynchronous operation started by
747
* gcr_trust_remove_pinned_certificate_async().
749
* Returns: %TRUE if the pinned certificate no longer exists
752
gcr_trust_remove_pinned_certificate_finish (GAsyncResult *result, GError **error)
756
g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
757
g_return_val_if_fail (!error || !*error, FALSE);
761
object = g_async_result_get_source_object (result);
762
g_return_val_if_fail (g_simple_async_result_is_valid (result, object,
763
gcr_trust_remove_pinned_certificate_async), FALSE);
764
g_object_unref (object);
766
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
772
/* ----------------------------------------------------------------------------------
776
static GckEnumerator*
777
prepare_is_certificate_anchored (GcrCertificate *certificate, const gchar *purpose)
779
GckAttributes *attrs;
783
attrs = prepare_trust_attrs (certificate, CKT_X_ANCHORED_CERTIFICATE);
784
g_return_val_if_fail (attrs, NULL);
786
gck_attributes_add_string (attrs, CKA_X_PURPOSE, purpose);
788
slots = gcr_pkcs11_get_trust_lookup_slots ();
789
en = gck_slots_enumerate_objects (slots, attrs, 0);
790
trust_operation_init (en, attrs);
791
gck_attributes_unref (attrs);
792
gck_list_unref_free (slots);
798
perform_is_certificate_anchored (GckEnumerator *en, GCancellable *cancellable, GError **error)
800
GcrTrustOperation *op;
803
op = trust_operation_get (en);
804
g_assert (op != NULL);
806
object = gck_enumerator_next (en, cancellable, error);
807
if (object != NULL) {
809
g_object_unref (object);
818
* gcr_trust_is_certificate_anchored:
819
* @certificate: a #GcrCertificate to check
820
* @purpose: the purpose string
821
* @cancellable: a #GCancellable
822
* @error: a #GError, or NULL
824
* Check if the @certificate is a trust anchor for the given @purpose. A trust
825
* anchor is used to verify the signatures on other certificates when verifying
826
* a certificate chain. Also known as a trusted certificate authority.
828
* This call may block, see gcr_trust_is_certificate_anchored_async() for the
829
* non-blocking version.
831
* In the case of an error, %FALSE is also returned. Check @error to detect
832
* if an error occurred.
834
* Returns: %TRUE if the certificate is a trust anchor
837
gcr_trust_is_certificate_anchored (GcrCertificate *certificate, const gchar *purpose,
838
GCancellable *cancellable, GError **error)
843
g_return_val_if_fail (GCR_IS_CERTIFICATE (certificate), FALSE);
844
g_return_val_if_fail (purpose, FALSE);
848
en = prepare_is_certificate_anchored (certificate, purpose);
849
g_return_val_if_fail (en, FALSE);
851
ret = perform_is_certificate_anchored (en, cancellable, error);
859
thread_is_certificate_anchored (GSimpleAsyncResult *result, GObject *object, GCancellable *cancel)
861
GError *error = NULL;
863
perform_is_certificate_anchored (GCK_ENUMERATOR (object), cancel, &error);
866
g_simple_async_result_set_from_error (result, error);
867
g_clear_error (&error);
872
* gcr_trust_is_certificate_anchored_async:
873
* @certificate: a #GcrCertificate to check
874
* @purpose: the purpose string
875
* @cancellable: a #GCancellable
876
* @callback: a #GAsyncReadyCallback to call when the operation completes
877
* @user_data: the data to pass to callback function
879
* Check if the @certificate is a trust anchor for the given @purpose. A trust
880
* anchor is used to verify the signatures on other certificates when verifying
881
* a certificate chain. Also known as a trusted certificate authority.
883
* When the operation is finished, callback will be called. You can then call
884
* gcr_trust_is_certificate_anchored_finish() to get the result of the operation.
887
gcr_trust_is_certificate_anchored_async (GcrCertificate *certificate, const gchar *purpose,
888
GCancellable *cancellable, GAsyncReadyCallback callback,
891
GSimpleAsyncResult *async;
894
g_return_if_fail (GCR_IS_CERTIFICATE (certificate));
895
g_return_if_fail (purpose);
899
en = prepare_is_certificate_anchored (certificate, purpose);
900
g_return_if_fail (en);
902
async = g_simple_async_result_new (G_OBJECT (en), callback, user_data,
903
gcr_trust_is_certificate_anchored_async);
905
g_simple_async_result_run_in_thread (async, thread_is_certificate_anchored,
906
G_PRIORITY_DEFAULT, cancellable);
908
g_object_unref (async);
913
* gcr_trust_is_certificate_anchored_finish:
914
* @result: the #GAsyncResult passed to the callback
915
* @error: a #GError, or NULL
917
* Finishes an asynchronous operation started by
918
* gcr_trust_is_certificate_anchored_async().
920
* In the case of an error, %FALSE is also returned. Check @error to detect
921
* if an error occurred.
923
* Returns: %TRUE if the certificate is a trust anchor
926
gcr_trust_is_certificate_anchored_finish (GAsyncResult *result, GError **error)
928
GcrTrustOperation *op;
932
g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
933
g_return_val_if_fail (!error || !*error, FALSE);
937
object = g_async_result_get_source_object (result);
938
g_return_val_if_fail (g_simple_async_result_is_valid (result, object,
939
gcr_trust_is_certificate_anchored_async), FALSE);
941
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
944
op = trust_operation_get (GCK_ENUMERATOR (object));
946
g_object_unref (object);