[gnome-keyring/trust-store: 99/105] Fix up gcr library to support trust assertions.



commit c7c0ee614c5a85a2ef2113e40ed07dfa3e6b7030
Author: Stef Walter <stefw collabora co uk>
Date:   Fri Nov 19 19:38:32 2010 +0000

    Fix up gcr library to support trust assertions.

 gcr/gcr-trust.c        |  446 ++++++++++++++++++++++++++----------------------
 gcr/gcr-trust.h        |  127 +++++++-------
 gcr/tests/test-trust.c |   75 ++++-----
 3 files changed, 345 insertions(+), 303 deletions(-)
---
diff --git a/gcr/gcr-trust.c b/gcr/gcr-trust.c
index a627987..860f7ca 100644
--- a/gcr/gcr-trust.c
+++ b/gcr/gcr-trust.c
@@ -28,7 +28,8 @@
 
 #include <gck/gck.h>
 
-#include <pkcs11/pkcs11n.h>
+#include "pkcs11/pkcs11n.h"
+#include "pkcs11/pkcs11i.h"
 
 /* ----------------------------------------------------------------------------------
  * HELPERS
@@ -37,37 +38,9 @@
 typedef struct _GcrTrustOperation {
 	GckEnumerator *en;
 	GckAttributes *attrs;
-	GcrPurpose purpose;
-	GcrTrust trust;
+	gboolean found;
 } GcrTrustOperation;
 
-static CK_ATTRIBUTE_TYPE
-attribute_type_for_purpose (GcrPurpose purpose)
-{
-	switch (purpose) {
-	case GCR_PURPOSE_SERVER_AUTH:
-		return CKA_TRUST_SERVER_AUTH;
-	case GCR_PURPOSE_CLIENT_AUTH:
-		return CKA_TRUST_CLIENT_AUTH;
-	case GCR_PURPOSE_CODE_SIGNING:
-		return CKA_TRUST_CODE_SIGNING;
-	case GCR_PURPOSE_EMAIL:
-		return CKA_TRUST_EMAIL_PROTECTION;
-	case GCR_PURPOSE_TIME_STAMPING:
-		return CKA_TRUST_TIME_STAMPING;
-	case GCR_PURPOSE_IPSEC_ENDPOINT:
-		return CKA_TRUST_IPSEC_END_SYSTEM;
-	case GCR_PURPOSE_IPSEC_TUNNEL:
-		return CKA_TRUST_IPSEC_TUNNEL;
-	case GCR_PURPOSE_IPSEC_USER:
-		return CKA_TRUST_IPSEC_USER;
-	case GCR_PURPOSE_IKE_INTERMEDIATE:
-		g_return_val_if_reached ((CK_ULONG)-1);
-	default:
-		g_return_val_if_reached ((CK_ULONG)-1);
-	};
-}
-
 static void
 trust_operation_free (gpointer data)
 {
@@ -86,8 +59,7 @@ trust_operation_free (gpointer data)
 }
 
 static void
-trust_operation_init (GckEnumerator *en, GckAttributes *attrs,
-                      GcrPurpose purpose, GcrTrust trust)
+trust_operation_init (GckEnumerator *en, GckAttributes *attrs)
 {
 	GcrTrustOperation *op;
 
@@ -96,8 +68,6 @@ trust_operation_init (GckEnumerator *en, GckAttributes *attrs,
 	g_assert (attrs);
 
 	op = g_slice_new0 (GcrTrustOperation);
-	op->purpose = purpose;
-	op->trust = trust;
 	op->attrs = gck_attributes_ref (attrs);
 
 	/* No reference held, GckEnumerator owns */
@@ -115,29 +85,19 @@ trust_operation_get (GckEnumerator *en)
 }
 
 static GckAttributes*
-prepare_trust_attrs (GcrCertificate *cert)
+prepare_trust_attrs (GcrCertificate *cert, CK_ASSERTION_TYPE type)
 {
 	GckAttributes *attrs;
-	gpointer data;
+	gconstpointer data;
 	gsize n_data;
 
 	attrs = gck_attributes_new ();
-	gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_NETSCAPE_TRUST);
-
-	data = gcr_certificate_get_issuer_raw (cert, &n_data);
-	g_return_val_if_fail (data, NULL);
-	gck_attributes_add_data (attrs, CKA_ISSUER, data, n_data);
-	g_free (data);
+	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_serial_number (cert, &n_data);
+	data = gcr_certificate_get_der_data (cert, &n_data);
 	g_return_val_if_fail (data, NULL);
-	gck_attributes_add_data (attrs, CKA_SERIAL_NUMBER, data, n_data);
-	g_free (data);
-
-	data = gcr_certificate_get_fingerprint (cert, G_CHECKSUM_SHA1, &n_data);
-	g_return_val_if_fail (data, NULL);
-	gck_attributes_add_data (attrs, CKA_CERT_SHA1_HASH, data, n_data);
-	g_free (data);
+	gck_attributes_add_data (attrs, CKA_G_CERTIFICATE_VALUE, data, n_data);
 
 	return attrs;
 }
@@ -147,7 +107,7 @@ prepare_trust_attrs (GcrCertificate *cert)
  */
 
 static GckEnumerator*
-prepare_get_certificate_exception (GcrCertificate *cert, GcrPurpose purpose)
+prepare_is_certificate_exception (GcrCertificate *cert, const gchar *purpose, const gchar *remote)
 {
 	GckAttributes *attrs;
 	GckEnumerator *en;
@@ -155,9 +115,12 @@ prepare_get_certificate_exception (GcrCertificate *cert, GcrPurpose purpose)
 
 	modules = _gcr_get_pkcs11_modules ();
 
-	attrs = prepare_trust_attrs (cert);
+	attrs = prepare_trust_attrs (cert, CKT_G_CERTIFICATE_TRUST_EXCEPTION);
 	g_return_val_if_fail (attrs, NULL);
 
+	gck_attributes_add_string (attrs, CKA_G_PURPOSE, purpose);
+	gck_attributes_add_string (attrs, CKA_G_REMOTE, remote);
+
 	/*
 	 * TODO: We need to be able to sort the modules by preference
 	 * on which sources of trust storage we want to read over which
@@ -165,80 +128,59 @@ prepare_get_certificate_exception (GcrCertificate *cert, GcrPurpose purpose)
 	 */
 
 	en = gck_modules_enumerate_objects (modules, attrs, 0);
-	trust_operation_init (en, attrs, purpose, GCR_TRUST_UNKNOWN);
+	trust_operation_init (en, attrs);
 	gck_attributes_unref (attrs);
 
 	return en;
 }
 
-static GcrTrust
-perform_get_certificate_exception (GckEnumerator *en, GCancellable *cancel, GError **error)
+static gboolean
+perform_is_certificate_exception (GckEnumerator *en, GCancellable *cancel, GError **error)
 {
-	CK_ATTRIBUTE_TYPE type;
 	GcrTrustOperation *op;
 	GckObject *object;
-	gpointer data;
-	gsize n_data;
-	gulong value;
 
 	op = trust_operation_get (en);
 
 	g_assert (op != NULL);
-	g_assert (op->trust == GCR_TRUST_UNKNOWN);
+	g_assert (op->found == FALSE);
 
-	type = attribute_type_for_purpose (op->purpose);
-
-	while (op->trust == GCR_TRUST_UNKNOWN) {
-		object = gck_enumerator_next (en, cancel, error);
-		if (!object)
-			break;
-
-		data = gck_object_get_data (object, type, NULL, &n_data, error);
+	object = gck_enumerator_next (en, cancel, error);
+	op->found = (object != NULL);
 
+	if (object)
 		g_object_unref (object);
 
-		if (!data)
-			break;
-
-		if (!gck_value_to_ulong (data, n_data, &value)) {
-			g_message ("an invalid sized value was received for trust attribute");
-			value = CKT_NETSCAPE_TRUST_UNKNOWN;
-		}
-
-		if (value == CKT_NETSCAPE_TRUSTED)
-			op->trust = GCR_TRUST_TRUSTED;
-		else if (value == CKT_NETSCAPE_UNTRUSTED)
-			op->trust = GCR_TRUST_UNTRUSTED;
-
-		g_free (data);
-	}
-
-	return op->trust;
+	return op->found;
 }
 
-GcrTrust
-gcr_trust_get_certificate_exception (GcrCertificate *cert, GcrPurpose purpose,
-                                     GCancellable *cancel, GError **error)
+gboolean
+gcr_trust_is_certificate_exception (GcrCertificate *cert, const gchar *purpose,
+                                    const gchar *remote, GCancellable *cancel, GError **error)
 {
 	GckEnumerator *en;
-	GcrTrust trust;
+	gboolean ret;
 
-	en = prepare_get_certificate_exception (cert, purpose);
-	g_return_val_if_fail (en, GCR_TRUST_UNKNOWN);
+	g_return_val_if_fail (GCR_IS_CERTIFICATE (cert), FALSE);
+	g_return_val_if_fail (purpose, FALSE);
+	g_return_val_if_fail (remote, FALSE);
+
+	en = prepare_is_certificate_exception (cert, purpose, remote);
+	g_return_val_if_fail (en, FALSE);
 
-	trust = perform_get_certificate_exception (en, cancel, error);
+	ret = perform_is_certificate_exception (en, cancel, error);
 
 	g_object_unref (en);
 
-	return trust;
+	return ret;
 }
 
 static void
-thread_get_certificate_exception (GSimpleAsyncResult *res, GObject *object, GCancellable *cancel)
+thread_is_certificate_exception (GSimpleAsyncResult *res, GObject *object, GCancellable *cancel)
 {
 	GError *error = NULL;
 
-	perform_get_certificate_exception (GCK_ENUMERATOR (object), cancel, &error);
+	perform_is_certificate_exception (GCK_ENUMERATOR (object), cancel, &error);
 
 	if (error != NULL) {
 		g_simple_async_result_set_from_error (res, error);
@@ -247,73 +189,61 @@ thread_get_certificate_exception (GSimpleAsyncResult *res, GObject *object, GCan
 }
 
 void
-gcr_trust_get_certificate_exception_async (GcrCertificate *cert, GcrPurpose purpose,
-                                           GCancellable *cancel, GAsyncReadyCallback callback,
-                                           gpointer user_data)
+gcr_trust_is_certificate_exception_async (GcrCertificate *cert, const gchar *purpose,
+                                          const gchar *remote, GCancellable *cancel,
+                                          GAsyncReadyCallback callback, gpointer user_data)
 {
 	GSimpleAsyncResult *async;
 	GckEnumerator *en;
 
-	en = prepare_get_certificate_exception (cert, purpose);
+	en = prepare_is_certificate_exception (cert, purpose, remote);
 	g_return_if_fail (en);
 
 	async = g_simple_async_result_new (G_OBJECT (en), callback, user_data,
-	                                   gcr_trust_get_certificate_exception_async);
+	                                   gcr_trust_is_certificate_exception_async);
 
-	g_simple_async_result_run_in_thread (async, thread_get_certificate_exception,
+	g_simple_async_result_run_in_thread (async, thread_is_certificate_exception,
 	                                     G_PRIORITY_DEFAULT, cancel);
 
 	g_object_unref (async);
 	g_object_unref (en);
 }
 
-GcrTrust
-gcr_trust_get_certificate_exception_finish (GAsyncResult *res, GError **error)
+gboolean
+gcr_trust_is_certificate_exception_finish (GAsyncResult *res, 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,
-	                      gcr_trust_get_certificate_exception_async), GCR_TRUST_UNKNOWN);
+	                      gcr_trust_is_certificate_exception_async), FALSE);
 
 	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
-		return GCR_TRUST_UNKNOWN;
+		return FALSE;
 
 	op = trust_operation_get (GCK_ENUMERATOR (object));
-	return op->trust;
+	return op->found;
 }
 
 /* ----------------------------------------------------------------------------------
- * SET CERTIFICATE EXCEPTION
+ * ADD CERTIFICATE EXCEPTION
  */
 
 static GckEnumerator*
-prepare_set_certificate_exception (GcrCertificate *cert, GcrPurpose purpose, GcrTrust trust)
+prepare_add_certificate_exception (GcrCertificate *cert, const gchar *purpose, const gchar *remote)
 {
 	GckAttributes *attrs;
 	GckEnumerator *en;
 	GList *modules;
-	gpointer data;
-	gsize n_data;
 
 	modules = _gcr_get_pkcs11_modules ();
 
-	attrs = prepare_trust_attrs (cert);
+	attrs = prepare_trust_attrs (cert, CKT_G_CERTIFICATE_TRUST_EXCEPTION);
 	g_return_val_if_fail (attrs, NULL);
 
-	gck_attributes_add_boolean (attrs, CKA_MODIFIABLE, TRUE);
-	gck_attributes_add_boolean (attrs, CKA_TOKEN, TRUE);
-
-	data = gcr_certificate_get_subject_raw (cert, &n_data);
-	g_return_val_if_fail (data, NULL);
-	gck_attributes_add_data (attrs, CKA_SUBJECT, data, n_data);
-	g_free (data);
-
-	data = gcr_certificate_get_fingerprint (cert, G_CHECKSUM_MD5, &n_data);
-	g_return_val_if_fail (data, NULL);
-	gck_attributes_add_data (attrs, CKA_CERT_MD5_HASH, data, n_data);
-	g_free (data);
+	gck_attributes_add_string (attrs, CKA_G_PURPOSE, purpose);
+	gck_attributes_add_string (attrs, CKA_G_REMOTE, remote);
 
 	/*
 	 * TODO: We need to be able to sort the modules by preference
@@ -322,23 +252,21 @@ prepare_set_certificate_exception (GcrCertificate *cert, GcrPurpose purpose, Gcr
 	 */
 
 	en = gck_modules_enumerate_objects (modules, attrs, CKF_RW_SESSION);
-	trust_operation_init (en, attrs, purpose, trust);
+	trust_operation_init (en, attrs);
 	gck_attributes_unref (attrs);
 
 	return en;
 }
 
 static gboolean
-perform_set_certificate_exception (GckEnumerator *en, GCancellable *cancel, GError **error)
+perform_add_certificate_exception (GckEnumerator *en, GCancellable *cancel, GError **error)
 {
-	CK_ATTRIBUTE_TYPE type;
 	GcrTrustOperation *op;
 	GckAttributes *attrs;
 	gboolean ret = FALSE;
 	GError *lerr = NULL;
 	GckObject *object;
 	GckSession *session;
-	gulong value;
 	GckSlot *slot;
 
 	op = trust_operation_get (en);
@@ -348,52 +276,36 @@ perform_set_certificate_exception (GckEnumerator *en, GCancellable *cancel, GErr
 	if (error && !*error)
 		*error = lerr;
 
-	switch (op->trust) {
-	case GCR_TRUST_UNKNOWN:
-		value = CKT_NETSCAPE_TRUST_UNKNOWN;
-		break;
-	case GCR_TRUST_UNTRUSTED:
-		value = CKT_NETSCAPE_UNTRUSTED;
-		break;
-	case GCR_TRUST_TRUSTED:
-		value = CKT_NETSCAPE_TRUSTED;
-		break;
-	}
-
-	type = attribute_type_for_purpose (op->purpose);
-	attrs = gck_attributes_new ();
-
 	object = gck_enumerator_next (en, cancel, error);
+	if (*error)
+		return FALSE;
 
-	/* Only set this one attribute */
+	/* It already exists */
 	if (object) {
+		g_object_unref (object);
+		return TRUE;
+	}
 
-		gck_attributes_add_ulong (attrs, type, value);
-		ret = gck_object_set (object, attrs, cancel, error);
-
-	/* Use all trust attributes to create trust object */
-	} else if (!*error) {
-
-		gck_attributes_add_all (attrs, op->attrs);
-		gck_attributes_add_ulong (attrs, type, value);
-
-		/* Find an appropriate token */
-		slot = _gcr_slot_for_storing_trust (error);
-		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);
-				if (object != NULL) {
-					g_object_unref (object);
-					ret = TRUE;
-				}
-
-				g_object_unref (session);
+	attrs = gck_attributes_new ();
+	gck_attributes_add_all (attrs, op->attrs);
+
+	/* TODO: Add relevant label */
+
+	/* Find an appropriate token */
+	slot = _gcr_slot_for_storing_trust (error);
+	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);
+			if (object != NULL) {
+				g_object_unref (object);
+				ret = TRUE;
 			}
 
-			g_object_unref (slot);
+			g_object_unref (session);
 		}
+
+		g_object_unref (slot);
 	}
 
 	gck_attributes_unref (attrs);
@@ -405,16 +317,16 @@ perform_set_certificate_exception (GckEnumerator *en, GCancellable *cancel, GErr
 }
 
 gboolean
-gcr_trust_set_certificate_exception (GcrCertificate *cert, GcrPurpose purpose, GcrTrust trust,
+gcr_trust_add_certificate_exception (GcrCertificate *cert, const gchar *purpose, const gchar *remote,
                                      GCancellable *cancel, GError **error)
 {
 	GckEnumerator *en;
 	gboolean ret;
 
-	en = prepare_set_certificate_exception (cert, purpose, trust);
+	en = prepare_add_certificate_exception (cert, purpose, remote);
 	g_return_val_if_fail (en, FALSE);
 
-	ret = perform_set_certificate_exception (en, cancel, error);
+	ret = perform_add_certificate_exception (en, cancel, error);
 
 	g_object_unref (en);
 
@@ -422,11 +334,11 @@ gcr_trust_set_certificate_exception (GcrCertificate *cert, GcrPurpose purpose, G
 }
 
 static void
-thread_set_certificate_exception (GSimpleAsyncResult *res, GObject *object, GCancellable *cancel)
+thread_add_certificate_exception (GSimpleAsyncResult *res, GObject *object, GCancellable *cancel)
 {
 	GError *error = NULL;
 
-	perform_set_certificate_exception (GCK_ENUMERATOR (object), cancel, &error);
+	perform_add_certificate_exception (GCK_ENUMERATOR (object), cancel, &error);
 
 	if (error != NULL) {
 		g_simple_async_result_set_from_error (res, error);
@@ -435,20 +347,20 @@ thread_set_certificate_exception (GSimpleAsyncResult *res, GObject *object, GCan
 }
 
 void
-gcr_trust_set_certificate_exception_async (GcrCertificate *cert, GcrPurpose purpose,
-                                           GcrTrust trust, GCancellable *cancel,
+gcr_trust_add_certificate_exception_async (GcrCertificate *cert, const gchar *purpose,
+                                           const gchar *remote, GCancellable *cancel,
                                            GAsyncReadyCallback callback, gpointer user_data)
 {
 	GSimpleAsyncResult *async;
 	GckEnumerator *en;
 
-	en = prepare_set_certificate_exception (cert, purpose, trust);
+	en = prepare_add_certificate_exception (cert, purpose, remote);
 	g_return_if_fail (en);
 
 	async = g_simple_async_result_new (G_OBJECT (en), callback, user_data,
-	                                   gcr_trust_set_certificate_exception_async);
+	                                   gcr_trust_add_certificate_exception_async);
 
-	g_simple_async_result_run_in_thread (async, thread_set_certificate_exception,
+	g_simple_async_result_run_in_thread (async, thread_add_certificate_exception,
 	                                     G_PRIORITY_DEFAULT, cancel);
 
 	g_object_unref (async);
@@ -456,13 +368,141 @@ gcr_trust_set_certificate_exception_async (GcrCertificate *cert, GcrPurpose purp
 }
 
 gboolean
-gcr_trust_set_certificate_exception_finish (GAsyncResult *res, GError **error)
+gcr_trust_add_certificate_exception_finish (GAsyncResult *res, 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,
-	                      gcr_trust_set_certificate_exception_async), FALSE);
+	                      gcr_trust_add_certificate_exception_async), FALSE);
+
+	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
+		return FALSE;
+
+	return TRUE;
+}
+
+/* -----------------------------------------------------------------------
+ * REMOVE CERTIFICATE EXCEPTION
+ */
+
+static GckEnumerator*
+prepare_remove_certificate_exception (GcrCertificate *cert, const gchar *purpose,
+                                      const gchar *remote)
+{
+	GckAttributes *attrs;
+	GckEnumerator *en;
+	GList *modules;
+
+	modules = _gcr_get_pkcs11_modules ();
+
+	attrs = prepare_trust_attrs (cert, CKT_G_CERTIFICATE_TRUST_EXCEPTION);
+	g_return_val_if_fail (attrs, NULL);
+
+	gck_attributes_add_string (attrs, CKA_G_PURPOSE, purpose);
+	gck_attributes_add_string (attrs, CKA_G_REMOTE, remote);
+
+	/*
+	 * TODO: We need to be able to sort the modules by preference
+	 * on which sources of trust storage we want to read over which
+	 * others.
+	 */
+
+	en = gck_modules_enumerate_objects (modules, attrs, CKF_RW_SESSION);
+	trust_operation_init (en, attrs);
+	gck_attributes_unref (attrs);
+
+	return en;
+}
+
+static gboolean
+perform_remove_certificate_exception (GckEnumerator *en, GCancellable *cancel, GError **error)
+{
+	GcrTrustOperation *op;
+	GList *objects, *l;
+	GError *lerr = NULL;
+
+	op = trust_operation_get (en);
+	g_assert (op != NULL);
+
+	/* We need an error below */
+	if (error && !*error)
+		*error = lerr;
+
+	objects = gck_enumerator_next_n (en, -1, cancel, error);
+	if (*error)
+		return FALSE;
+
+	for (l = objects; l; l = g_list_next (l)) {
+		if (!gck_object_destroy (l->data, cancel, error)) {
+			gck_list_unref_free (objects);
+			return FALSE;
+		}
+	}
+
+	gck_list_unref_free (objects);
+	return TRUE;
+}
+
+gboolean
+gcr_trust_remove_certificate_exception (GcrCertificate *cert, const gchar *purpose, const gchar *remote,
+                                        GCancellable *cancel, GError **error)
+{
+	GckEnumerator *en;
+	gboolean ret;
+
+	en = prepare_remove_certificate_exception (cert, purpose, remote);
+	g_return_val_if_fail (en, FALSE);
+
+	ret = perform_remove_certificate_exception (en, cancel, error);
+
+	g_object_unref (en);
+
+	return ret;
+}
+
+static void
+thread_remove_certificate_exception (GSimpleAsyncResult *res, 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_clear_error (&error);
+	}
+}
+
+void
+gcr_trust_remove_certificate_exception_async (GcrCertificate *cert, const gchar *purpose,
+                                              const gchar *remote, GCancellable *cancel,
+                                              GAsyncReadyCallback callback, gpointer user_data)
+{
+	GSimpleAsyncResult *async;
+	GckEnumerator *en;
+
+	en = prepare_remove_certificate_exception (cert, purpose, remote);
+	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_object_unref (async);
+	g_object_unref (en);
+}
+
+gboolean
+gcr_trust_remove_certificate_exception_finish (GAsyncResult *res, 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,
+	                      gcr_trust_remove_certificate_exception_async), FALSE);
 
 	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
 		return FALSE;
@@ -475,7 +515,7 @@ gcr_trust_set_certificate_exception_finish (GAsyncResult *res, GError **error)
  */
 
 static GckEnumerator*
-prepare_is_certificate_root (GcrCertificate *cert, GcrPurpose purpose)
+prepare_is_certificate_anchor (GcrCertificate *cert, const gchar *purpose)
 {
 	GckAttributes *attrs;
 	GckEnumerator *en;
@@ -483,11 +523,10 @@ prepare_is_certificate_root (GcrCertificate *cert, GcrPurpose purpose)
 
 	modules = _gcr_get_pkcs11_modules ();
 
-	attrs = prepare_trust_attrs (cert);
+	attrs = prepare_trust_attrs (cert, CKT_G_CERTIFICATE_TRUST_ANCHOR);
 	g_return_val_if_fail (attrs, NULL);
 
-	gck_attributes_add_ulong (attrs, attribute_type_for_purpose (purpose),
-	                          CKT_NETSCAPE_TRUSTED_DELEGATOR);
+	gck_attributes_add_string (attrs, CKA_G_PURPOSE, purpose);
 
 	/*
 	 * TODO: We need to be able to sort the modules by preference
@@ -495,15 +534,15 @@ prepare_is_certificate_root (GcrCertificate *cert, GcrPurpose purpose)
 	 * others.
 	 */
 
-	en = gck_modules_enumerate_objects (modules, attrs, CKF_RW_SESSION);
-	trust_operation_init (en, attrs, purpose, GCR_TRUST_UNKNOWN);
+	en = gck_modules_enumerate_objects (modules, attrs, 0);
+	trust_operation_init (en, attrs);
 	gck_attributes_unref (attrs);
 
 	return en;
 }
 
 static gboolean
-perform_is_certificate_root (GckEnumerator *en, GCancellable *cancel, GError **error)
+perform_is_certificate_anchor (GckEnumerator *en, GCancellable *cancel, GError **error)
 {
 	GcrTrustOperation *op;
 	GckObject *object;
@@ -513,25 +552,26 @@ perform_is_certificate_root (GckEnumerator *en, GCancellable *cancel, GError **e
 
 	object = gck_enumerator_next (en, cancel, error);
 	if (object != NULL) {
-		op->trust = GCR_TRUST_TRUSTED;
+		op->found = TRUE;
 		g_object_unref (object);
-		return TRUE;
+	} else {
+		op->found = FALSE;
 	}
 
-	return FALSE;
+	return op->found;
 }
 
 gboolean
-gcr_trust_is_certificate_root (GcrCertificate *cert, GcrPurpose purpose,
-                               GCancellable *cancel, GError **error)
+gcr_trust_is_certificate_anchor (GcrCertificate *cert, const gchar *purpose,
+                                 GCancellable *cancel, GError **error)
 {
 	GckEnumerator *en;
 	gboolean ret;
 
-	en = prepare_is_certificate_root (cert, purpose);
+	en = prepare_is_certificate_anchor (cert, purpose);
 	g_return_val_if_fail (en, FALSE);
 
-	ret = perform_is_certificate_root (en, cancel, error);
+	ret = perform_is_certificate_anchor (en, cancel, error);
 
 	g_object_unref (en);
 
@@ -539,11 +579,11 @@ gcr_trust_is_certificate_root (GcrCertificate *cert, GcrPurpose purpose,
 }
 
 static void
-thread_is_certificate_root (GSimpleAsyncResult *res, GObject *object, GCancellable *cancel)
+thread_is_certificate_anchor (GSimpleAsyncResult *res, GObject *object, GCancellable *cancel)
 {
 	GError *error = NULL;
 
-	perform_is_certificate_root (GCK_ENUMERATOR (object), cancel, &error);
+	perform_is_certificate_anchor (GCK_ENUMERATOR (object), cancel, &error);
 
 	if (error != NULL) {
 		g_simple_async_result_set_from_error (res, error);
@@ -552,20 +592,20 @@ thread_is_certificate_root (GSimpleAsyncResult *res, GObject *object, GCancellab
 }
 
 void
-gcr_trust_is_certificate_root_async (GcrCertificate *cert, GcrPurpose purpose,
-                                     GCancellable *cancel, GAsyncReadyCallback callback,
-                                     gpointer user_data)
+gcr_trust_is_certificate_anchor_async (GcrCertificate *cert, const gchar *purpose,
+                                       GCancellable *cancel, GAsyncReadyCallback callback,
+                                       gpointer user_data)
 {
 	GSimpleAsyncResult *async;
 	GckEnumerator *en;
 
-	en = prepare_is_certificate_root (cert, purpose);
+	en = prepare_is_certificate_anchor (cert, purpose);
 	g_return_if_fail (en);
 
 	async = g_simple_async_result_new (G_OBJECT (en), callback, user_data,
-	                                   gcr_trust_is_certificate_root_async);
+	                                   gcr_trust_is_certificate_anchor_async);
 
-	g_simple_async_result_run_in_thread (async, thread_is_certificate_root,
+	g_simple_async_result_run_in_thread (async, thread_is_certificate_anchor,
 	                                     G_PRIORITY_DEFAULT, cancel);
 
 	g_object_unref (async);
@@ -573,18 +613,18 @@ gcr_trust_is_certificate_root_async (GcrCertificate *cert, GcrPurpose purpose,
 }
 
 gboolean
-gcr_trust_is_certificate_root_finish (GAsyncResult *res, GError **error)
+gcr_trust_is_certificate_anchor_finish (GAsyncResult *res, 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,
-	                      gcr_trust_is_certificate_root_async), FALSE);
+	                      gcr_trust_is_certificate_anchor_async), FALSE);
 
 	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
 		return FALSE;
 
 	op = trust_operation_get (GCK_ENUMERATOR (object));
-	return op->trust == GCR_TRUST_TRUSTED;
+	return op->found;
 }
diff --git a/gcr/gcr-trust.h b/gcr/gcr-trust.h
index 89902fa..74238db 100644
--- a/gcr/gcr-trust.h
+++ b/gcr/gcr-trust.h
@@ -26,67 +26,72 @@
 
 G_BEGIN_DECLS
 
-typedef enum _GcrTrust {
-	GCR_TRUST_UNTRUSTED = -1,
-	GCR_TRUST_UNKNOWN = 0,
-	GCR_TRUST_TRUSTED,
-} GcrTrust;
-
-typedef enum _GcrPurpose {
-	GCR_PURPOSE_SERVER_AUTH = 1,
-	GCR_PURPOSE_CLIENT_AUTH,
-	GCR_PURPOSE_CODE_SIGNING,
-	GCR_PURPOSE_EMAIL,
-	GCR_PURPOSE_TIME_STAMPING,
-	GCR_PURPOSE_IPSEC_ENDPOINT,
-	GCR_PURPOSE_IPSEC_TUNNEL,
-	GCR_PURPOSE_IPSEC_USER,
-	GCR_PURPOSE_IKE_INTERMEDIATE,
-} GcrPurpose;
-
-GcrTrust       gcr_trust_get_certificate_exception          (GcrCertificate *cert,
-                                                             GcrPurpose purpose,
-                                                             GCancellable *cancel,
-                                                             GError **error);
-
-void           gcr_trust_get_certificate_exception_async    (GcrCertificate *cert,
-                                                             GcrPurpose purpose,
-                                                             GCancellable *cancel,
-                                                             GAsyncReadyCallback callback,
-                                                             gpointer user_data);
-
-GcrTrust       gcr_trust_get_certificate_exception_finish   (GAsyncResult *res,
-                                                             GError **error);
-
-gboolean       gcr_trust_set_certificate_exception          (GcrCertificate *cert,
-                                                             GcrPurpose purpose,
-                                                             GcrTrust trust,
-                                                             GCancellable *cancel,
-                                                             GError **error);
-
-void           gcr_trust_set_certificate_exception_async    (GcrCertificate *cert,
-                                                             GcrPurpose purpose,
-                                                             GcrTrust trust,
-                                                             GCancellable *cancel,
-                                                             GAsyncReadyCallback callback,
-                                                             gpointer user_data);
-
-gboolean       gcr_trust_set_certificate_exception_finish   (GAsyncResult *res,
-                                                             GError **error);
-
-gboolean       gcr_trust_is_certificate_root                (GcrCertificate *cert,
-                                                             GcrPurpose purpose,
-                                                             GCancellable *cancel,
-                                                             GError **error);
-
-void           gcr_trust_is_certificate_root_async          (GcrCertificate *cert,
-                                                             GcrPurpose purpose,
-                                                             GCancellable *cancel,
-                                                             GAsyncReadyCallback callback,
-                                                             gpointer user_data);
-
-gboolean       gcr_trust_is_certificate_root_finish         (GAsyncResult *res,
-                                                             GError **error);
+#define GCR_PURPOSE_SERVER_AUTH "1.3.6.1.5.5.7.3.1"
+#define GCR_PURPOSE_CLIENT_AUTH "1.3.6.1.5.5.7.3.2"
+#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,
+                                                                const gchar *purpose,
+                                                                const gchar *remote,
+                                                                GCancellable *cancel,
+                                                                GError **error);
+
+void           gcr_trust_is_certificate_exception_async        (GcrCertificate *cert,
+                                                                const gchar *purpose,
+                                                                const gchar *remote,
+                                                                GCancellable *cancel,
+                                                                GAsyncReadyCallback callback,
+                                                                gpointer user_data);
+
+gboolean       gcr_trust_is_certificate_exception_finish       (GAsyncResult *res,
+                                                                GError **error);
+
+gboolean       gcr_trust_add_certificate_exception             (GcrCertificate *cert,
+                                                                const gchar *purpose,
+                                                                const gchar *remote,
+                                                                GCancellable *cancel,
+                                                                GError **error);
+
+void           gcr_trust_add_certificate_exception_async       (GcrCertificate *cert,
+                                                                const gchar *purpose,
+                                                                const gchar *remote,
+                                                                GCancellable *cancel,
+                                                                GAsyncReadyCallback callback,
+                                                                gpointer user_data);
+
+gboolean       gcr_trust_add_certificate_exception_finish      (GAsyncResult *res,
+                                                                GError **error);
+
+gboolean       gcr_trust_remove_certificate_exception          (GcrCertificate *cert,
+                                                                const gchar *purpose,
+                                                                const gchar *remote,
+                                                                GCancellable *cancel,
+                                                                GError **error);
+
+void           gcr_trust_remove_certificate_exception_async    (GcrCertificate *cert,
+                                                                const gchar *purpose,
+                                                                const gchar *remote,
+                                                                GCancellable *cancel,
+                                                                GAsyncReadyCallback callback,
+                                                                gpointer user_data);
+
+gboolean       gcr_trust_remove_certificate_exception_finish   (GAsyncResult *res,
+                                                                GError **error);
+
+gboolean       gcr_trust_is_certificate_anchor                 (GcrCertificate *cert,
+                                                                const gchar *purpose,
+                                                                GCancellable *cancel,
+                                                                GError **error);
+
+void           gcr_trust_is_certificate_anchor_async           (GcrCertificate *cert,
+                                                                const gchar *purpose,
+                                                                GCancellable *cancel,
+                                                                GAsyncReadyCallback callback,
+                                                                gpointer user_data);
+
+gboolean       gcr_trust_is_certificate_anchor_finish          (GAsyncResult *res,
+                                                                GError **error);
 
 G_END_DECLS
 
diff --git a/gcr/tests/test-trust.c b/gcr/tests/test-trust.c
index f97f009..480d40e 100644
--- a/gcr/tests/test-trust.c
+++ b/gcr/tests/test-trust.c
@@ -80,58 +80,55 @@ DEFINE_TEARDOWN (trust_setup)
 	modules = NULL;
 }
 
-DEFINE_TEST (trust_get_exception_none)
+DEFINE_TEST (trust_is_exception_none)
 {
 	GError *error = NULL;
-	GcrTrust trust;
+	gboolean trust;
 
-	trust = gcr_trust_get_certificate_exception (certificate, GCR_PURPOSE_EMAIL, NULL, &error);
-	g_assert_cmpint (trust, ==, GCR_TRUST_UNKNOWN);
+	trust = gcr_trust_is_certificate_exception (certificate, GCR_PURPOSE_EMAIL, "host", NULL, &error);
+	g_assert_cmpint (trust, ==, TRUE);
 	g_assert (error == NULL);
 }
 
-DEFINE_TEST (trust_set_and_get_exception)
+DEFINE_TEST (trust_add_and_is_exception)
 {
 	GError *error = NULL;
-	GcrTrust trust;
+	gboolean trust;
 	gboolean ret;
 
-	trust = gcr_trust_get_certificate_exception (certificate, GCR_PURPOSE_EMAIL, NULL, &error);
-	g_assert_cmpint (trust, ==, GCR_TRUST_UNKNOWN);
+	trust = gcr_trust_is_certificate_exception (certificate, GCR_PURPOSE_EMAIL, "host", NULL, &error);
+	g_assert_cmpint (trust, ==, TRUE);
 	g_assert (error == NULL);
 
-	ret = gcr_trust_set_certificate_exception (certificate, GCR_PURPOSE_EMAIL,
-	                                           GCR_TRUST_TRUSTED, NULL, &error);
+	ret = gcr_trust_add_certificate_exception (certificate, GCR_PURPOSE_EMAIL, "host", NULL, &error);
 	g_assert (ret == TRUE);
 	g_assert (error == NULL);
 
-	trust = gcr_trust_get_certificate_exception (certificate, GCR_PURPOSE_EMAIL, NULL, &error);
-	g_assert_cmpint (trust, ==, GCR_TRUST_TRUSTED);
+	trust = gcr_trust_is_certificate_exception (certificate, GCR_PURPOSE_EMAIL, "host", NULL, &error);
+	g_assert_cmpint (trust, ==, TRUE);
 	g_assert (error == NULL);
 }
 
-DEFINE_TEST (trust_set_and_override_exception)
+DEFINE_TEST (trust_add_and_remov_exception)
 {
 	GError *error = NULL;
-	GcrTrust trust;
+	gboolean trust;
 	gboolean ret;
 
-	ret = gcr_trust_set_certificate_exception (certificate, GCR_PURPOSE_EMAIL,
-	                                           GCR_TRUST_TRUSTED, NULL, &error);
+	ret = gcr_trust_add_certificate_exception (certificate, GCR_PURPOSE_EMAIL, "host", NULL, &error);
 	g_assert (ret == TRUE);
 	g_assert (error == NULL);
 
-	trust = gcr_trust_get_certificate_exception (certificate, GCR_PURPOSE_EMAIL, NULL, &error);
-	g_assert_cmpint (trust, ==, GCR_TRUST_TRUSTED);
+	trust = gcr_trust_is_certificate_exception (certificate, GCR_PURPOSE_EMAIL, "host", NULL, &error);
+	g_assert_cmpint (trust, ==, TRUE);
 	g_assert (error == NULL);
 
-	ret = gcr_trust_set_certificate_exception (certificate, GCR_PURPOSE_EMAIL,
-	                                           GCR_TRUST_UNTRUSTED, NULL, &error);
+	ret = gcr_trust_remove_certificate_exception (certificate, GCR_PURPOSE_EMAIL, "host", NULL, &error);
 	g_assert (ret == TRUE);
 	g_assert (error == NULL);
 
-	trust = gcr_trust_get_certificate_exception (certificate, GCR_PURPOSE_EMAIL, NULL, &error);
-	g_assert_cmpint (trust, ==, GCR_TRUST_UNTRUSTED);
+	trust = gcr_trust_is_certificate_exception (certificate, GCR_PURPOSE_EMAIL, "host", NULL, &error);
+	g_assert_cmpint (trust, ==, FALSE);
 	g_assert (error == NULL);
 }
 
@@ -143,53 +140,53 @@ fetch_async_result (GObject *source, GAsyncResult *result, gpointer user_data)
 	testing_wait_stop ();
 }
 
-DEFINE_TEST (trust_set_and_get_exception_async)
+DEFINE_TEST (trust_add_and_is_exception_async)
 {
 	GAsyncResult *result = NULL;
 	GError *error = NULL;
-	GcrTrust trust;
+	gboolean trust;
 	gboolean ret;
 
-	gcr_trust_get_certificate_exception_async (certificate, GCR_PURPOSE_EMAIL, NULL, fetch_async_result, &result);
+	gcr_trust_is_certificate_exception_async (certificate, GCR_PURPOSE_EMAIL, "host", NULL, fetch_async_result, &result);
 	testing_wait_until (500);
 	g_assert (result);
-	trust = gcr_trust_get_certificate_exception_finish (result, &error);
-	g_assert (trust == GCR_TRUST_UNKNOWN);
+	trust = gcr_trust_is_certificate_exception_finish (result, &error);
+	g_assert (trust == FALSE);
 	g_assert (error == NULL);
 	g_object_unref (result);
 	result = NULL;
 
-	gcr_trust_set_certificate_exception_async (certificate, GCR_PURPOSE_EMAIL, GCR_TRUST_TRUSTED,
+	gcr_trust_add_certificate_exception_async (certificate, GCR_PURPOSE_EMAIL, "host",
 	                                           NULL, fetch_async_result, &result);
 	testing_wait_until (500);
 	g_assert (result);
-	ret = gcr_trust_set_certificate_exception_finish (result, &error);
+	ret = gcr_trust_add_certificate_exception_finish (result, &error);
 	g_assert (ret == TRUE);
 	g_assert (error == NULL);
 	g_object_unref (result);
 	result = NULL;
 
-	gcr_trust_get_certificate_exception_async (certificate, GCR_PURPOSE_EMAIL, NULL, fetch_async_result, &result);
+	gcr_trust_is_certificate_exception_async (certificate, GCR_PURPOSE_EMAIL, "host", NULL, fetch_async_result, &result);
 	testing_wait_until (500);
 	g_assert (result);
-	trust = gcr_trust_get_certificate_exception_finish (result, &error);
-	g_assert (trust == GCR_TRUST_TRUSTED);
+	trust = gcr_trust_is_certificate_exception_finish (result, &error);
+	g_assert (trust == TRUE);
 	g_assert (error == NULL);
 	g_object_unref (result);
 	result = NULL;
 }
 
-DEFINE_TEST (trust_is_certificate_root_not)
+DEFINE_TEST (trust_is_certificate_anchor_not)
 {
 	GError *error = NULL;
 	gboolean ret;
 
-	ret = gcr_trust_is_certificate_root (certificate, GCR_PURPOSE_CLIENT_AUTH, NULL, &error);
+	ret = gcr_trust_is_certificate_anchor (certificate, GCR_PURPOSE_CLIENT_AUTH, NULL, &error);
 	g_assert (ret == FALSE);
 	g_assert (error == NULL);
 }
 
-DEFINE_TEST (trust_is_certificate_root_yes)
+DEFINE_TEST (trust_is_certificate_anchor_yes)
 {
 	GError *error = NULL;
 	GckAttributes *attrs;
@@ -215,22 +212,22 @@ DEFINE_TEST (trust_is_certificate_root_yes)
 	gck_attributes_add_ulong (attrs, CKA_TRUST_CLIENT_AUTH, CKT_NETSCAPE_TRUSTED_DELEGATOR);
 	gck_mock_module_take_object (attrs);
 
-	ret = gcr_trust_is_certificate_root (certificate, GCR_PURPOSE_CLIENT_AUTH, NULL, &error);
+	ret = gcr_trust_is_certificate_anchor (certificate, GCR_PURPOSE_CLIENT_AUTH, NULL, &error);
 	g_assert (ret == TRUE);
 	g_assert (error == NULL);
 }
 
-DEFINE_TEST (trust_is_certificate_root_async)
+DEFINE_TEST (trust_is_certificate_anchor_async)
 {
 	GAsyncResult *result = NULL;
 	GError *error = NULL;
 	gboolean ret;
 
-	gcr_trust_is_certificate_root_async (certificate, GCR_PURPOSE_CLIENT_AUTH, NULL, fetch_async_result, &result);
+	gcr_trust_is_certificate_anchor_async (certificate, GCR_PURPOSE_CLIENT_AUTH, NULL, fetch_async_result, &result);
 	testing_wait_until (500);
 	g_assert (result);
 
-	ret = gcr_trust_is_certificate_root_finish (result, &error);
+	ret = gcr_trust_is_certificate_anchor_finish (result, &error);
 	g_assert (ret == FALSE);
 	g_assert (error == NULL);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]