[gnome-keyring/trust-store] [gcr] Document trust storage and lookup functions.
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-keyring/trust-store] [gcr] Document trust storage and lookup functions.
- Date: Tue, 7 Dec 2010 19:30:54 +0000 (UTC)
commit 73cb96415080d56ddee81585414b1676d637e444
Author: Stef Walter <stefw collabora co uk>
Date: Tue Dec 7 18:47:49 2010 +0000
[gcr] Document trust storage and lookup functions.
docs/reference/gcr/gcr-docs.sgml | 5 +-
docs/reference/gcr/gcr-sections.txt | 87 ++------
gcr/gcr-trust.c | 427 ++++++++++++++++++++++++++++-------
gcr/gcr-trust.h | 40 ++--
4 files changed, 388 insertions(+), 171 deletions(-)
---
diff --git a/docs/reference/gcr/gcr-docs.sgml b/docs/reference/gcr/gcr-docs.sgml
index f4ef9c7..f7a0eaa 100644
--- a/docs/reference/gcr/gcr-docs.sgml
+++ b/docs/reference/gcr/gcr-docs.sgml
@@ -13,15 +13,12 @@
<chapter>
<title>[Insert title here]</title>
- <xi:include href="xml/gcr-import-dialog.xml"/>
- <xi:include href="xml/gcr-certificate-details-widget.xml"/>
- <xi:include href="xml/gcr-certificate-basics-widget.xml"/>
<xi:include href="xml/gcr-parser.xml"/>
<xi:include href="xml/gcr-certificate.xml"/>
<xi:include href="xml/gcr-initializer.xml"/>
<xi:include href="xml/gcr-importer.xml"/>
<xi:include href="xml/gcr-simple-certificate.xml"/>
- <xi:include href="xml/gcr-xxx.xml"/>
<xi:include href="xml/gcr-types.xml"/>
+ <xi:include href="xml/gcr-trust.xml"/>
</chapter>
</book>
diff --git a/docs/reference/gcr/gcr-sections.txt b/docs/reference/gcr/gcr-sections.txt
index ac83c61..fec7175 100644
--- a/docs/reference/gcr/gcr-sections.txt
+++ b/docs/reference/gcr/gcr-sections.txt
@@ -13,42 +13,6 @@ GCR_IMPORT_DIALOG_GET_CLASS
</SECTION>
<SECTION>
-<FILE>gcr-certificate-details-widget</FILE>
-GcrCertificateDetailsWidgetPrivate
-<TITLE>GcrCertificateDetailsWidget</TITLE>
-GcrCertificateDetailsWidget
-gcr_certificate_details_widget_new
-gcr_certificate_details_widget_get_certificate
-gcr_certificate_details_widget_set_certificate
-<SUBSECTION Standard>
-GCR_CERTIFICATE_DETAILS_WIDGET
-GCR_IS_CERTIFICATE_DETAILS_WIDGET
-GCR_TYPE_CERTIFICATE_DETAILS_WIDGET
-gcr_certificate_details_widget_get_type
-GCR_CERTIFICATE_DETAILS_WIDGET_CLASS
-GCR_IS_CERTIFICATE_DETAILS_WIDGET_CLASS
-GCR_CERTIFICATE_DETAILS_WIDGET_GET_CLASS
-</SECTION>
-
-<SECTION>
-<FILE>gcr-certificate-basics-widget</FILE>
-GcrCertificateBasicsWidgetPrivate
-<TITLE>GcrCertificateBasicsWidget</TITLE>
-GcrCertificateBasicsWidget
-gcr_certificate_basics_widget_new
-gcr_certificate_basics_widget_get_certificate
-gcr_certificate_basics_widget_set_certificate
-<SUBSECTION Standard>
-GCR_CERTIFICATE_BASICS_WIDGET
-GCR_IS_CERTIFICATE_BASICS_WIDGET
-GCR_TYPE_CERTIFICATE_BASICS_WIDGET
-gcr_certificate_basics_widget_get_type
-GCR_CERTIFICATE_BASICS_WIDGET_CLASS
-GCR_IS_CERTIFICATE_BASICS_WIDGET_CLASS
-GCR_CERTIFICATE_BASICS_WIDGET_GET_CLASS
-</SECTION>
-
-<SECTION>
<FILE>gcr-parser</FILE>
GcrParsedItem
GcrParserPrivate
@@ -165,36 +129,21 @@ GCR_SIMPLE_CERTIFICATE_GET_CLASS
</SECTION>
<SECTION>
-<FILE>gcr-xxx</FILE>
-GcrXxxPrivate
-<TITLE>GcrXxx</TITLE>
-GcrXxx
-gcr_xxx_new
-<SUBSECTION Standard>
-GCR_XXX
-GCR_IS_XXX
-GCR_TYPE_XXX
-gcr_xxx_get_type
-GCR_XXX_CLASS
-GCR_IS_XXX_CLASS
-GCR_XXX_GET_CLASS
-</SECTION>
-
-<SECTION>
-<FILE>gcr-marshal</FILE>
-</SECTION>
-
-<SECTION>
-<FILE>gcr-internal</FILE>
-</SECTION>
-
-<SECTION>
-<FILE>gcr</FILE>
-</SECTION>
-
-<SECTION>
-<FILE>gcr-types</FILE>
-GCR_DATA_ERROR
-gcr_data_error_get_domain
-</SECTION>
-
+<FILE>gcr-trust</FILE>
+GCR_PURPOSE_SERVER_AUTH
+GCR_PURPOSE_CLIENT_AUTH
+GCR_PURPOSE_EMAIL
+GCR_PURPOSE_CODE_SIGNING
+gcr_trust_is_certificate_anchor
+gcr_trust_is_certificate_anchor_async
+gcr_trust_is_certificate_anchor_finish
+gcr_trust_is_certificate_exception
+gcr_trust_is_certificate_exception_async
+gcr_trust_is_certificate_exception_finish
+gcr_trust_add_certificate_exception
+gcr_trust_add_certificate_exception_async
+gcr_trust_add_certificate_exception_finish
+gcr_trust_remove_certificate_exception
+gcr_trust_remove_certificate_exception_async
+gcr_trust_remove_certificate_exception_finish
+</SECTION>
\ No newline at end of file
diff --git a/gcr/gcr-trust.c b/gcr/gcr-trust.c
index 809636b..37fb2ea 100644
--- a/gcr/gcr-trust.c
+++ b/gcr/gcr-trust.c
@@ -1,7 +1,7 @@
/*
* gnome-keyring
*
- * Copyright (C) 2010 Stefan Walter
+ * Copyright (C) 2010 Collabora Ltd
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
@@ -17,6 +17,8 @@
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw collabora co uk>
*/
#include "config.h"
@@ -31,6 +33,66 @@
#include "pkcs11/pkcs11n.h"
#include "pkcs11/pkcs11i.h"
+/**
+ * SECTION:gcr-trust
+ * @title: Trust Storage and Lookups
+ * @short_description: Used to store and lookup bits of information used for
+ * verifying certificates.
+ *
+ * These functions provide access to stored information about which
+ * certificates the system and user trusts as certificate authority trust
+ * anchors, or overrides to the normal verification of certificates.
+ *
+ * Trust anchors are used to verify the certificate authority in a certificate
+ * chain. Trust anchors are always valid for a given purpose. The most common
+ * purpose is the #GCR_PURPOSE_SERVER_AUTH and is used for a client application
+ * to verify that the certificate at the server side of a TLS connection is
+ * authorized to act as such. To check if a certificate is a trust anchor use
+ * gcr_trust_is_certificate_anchor().
+ *
+ * Certificate exceptions are used when a user overrides the default trust
+ * decision for a given certificate. They're often used with self-signed
+ * certificates. Certificate exceptions are always only valid for a single peer
+ * such as the remote host with which TLS is being performed. To lookup
+ * certificate exceptions use gcr_trust_is_certificate_exception().
+ *
+ * After the user has requested to override the trust decision
+ * about a given certificate then a certificate exception can be added by using
+ * the gcr_trust_add_certificate_exception() function.
+ *
+ * These functions do not constitute a viable method for verifying certificates
+ * used in TLS or other locations. Instead they support such verification
+ * by providing some of the needed data for a trust decision.
+ *
+ * The storage is provided by pluggable PKCS\#11 modules.
+ */
+
+/**
+ * GCR_PURPOSE_SERVER_AUTH:
+ *
+ * The purpose used to verify the server certificate in a TLS connection. This
+ * is the most common purpose in use.
+ */
+
+/**
+ * GCR_PURPOSE_CLIENT_AUTH:
+ *
+ * The purpose used to verify the client certificate in a TLS connection.
+ */
+
+/**
+ * GCR_PURPOSE_CODE_SIGNING:
+ *
+ * The purpose used to verify certificate used for the signature on signed code.
+ */
+
+/**
+ * GCR_PURPOSE_CODE_SIGNING:
+ *
+ * The purpose used to verify certificates that are used in email communication
+ * such as S/MIME.
+ */
+
/* ----------------------------------------------------------------------------------
* HELPERS
*/
@@ -85,7 +147,7 @@ trust_operation_get (GckEnumerator *en)
}
static GckAttributes*
-prepare_trust_attrs (GcrCertificate *cert, CK_ASSERTION_TYPE type)
+prepare_trust_attrs (GcrCertificate *certificate, CK_ASSERTION_TYPE type)
{
GckAttributes *attrs;
gconstpointer data;
@@ -95,7 +157,7 @@ prepare_trust_attrs (GcrCertificate *cert, CK_ASSERTION_TYPE type)
gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_G_TRUST_ASSERTION);
gck_attributes_add_ulong (attrs, CKA_G_ASSERTION_TYPE, type);
- data = gcr_certificate_get_der_data (cert, &n_data);
+ data = gcr_certificate_get_der_data (certificate, &n_data);
g_return_val_if_fail (data, NULL);
gck_attributes_add_data (attrs, CKA_G_CERTIFICATE_VALUE, data, n_data);
@@ -107,7 +169,7 @@ prepare_trust_attrs (GcrCertificate *cert, CK_ASSERTION_TYPE type)
*/
static GckEnumerator*
-prepare_is_certificate_exception (GcrCertificate *cert, const gchar *purpose, const gchar *peer)
+prepare_is_certificate_exception (GcrCertificate *certificate, const gchar *purpose, const gchar *peer)
{
GckAttributes *attrs;
GckEnumerator *en;
@@ -115,7 +177,7 @@ prepare_is_certificate_exception (GcrCertificate *cert, const gchar *purpose, co
modules = _gcr_get_pkcs11_modules ();
- attrs = prepare_trust_attrs (cert, CKT_G_CERTIFICATE_TRUST_EXCEPTION);
+ attrs = prepare_trust_attrs (certificate, CKT_G_CERTIFICATE_TRUST_EXCEPTION);
g_return_val_if_fail (attrs, NULL);
gck_attributes_add_string (attrs, CKA_G_PURPOSE, purpose);
@@ -135,7 +197,7 @@ prepare_is_certificate_exception (GcrCertificate *cert, const gchar *purpose, co
}
static gboolean
-perform_is_certificate_exception (GckEnumerator *en, GCancellable *cancel, GError **error)
+perform_is_certificate_exception (GckEnumerator *en, GCancellable *cancellable, GError **error)
{
GcrTrustOperation *op;
GckObject *object;
@@ -145,7 +207,7 @@ perform_is_certificate_exception (GckEnumerator *en, GCancellable *cancel, GErro
g_assert (op != NULL);
g_assert (op->found == FALSE);
- object = gck_enumerator_next (en, cancel, error);
+ object = gck_enumerator_next (en, cancellable, error);
op->found = (object != NULL);
if (object)
@@ -154,21 +216,41 @@ perform_is_certificate_exception (GckEnumerator *en, GCancellable *cancel, GErro
return op->found;
}
+/**
+ * gcr_trust_is_certificate_exception:
+ * @certificate: a #GcrCertificate to check
+ * @purpose: the purpose string
+ * @peer: the peer for this exception
+ * @cancellable: a #GCancellable
+ * @error: a #GError, or NULL
+ *
+ * Check if there is a recorded exception for connections using @certificate
+ * for @purpose to communicate with @peer. A certificate exception overrides
+ * all other certificate verification.
+ *
+ * This call may block, see gcr_trust_is_certificate_exception_async() for the
+ * non-blocking version.
+ *
+ * In the case of an error, %FALSE is also returned. Check @error to detect
+ * if an error occurred.
+ *
+ * Returns: %TRUE if the certificate has a certificate exception
+ */
gboolean
-gcr_trust_is_certificate_exception (GcrCertificate *cert, const gchar *purpose,
- const gchar *peer, GCancellable *cancel, GError **error)
+gcr_trust_is_certificate_exception (GcrCertificate *certificate, const gchar *purpose,
+ const gchar *peer, GCancellable *cancellable, GError **error)
{
GckEnumerator *en;
gboolean ret;
- g_return_val_if_fail (GCR_IS_CERTIFICATE (cert), FALSE);
+ g_return_val_if_fail (GCR_IS_CERTIFICATE (certificate), FALSE);
g_return_val_if_fail (purpose, FALSE);
g_return_val_if_fail (peer, FALSE);
- en = prepare_is_certificate_exception (cert, purpose, peer);
+ en = prepare_is_certificate_exception (certificate, purpose, peer);
g_return_val_if_fail (en, FALSE);
- ret = perform_is_certificate_exception (en, cancel, error);
+ ret = perform_is_certificate_exception (en, cancellable, error);
g_object_unref (en);
@@ -176,50 +258,80 @@ gcr_trust_is_certificate_exception (GcrCertificate *cert, const gchar *purpose,
}
static void
-thread_is_certificate_exception (GSimpleAsyncResult *res, GObject *object, GCancellable *cancel)
+thread_is_certificate_exception (GSimpleAsyncResult *result, GObject *object, GCancellable *cancel)
{
GError *error = NULL;
perform_is_certificate_exception (GCK_ENUMERATOR (object), cancel, &error);
if (error != NULL) {
- g_simple_async_result_set_from_error (res, error);
+ g_simple_async_result_set_from_error (result, error);
g_clear_error (&error);
}
}
+/**
+ * gcr_trust_is_certificate_exception_async:
+ * @certificate: a #GcrCertificate to check
+ * @purpose: the purpose string
+ * @peer: the peer for this exception
+ * @cancellable: a #GCancellable
+ * @callback: a #GAsyncReadyCallback to call when the operation completes
+ * @user_data: the data to pass to callback function
+ *
+ * Check if there is a recorded exception for connections using @certificate
+ * for @purpose to communicate with @peer. A certificate exception overrides
+ * all other certificate verification.
+ *
+ * When the operation is finished, callback will be called. You can then call
+ * gcr_trust_is_certificate_exception_finish() to get the result of the
+ * operation.
+ */
void
-gcr_trust_is_certificate_exception_async (GcrCertificate *cert, const gchar *purpose,
- const gchar *peer, GCancellable *cancel,
+gcr_trust_is_certificate_exception_async (GcrCertificate *certificate, const gchar *purpose,
+ const gchar *peer, GCancellable *cancellable,
GAsyncReadyCallback callback, gpointer user_data)
{
GSimpleAsyncResult *async;
GckEnumerator *en;
- en = prepare_is_certificate_exception (cert, purpose, peer);
+ en = prepare_is_certificate_exception (certificate, purpose, peer);
g_return_if_fail (en);
async = g_simple_async_result_new (G_OBJECT (en), callback, user_data,
gcr_trust_is_certificate_exception_async);
g_simple_async_result_run_in_thread (async, thread_is_certificate_exception,
- G_PRIORITY_DEFAULT, cancel);
+ G_PRIORITY_DEFAULT, cancellable);
g_object_unref (async);
g_object_unref (en);
}
+/**
+ * gcr_trust_is_certificate_exception_finish:
+ * @result: the #GAsyncResult passed to the callback
+ * @error: a #GError, or NULL
+ *
+ * Finishes an asynchronous operation started by
+ * gcr_trust_is_certificate_exception_async().
+ *
+ * In the case of an error, %FALSE is also returned. Check @error to detect
+ * if an error occurred.
+ *
+ * Returns: %TRUE if the certificate has a certificate exception
+ */
gboolean
-gcr_trust_is_certificate_exception_finish (GAsyncResult *res, GError **error)
+gcr_trust_is_certificate_exception_finish (GAsyncResult *result, GError **error)
{
GcrTrustOperation *op;
GObject *object;
- object = g_async_result_get_source_object (res);
- g_return_val_if_fail (g_simple_async_result_is_valid (res, object,
+ object = g_async_result_get_source_object (result);
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, object,
gcr_trust_is_certificate_exception_async), FALSE);
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
return FALSE;
op = trust_operation_get (GCK_ENUMERATOR (object));
@@ -231,7 +343,7 @@ gcr_trust_is_certificate_exception_finish (GAsyncResult *res, GError **error)
*/
static GckEnumerator*
-prepare_add_certificate_exception (GcrCertificate *cert, const gchar *purpose, const gchar *peer)
+prepare_add_certificate_exception (GcrCertificate *certificate, const gchar *purpose, const gchar *peer)
{
GckAttributes *attrs;
GckEnumerator *en;
@@ -239,7 +351,7 @@ prepare_add_certificate_exception (GcrCertificate *cert, const gchar *purpose, c
modules = _gcr_get_pkcs11_modules ();
- attrs = prepare_trust_attrs (cert, CKT_G_CERTIFICATE_TRUST_EXCEPTION);
+ attrs = prepare_trust_attrs (certificate, CKT_G_CERTIFICATE_TRUST_EXCEPTION);
g_return_val_if_fail (attrs, NULL);
gck_attributes_add_string (attrs, CKA_G_PURPOSE, purpose);
@@ -260,7 +372,7 @@ prepare_add_certificate_exception (GcrCertificate *cert, const gchar *purpose, c
}
static gboolean
-perform_add_certificate_exception (GckEnumerator *en, GCancellable *cancel, GError **error)
+perform_add_certificate_exception (GckEnumerator *en, GCancellable *cancellable, GError **error)
{
GcrTrustOperation *op;
GckAttributes *attrs;
@@ -277,7 +389,7 @@ perform_add_certificate_exception (GckEnumerator *en, GCancellable *cancel, GErr
if (error && !*error)
*error = lerr;
- object = gck_enumerator_next (en, cancel, error);
+ object = gck_enumerator_next (en, cancellable, error);
if (*error)
return FALSE;
@@ -297,7 +409,7 @@ perform_add_certificate_exception (GckEnumerator *en, GCancellable *cancel, GErr
if (slot != NULL) {
session = gck_slot_open_session (slot, CKF_RW_SESSION, NULL, error);
if (session != NULL) {
- object = gck_session_create_object (session, attrs, cancel, error);
+ object = gck_session_create_object (session, attrs, cancellable, error);
if (object != NULL) {
g_object_unref (object);
ret = TRUE;
@@ -317,17 +429,37 @@ perform_add_certificate_exception (GckEnumerator *en, GCancellable *cancel, GErr
return ret;
}
+/**
+ * gcr_trust_add_certificate_exception:
+ * @certificate: a #GcrCertificate
+ * @purpose: the purpose string
+ * @peer: the peer for this exception
+ * @cancellable: a #GCancellable
+ * @error: a #GError, or NULL
+ *
+ * Add a recorded exception for connections using @certificate for @purpose
+ * to communicate with @peer. A certificate exception overrides all other
+ * certificate verification and should be used with care.
+ *
+ * If the same certificate exception already exists, then this operation
+ * does not add another, and succeeds without error.
+ *
+ * This call may block, see gcr_trust_add_certificate_exception_async() for the
+ * non-blocking version.
+ *
+ * Returns: %TRUE if the certificate exception is recorded successfully
+ */
gboolean
-gcr_trust_add_certificate_exception (GcrCertificate *cert, const gchar *purpose, const gchar *peer,
- GCancellable *cancel, GError **error)
+gcr_trust_add_certificate_exception (GcrCertificate *certificate, const gchar *purpose, const gchar *peer,
+ GCancellable *cancellable, GError **error)
{
GckEnumerator *en;
gboolean ret;
- en = prepare_add_certificate_exception (cert, purpose, peer);
+ en = prepare_add_certificate_exception (certificate, purpose, peer);
g_return_val_if_fail (en, FALSE);
- ret = perform_add_certificate_exception (en, cancel, error);
+ ret = perform_add_certificate_exception (en, cancellable, error);
g_object_unref (en);
@@ -335,49 +467,79 @@ gcr_trust_add_certificate_exception (GcrCertificate *cert, const gchar *purpose,
}
static void
-thread_add_certificate_exception (GSimpleAsyncResult *res, GObject *object, GCancellable *cancel)
+thread_add_certificate_exception (GSimpleAsyncResult *result, GObject *object, GCancellable *cancel)
{
GError *error = NULL;
perform_add_certificate_exception (GCK_ENUMERATOR (object), cancel, &error);
if (error != NULL) {
- g_simple_async_result_set_from_error (res, error);
+ g_simple_async_result_set_from_error (result, error);
g_clear_error (&error);
}
}
+/**
+ * gcr_trust_add_certificate_exception_async:
+ * @certificate: a #GcrCertificate
+ * @purpose: the purpose string
+ * @peer: the peer for this exception
+ * @cancellable: a #GCancellable
+ * @callback: a #GAsyncReadyCallback to call when the operation completes
+ * @user_data: the data to pass to callback function
+ *
+ * Add a recorded exception for connections using @certificate for @purpose
+ * to communicate with @peer. A certificate exception overrides all other
+ * certificate verification and should be used with care.
+ *
+ * If the same certificate exception already exists, then this operation
+ * does not add another, and succeeds without error.
+ *
+ * When the operation is finished, callback will be called. You can then call
+ * gcr_trust_add_certificate_exception_finish() to get the result of the
+ * operation.
+ */
void
-gcr_trust_add_certificate_exception_async (GcrCertificate *cert, const gchar *purpose,
- const gchar *peer, GCancellable *cancel,
+gcr_trust_add_certificate_exception_async (GcrCertificate *certificate, const gchar *purpose,
+ const gchar *peer, GCancellable *cancellable,
GAsyncReadyCallback callback, gpointer user_data)
{
GSimpleAsyncResult *async;
GckEnumerator *en;
- en = prepare_add_certificate_exception (cert, purpose, peer);
+ en = prepare_add_certificate_exception (certificate, purpose, peer);
g_return_if_fail (en);
async = g_simple_async_result_new (G_OBJECT (en), callback, user_data,
gcr_trust_add_certificate_exception_async);
g_simple_async_result_run_in_thread (async, thread_add_certificate_exception,
- G_PRIORITY_DEFAULT, cancel);
+ G_PRIORITY_DEFAULT, cancellable);
g_object_unref (async);
g_object_unref (en);
}
+/**
+ * gcr_trust_add_certificate_exception_finish:
+ * @result: the #GAsyncResult passed to the callback
+ * @error: a #GError, or NULL
+ *
+ * Finishes an asynchronous operation started by
+ * gcr_trust_add_certificate_exception_async().
+ *
+ * Returns: %TRUE if the certificate exception is recorded successfully
+ */
gboolean
-gcr_trust_add_certificate_exception_finish (GAsyncResult *res, GError **error)
+gcr_trust_add_certificate_exception_finish (GAsyncResult *result, GError **error)
{
GObject *object;
- object = g_async_result_get_source_object (res);
- g_return_val_if_fail (g_simple_async_result_is_valid (res, object,
+ object = g_async_result_get_source_object (result);
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, object,
gcr_trust_add_certificate_exception_async), FALSE);
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
return FALSE;
return TRUE;
@@ -388,7 +550,7 @@ gcr_trust_add_certificate_exception_finish (GAsyncResult *res, GError **error)
*/
static GckEnumerator*
-prepare_remove_certificate_exception (GcrCertificate *cert, const gchar *purpose,
+prepare_remove_certificate_exception (GcrCertificate *certificate, const gchar *purpose,
const gchar *peer)
{
GckAttributes *attrs;
@@ -397,7 +559,7 @@ prepare_remove_certificate_exception (GcrCertificate *cert, const gchar *purpose
modules = _gcr_get_pkcs11_modules ();
- attrs = prepare_trust_attrs (cert, CKT_G_CERTIFICATE_TRUST_EXCEPTION);
+ attrs = prepare_trust_attrs (certificate, CKT_G_CERTIFICATE_TRUST_EXCEPTION);
g_return_val_if_fail (attrs, NULL);
gck_attributes_add_string (attrs, CKA_G_PURPOSE, purpose);
@@ -417,7 +579,7 @@ prepare_remove_certificate_exception (GcrCertificate *cert, const gchar *purpose
}
static gboolean
-perform_remove_certificate_exception (GckEnumerator *en, GCancellable *cancel, GError **error)
+perform_remove_certificate_exception (GckEnumerator *en, GCancellable *cancellable, GError **error)
{
GcrTrustOperation *op;
GList *objects, *l;
@@ -430,12 +592,19 @@ perform_remove_certificate_exception (GckEnumerator *en, GCancellable *cancel, G
if (error && !*error)
*error = lerr;
- objects = gck_enumerator_next_n (en, -1, cancel, error);
+ objects = gck_enumerator_next_n (en, -1, cancellable, error);
if (*error)
return FALSE;
for (l = objects; l; l = g_list_next (l)) {
- if (!gck_object_destroy (l->data, cancel, error)) {
+ if (!gck_object_destroy (l->data, cancellable, error)) {
+
+ /* In case there's a race condition */
+ if (g_error_matches (*error, GCK_ERROR, CKR_OBJECT_HANDLE_INVALID)) {
+ g_clear_error (error);
+ continue;
+ }
+
gck_list_unref_free (objects);
return FALSE;
}
@@ -445,17 +614,36 @@ perform_remove_certificate_exception (GckEnumerator *en, GCancellable *cancel, G
return TRUE;
}
+/**
+ * gcr_trust_remove_certificate_exception:
+ * @certificate: a #GcrCertificate
+ * @purpose: the purpose string
+ * @peer: the peer for this exception
+ * @cancellable: a #GCancellable
+ * @error: a #GError, or NULL
+ *
+ * Remove a recorded exception for connections using @certificate for @purpose
+ * to communicate with @peer.
+ *
+ * If the same certificate exception does not exist, or was already removed,
+ * then this operation succeeds without error.
+ *
+ * This call may block, see gcr_trust_remove_certificate_exception_async() for the
+ * non-blocking version.
+ *
+ * Returns: %TRUE if the certificate exception no longer exists
+ */
gboolean
-gcr_trust_remove_certificate_exception (GcrCertificate *cert, const gchar *purpose, const gchar *peer,
- GCancellable *cancel, GError **error)
+gcr_trust_remove_certificate_exception (GcrCertificate *certificate, const gchar *purpose, const gchar *peer,
+ GCancellable *cancellable, GError **error)
{
GckEnumerator *en;
gboolean ret;
- en = prepare_remove_certificate_exception (cert, purpose, peer);
+ en = prepare_remove_certificate_exception (certificate, purpose, peer);
g_return_val_if_fail (en, FALSE);
- ret = perform_remove_certificate_exception (en, cancel, error);
+ ret = perform_remove_certificate_exception (en, cancellable, error);
g_object_unref (en);
@@ -463,49 +651,78 @@ gcr_trust_remove_certificate_exception (GcrCertificate *cert, const gchar *purpo
}
static void
-thread_remove_certificate_exception (GSimpleAsyncResult *res, GObject *object, GCancellable *cancel)
+thread_remove_certificate_exception (GSimpleAsyncResult *result, GObject *object, GCancellable *cancel)
{
GError *error = NULL;
perform_remove_certificate_exception (GCK_ENUMERATOR (object), cancel, &error);
if (error != NULL) {
- g_simple_async_result_set_from_error (res, error);
+ g_simple_async_result_set_from_error (result, error);
g_clear_error (&error);
}
}
+/**
+ * gcr_trust_remove_certificate_exception_async:
+ * @certificate: a #GcrCertificate
+ * @purpose: the purpose string
+ * @peer: the peer for this exception
+ * @cancellable: a #GCancellable
+ * @callback: a #GAsyncReadyCallback to call when the operation completes
+ * @user_data: the data to pass to callback function
+ *
+ * Remove a recorded exception for connections using @certificate for @purpose
+ * to communicate with @peer.
+ *
+ * If the same certificate exception does not exist, or was already removed,
+ * then this operation succeeds without error.
+ *
+ * When the operation is finished, callback will be called. You can then call
+ * gcr_trust_remove_certificate_exception_finish() to get the result of the
+ * operation.
+ */
void
-gcr_trust_remove_certificate_exception_async (GcrCertificate *cert, const gchar *purpose,
- const gchar *peer, GCancellable *cancel,
+gcr_trust_remove_certificate_exception_async (GcrCertificate *certificate, const gchar *purpose,
+ const gchar *peer, GCancellable *cancellable,
GAsyncReadyCallback callback, gpointer user_data)
{
GSimpleAsyncResult *async;
GckEnumerator *en;
- en = prepare_remove_certificate_exception (cert, purpose, peer);
+ en = prepare_remove_certificate_exception (certificate, purpose, peer);
g_return_if_fail (en);
async = g_simple_async_result_new (G_OBJECT (en), callback, user_data,
gcr_trust_remove_certificate_exception_async);
g_simple_async_result_run_in_thread (async, thread_remove_certificate_exception,
- G_PRIORITY_DEFAULT, cancel);
+ G_PRIORITY_DEFAULT, cancellable);
g_object_unref (async);
g_object_unref (en);
}
+/**
+ * gcr_trust_remove_certificate_exception_finish:
+ * @result: the #GAsyncResult passed to the callback
+ * @error: a #GError, or NULL
+ *
+ * Finishes an asynchronous operation started by
+ * gcr_trust_remove_certificate_exception_async().
+ *
+ * Returns: %TRUE if the certificate exception no longer exists
+ */
gboolean
-gcr_trust_remove_certificate_exception_finish (GAsyncResult *res, GError **error)
+gcr_trust_remove_certificate_exception_finish (GAsyncResult *result, GError **error)
{
GObject *object;
- object = g_async_result_get_source_object (res);
- g_return_val_if_fail (g_simple_async_result_is_valid (res, object,
+ object = g_async_result_get_source_object (result);
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, object,
gcr_trust_remove_certificate_exception_async), FALSE);
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
return FALSE;
return TRUE;
@@ -516,7 +733,7 @@ gcr_trust_remove_certificate_exception_finish (GAsyncResult *res, GError **error
*/
static GckEnumerator*
-prepare_is_certificate_anchor (GcrCertificate *cert, const gchar *purpose)
+prepare_is_certificate_anchor (GcrCertificate *certificate, const gchar *purpose)
{
GckAttributes *attrs;
GckEnumerator *en;
@@ -524,7 +741,7 @@ prepare_is_certificate_anchor (GcrCertificate *cert, const gchar *purpose)
modules = _gcr_get_pkcs11_modules ();
- attrs = prepare_trust_attrs (cert, CKT_G_CERTIFICATE_TRUST_ANCHOR);
+ attrs = prepare_trust_attrs (certificate, CKT_G_CERTIFICATE_TRUST_ANCHOR);
g_return_val_if_fail (attrs, NULL);
gck_attributes_add_string (attrs, CKA_G_PURPOSE, purpose);
@@ -543,7 +760,7 @@ prepare_is_certificate_anchor (GcrCertificate *cert, const gchar *purpose)
}
static gboolean
-perform_is_certificate_anchor (GckEnumerator *en, GCancellable *cancel, GError **error)
+perform_is_certificate_anchor (GckEnumerator *en, GCancellable *cancellable, GError **error)
{
GcrTrustOperation *op;
GckObject *object;
@@ -551,7 +768,7 @@ perform_is_certificate_anchor (GckEnumerator *en, GCancellable *cancel, GError *
op = trust_operation_get (en);
g_assert (op != NULL);
- object = gck_enumerator_next (en, cancel, error);
+ object = gck_enumerator_next (en, cancellable, error);
if (object != NULL) {
op->found = TRUE;
g_object_unref (object);
@@ -562,17 +779,39 @@ perform_is_certificate_anchor (GckEnumerator *en, GCancellable *cancel, GError *
return op->found;
}
+/**
+ * gcr_trust_is_certificate_anchor:
+ * @certificate: a #GcrCertificate to check
+ * @purpose: the purpose string
+ * @cancellable: a #GCancellable
+ * @error: a #GError, or NULL
+ *
+ * Check if the @certificate is a trust anchor for the given @purpose. A trust
+ * anchor is used to verify the signatures on other certificates when verifying
+ * a certificate chain. Also known as a trusted certificate authority.
+ *
+ * This call may block, see gcr_trust_is_certificate_anchor_async() for the
+ * non-blocking version.
+ *
+ * In the case of an error, %FALSE is also returned. Check @error to detect
+ * if an error occurred.
+ *
+ * Returns: %TRUE if the certificate is a trust anchor
+ */
gboolean
-gcr_trust_is_certificate_anchor (GcrCertificate *cert, const gchar *purpose,
- GCancellable *cancel, GError **error)
+gcr_trust_is_certificate_anchor (GcrCertificate *certificate, const gchar *purpose,
+ GCancellable *cancellable, GError **error)
{
GckEnumerator *en;
gboolean ret;
- en = prepare_is_certificate_anchor (cert, purpose);
+ g_return_val_if_fail (GCR_IS_CERTIFICATE (certificate), FALSE);
+ g_return_val_if_fail (purpose, FALSE);
+
+ en = prepare_is_certificate_anchor (certificate, purpose);
g_return_val_if_fail (en, FALSE);
- ret = perform_is_certificate_anchor (en, cancel, error);
+ ret = perform_is_certificate_anchor (en, cancellable, error);
g_object_unref (en);
@@ -580,50 +819,82 @@ gcr_trust_is_certificate_anchor (GcrCertificate *cert, const gchar *purpose,
}
static void
-thread_is_certificate_anchor (GSimpleAsyncResult *res, GObject *object, GCancellable *cancel)
+thread_is_certificate_anchor (GSimpleAsyncResult *result, GObject *object, GCancellable *cancel)
{
GError *error = NULL;
perform_is_certificate_anchor (GCK_ENUMERATOR (object), cancel, &error);
if (error != NULL) {
- g_simple_async_result_set_from_error (res, error);
+ g_simple_async_result_set_from_error (result, error);
g_clear_error (&error);
}
}
+/**
+ * gcr_trust_is_certificate_anchor_async:
+ * @certificate: a #GcrCertificate to check
+ * @purpose: the purpose string
+ * @cancellable: a #GCancellable
+ * @callback: a #GAsyncReadyCallback to call when the operation completes
+ * @user_data: the data to pass to callback function
+ *
+ * Check if the @certificate is a trust anchor for the given @purpose. A trust
+ * anchor is used to verify the signatures on other certificates when verifying
+ * a certificate chain. Also known as a trusted certificate authority.
+ *
+ * When the operation is finished, callback will be called. You can then call
+ * gcr_trust_is_certificate_anchor_finish() to get the result of the operation.
+ */
void
-gcr_trust_is_certificate_anchor_async (GcrCertificate *cert, const gchar *purpose,
- GCancellable *cancel, GAsyncReadyCallback callback,
+gcr_trust_is_certificate_anchor_async (GcrCertificate *certificate, const gchar *purpose,
+ GCancellable *cancellable, GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *async;
GckEnumerator *en;
- en = prepare_is_certificate_anchor (cert, purpose);
+ g_return_if_fail (GCR_IS_CERTIFICATE (certificate));
+ g_return_if_fail (purpose);
+
+ en = prepare_is_certificate_anchor (certificate, purpose);
g_return_if_fail (en);
async = g_simple_async_result_new (G_OBJECT (en), callback, user_data,
gcr_trust_is_certificate_anchor_async);
g_simple_async_result_run_in_thread (async, thread_is_certificate_anchor,
- G_PRIORITY_DEFAULT, cancel);
+ G_PRIORITY_DEFAULT, cancellable);
g_object_unref (async);
g_object_unref (en);
}
+/**
+ * gcr_trust_is_certificate_anchor_finish:
+ * @result: the #GAsyncResult passed to the callback
+ * @error: a #GError, or NULL
+ *
+ * Finishes an asynchronous operation started by
+ * gcr_trust_is_certificate_anchor_async().
+ *
+ * In the case of an error, %FALSE is also returned. Check @error to detect
+ * if an error occurred.
+ *
+ * Returns: %TRUE if the certificate is a trust anchor
+ */
gboolean
-gcr_trust_is_certificate_anchor_finish (GAsyncResult *res, GError **error)
+gcr_trust_is_certificate_anchor_finish (GAsyncResult *result, GError **error)
{
GcrTrustOperation *op;
GObject *object;
- object = g_async_result_get_source_object (res);
- g_return_val_if_fail (g_simple_async_result_is_valid (res, object,
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+ object = g_async_result_get_source_object (result);
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, object,
gcr_trust_is_certificate_anchor_async), FALSE);
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
return FALSE;
op = trust_operation_get (GCK_ENUMERATOR (object));
diff --git a/gcr/gcr-trust.h b/gcr/gcr-trust.h
index c49ca3b..53ff770 100644
--- a/gcr/gcr-trust.h
+++ b/gcr/gcr-trust.h
@@ -35,66 +35,66 @@ G_BEGIN_DECLS
#define GCR_PURPOSE_CODE_SIGNING "1.3.6.1.5.5.7.3.3"
#define GCR_PURPOSE_EMAIL "1.3.6.1.5.5.7.3.4"
-gboolean gcr_trust_is_certificate_exception (GcrCertificate *cert,
+gboolean gcr_trust_is_certificate_exception (GcrCertificate *certificate,
const gchar *purpose,
const gchar *peer,
- GCancellable *cancel,
+ GCancellable *cancellable,
GError **error);
-void gcr_trust_is_certificate_exception_async (GcrCertificate *cert,
+void gcr_trust_is_certificate_exception_async (GcrCertificate *certificate,
const gchar *purpose,
const gchar *peer,
- GCancellable *cancel,
+ GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
-gboolean gcr_trust_is_certificate_exception_finish (GAsyncResult *res,
+gboolean gcr_trust_is_certificate_exception_finish (GAsyncResult *result,
GError **error);
-gboolean gcr_trust_add_certificate_exception (GcrCertificate *cert,
+gboolean gcr_trust_add_certificate_exception (GcrCertificate *certificate,
const gchar *purpose,
const gchar *peer,
- GCancellable *cancel,
+ GCancellable *cancellable,
GError **error);
-void gcr_trust_add_certificate_exception_async (GcrCertificate *cert,
+void gcr_trust_add_certificate_exception_async (GcrCertificate *certificate,
const gchar *purpose,
const gchar *peer,
- GCancellable *cancel,
+ GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
-gboolean gcr_trust_add_certificate_exception_finish (GAsyncResult *res,
+gboolean gcr_trust_add_certificate_exception_finish (GAsyncResult *result,
GError **error);
-gboolean gcr_trust_remove_certificate_exception (GcrCertificate *cert,
+gboolean gcr_trust_remove_certificate_exception (GcrCertificate *certificate,
const gchar *purpose,
const gchar *peer,
- GCancellable *cancel,
+ GCancellable *cancellable,
GError **error);
-void gcr_trust_remove_certificate_exception_async (GcrCertificate *cert,
+void gcr_trust_remove_certificate_exception_async (GcrCertificate *certificate,
const gchar *purpose,
const gchar *peer,
- GCancellable *cancel,
+ GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
-gboolean gcr_trust_remove_certificate_exception_finish (GAsyncResult *res,
+gboolean gcr_trust_remove_certificate_exception_finish (GAsyncResult *result,
GError **error);
-gboolean gcr_trust_is_certificate_anchor (GcrCertificate *cert,
+gboolean gcr_trust_is_certificate_anchor (GcrCertificate *certificate,
const gchar *purpose,
- GCancellable *cancel,
+ GCancellable *cancellable,
GError **error);
-void gcr_trust_is_certificate_anchor_async (GcrCertificate *cert,
+void gcr_trust_is_certificate_anchor_async (GcrCertificate *certificate,
const gchar *purpose,
- GCancellable *cancel,
+ GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
-gboolean gcr_trust_is_certificate_anchor_finish (GAsyncResult *res,
+gboolean gcr_trust_is_certificate_anchor_finish (GAsyncResult *result,
GError **error);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]