[gnome-keyring/trust-store] [xdg-store] Complete work on adding and removing assertions.
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-keyring/trust-store] [xdg-store] Complete work on adding and removing assertions.
- Date: Thu, 25 Nov 2010 03:25:00 +0000 (UTC)
commit 004c9b1d97a6f4e1257f39811af6a406c9fcaaba
Author: Stef Walter <stefw collabora co uk>
Date: Wed Nov 24 23:02:28 2010 +0000
[xdg-store] Complete work on adding and removing assertions.
* Support for adding and removing assertions.
* Various other small fixes.
pkcs11/xdg-store/gkm-xdg-assertion.c | 52 ++++++--
pkcs11/xdg-store/gkm-xdg-assertion.h | 6 +-
pkcs11/xdg-store/gkm-xdg-module.c | 88 ++++++++++--
pkcs11/xdg-store/gkm-xdg-trust.c | 216 ++++++++++++++++++++++++++----
pkcs11/xdg-store/gkm-xdg-trust.h | 14 ++-
pkcs11/xdg-store/tests/test-xdg-module.c | 67 +++++++++-
6 files changed, 386 insertions(+), 57 deletions(-)
---
diff --git a/pkcs11/xdg-store/gkm-xdg-assertion.c b/pkcs11/xdg-store/gkm-xdg-assertion.c
index db9f3b4..55f5229 100644
--- a/pkcs11/xdg-store/gkm-xdg-assertion.c
+++ b/pkcs11/xdg-store/gkm-xdg-assertion.c
@@ -24,6 +24,7 @@
#include "gkm-xdg-assertion.h"
#include "gkm-xdg-trust.h"
+#include "gkm/gkm-assertion.h"
#include "gkm/gkm-attributes.h"
#include "gkm/gkm-object.h"
#include "gkm/gkm-session.h"
@@ -36,7 +37,7 @@
#include <glib/gi18n.h>
-G_DEFINE_TYPE (GkmXdgAssertion, gkm_xdg_assertion, GKM_TYPE_OBJECT);
+G_DEFINE_TYPE (GkmXdgAssertion, gkm_xdg_assertion, GKM_TYPE_ASSERTION);
/* -----------------------------------------------------------------------------
* QUARKS
@@ -46,7 +47,7 @@ G_DEFINE_TYPE (GkmXdgAssertion, gkm_xdg_assertion, GKM_TYPE_OBJECT);
* INTERNAL
*/
-static GkmTrust*
+static GkmXdgTrust*
lookup_or_create_trust_object (GkmSession *session, GkmManager *manager,
GkmTransaction *transaction, CK_ASSERTION_TYPE type,
CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs, gboolean *created)
@@ -56,7 +57,7 @@ lookup_or_create_trust_object (GkmSession *session, GkmManager *manager,
CK_OBJECT_CLASS klass;
CK_ULONG n_lookups;
GList *objects;
- GkmTrust *trust;
+ GkmXdgTrust *trust;
GkmModule *module;
klass = CKO_NETSCAPE_TRUST;
@@ -102,8 +103,8 @@ lookup_or_create_trust_object (GkmSession *session, GkmManager *manager,
/* Found a matching trust object for this assertion */
if (objects) {
- g_return_val_if_fail (GKM_IS_TRUST (objects->data), NULL);
- trust = GKM_TRUST (objects->data);
+ g_return_val_if_fail (GKM_XDG_IS_TRUST (objects->data), NULL);
+ trust = GKM_XDG_TRUST (objects->data);
g_list_free (objects);
/* Create a trust object for this assertion */
@@ -130,11 +131,13 @@ factory_create_assertion (GkmSession *session, GkmTransaction *transaction,
CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
{
GkmAssertion *assertion;
+ GkmAssertion *previous;
CK_ASSERTION_TYPE type;
GkmManager *manager;
gboolean created = FALSE;
- GkmTrust *trust;
+ GkmXdgTrust *trust;
gchar *purpose;
+ gchar *peer;
g_return_val_if_fail (attrs || !n_attrs, NULL);
@@ -148,6 +151,9 @@ factory_create_assertion (GkmSession *session, GkmTransaction *transaction,
return NULL;
}
+ if (!gkm_attributes_find_string (attrs, n_attrs, CKA_G_PEER, &peer))
+ peer = NULL;
+
/* Try to find or create an appropriate trust object for this assertion */
manager = gkm_manager_for_template (attrs, n_attrs, session);
trust = lookup_or_create_trust_object (session, manager, transaction,
@@ -157,17 +163,39 @@ factory_create_assertion (GkmSession *session, GkmTransaction *transaction,
if (trust == NULL) {
g_return_val_if_fail (gkm_transaction_get_failed (transaction), NULL);
g_free (purpose);
+ g_free (peer);
return NULL;
}
- assertion = g_object_new (GKM_XDG_TYPE_ASSERTION, "trust", trust,
- "type", type, "purpose", purpose, NULL);
+ assertion = g_object_new (GKM_XDG_TYPE_ASSERTION,
+ "module", gkm_object_get_module (GKM_OBJECT (trust)),
+ "manager", gkm_object_get_manager (GKM_OBJECT (manager)),
+ "trust", trust,
+ "type", type,
+ "purpose", purpose,
+ "peer", peer,
+ NULL);
- gkm_attributes_consume (attrs, n_attrs, CKA_G_ASSERTION_TYPE, CKA_G_PURPOSE, G_MAXULONG);
- gkm_session_complete_object_creation (session, transaction, GKM_OBJECT (assertion),
- TRUE, attrs, n_attrs);
+ /* Add the assertion to the trust object */
+ if (!gkm_transaction_get_failed (transaction)) {
+ previous = gkm_xdg_trust_add_assertion (trust, GKM_ASSERTION (assertion), transaction);
+ if (previous == NULL) {
+ gkm_transaction_fail (transaction, CKR_GENERAL_ERROR);
+
+ /* If trust refused to add this object, return whatever we did add */
+ } else if (previous != assertion) {
+ g_object_unref (assertion);
+ assertion = g_object_ref (previous);
+ }
+ }
+
+ if (!gkm_transaction_get_failed (transaction)) {
+ gkm_attributes_consume (attrs, n_attrs, CKA_G_ASSERTION_TYPE, CKA_G_PURPOSE, G_MAXULONG);
+ gkm_session_complete_object_creation (session, transaction, GKM_OBJECT (assertion),
+ TRUE, attrs, n_attrs);
+ }
- return GKM_OBJECT (trust);
+ return GKM_OBJECT (assertion);
}
/* -----------------------------------------------------------------------------
diff --git a/pkcs11/xdg-store/gkm-xdg-assertion.h b/pkcs11/xdg-store/gkm-xdg-assertion.h
index 75bc073..7b70561 100644
--- a/pkcs11/xdg-store/gkm-xdg-assertion.h
+++ b/pkcs11/xdg-store/gkm-xdg-assertion.h
@@ -25,7 +25,7 @@
#include <glib-object.h>
-#include "gkm/gkm-object.h"
+#include "gkm/gkm-assertion.h"
#define GKM_XDG_FACTORY_ASSERTION (gkm_xdg_assertion_get_factory ())
#define GKM_XDG_TYPE_ASSERTION (gkm_xdg_assertion_get_type ())
@@ -40,12 +40,12 @@ typedef struct _GkmXdgAssertionClass GkmXdgAssertionClass;
typedef struct _GkmXdgAssertionPrivate GkmXdgAssertionPrivate;
struct _GkmXdgAssertion {
- GkmObject parent;
+ GkmAssertion parent;
GkmXdgAssertionPrivate *pv;
};
struct _GkmXdgAssertionClass {
- GkmObjectClass parent_class;
+ GkmAssertionClass parent_class;
};
GType gkm_xdg_assertion_get_type (void);
diff --git a/pkcs11/xdg-store/gkm-xdg-module.c b/pkcs11/xdg-store/gkm-xdg-module.c
index f6d20f4..bae8abd 100644
--- a/pkcs11/xdg-store/gkm-xdg-module.c
+++ b/pkcs11/xdg-store/gkm-xdg-module.c
@@ -86,6 +86,12 @@ G_DEFINE_TYPE (GkmXdgModule, gkm_xdg_module, GKM_TYPE_MODULE);
GkmModule* _gkm_xdg_store_get_module_for_testing (void);
+/* Forward declarations */
+static void remove_object_from_module (GkmXdgModule *self, GkmObject *object,
+ const gchar *filename, GkmTransaction *transaction);
+static void add_object_to_module (GkmXdgModule *self, GkmObject *object,
+ const gchar *filename, GkmTransaction *transaction);
+
/* -----------------------------------------------------------------------------
* ACTUAL PKCS#11 Module Implementation
*/
@@ -122,8 +128,27 @@ lookup_filename_for_object (GkmObject *object)
return g_object_get_data (G_OBJECT (object), "xdg-module-filename");
}
+static gboolean
+complete_add_object (GkmTransaction *transaction, GObject *module, gpointer user_data)
+{
+ GkmXdgModule *self = GKM_XDG_MODULE (module);
+ GkmObject *object = GKM_OBJECT (user_data);
+ const gchar *filename;
+
+ /* If the transaction failed, revert it */
+ if (gkm_transaction_get_failed (transaction)) {
+ filename = g_object_get_data (G_OBJECT (object), "xdg-module-filename");
+ g_return_val_if_fail (filename, FALSE);
+ remove_object_from_module (self, object, filename, NULL);
+ }
+
+ g_object_unref (object);
+ return TRUE;
+}
+
static void
-add_object_to_module (GkmXdgModule *self, GkmObject *object, const gchar *filename)
+add_object_to_module (GkmXdgModule *self, GkmObject *object,
+ const gchar *filename, GkmTransaction *transaction)
{
g_assert (!g_hash_table_lookup (self->objects_by_path, filename));
g_hash_table_insert (self->objects_by_path, g_strdup (filename), g_object_ref (object));
@@ -133,13 +158,38 @@ add_object_to_module (GkmXdgModule *self, GkmObject *object, const gchar *filena
g_strdup (filename), g_free);
gkm_object_expose (object, TRUE);
+
+ if (transaction != NULL)
+ gkm_transaction_add (transaction, self, complete_add_object, g_object_ref (object));
+}
+
+static gboolean
+complete_remove_object (GkmTransaction *transaction, GObject *module, gpointer user_data)
+{
+ GkmXdgModule *self = GKM_XDG_MODULE (module);
+ GkmObject *object = GKM_OBJECT (user_data);
+ const gchar *filename;
+
+ /* If the transaction failed, revert it */
+ if (gkm_transaction_get_failed (transaction)) {
+ filename = g_object_get_data (G_OBJECT (object), "xdg-module-filename");
+ g_return_val_if_fail (filename, FALSE);
+ add_object_to_module (self, object, filename, NULL);
+ }
+
+ g_object_unref (object);
+ return TRUE;
}
static void
-remove_object_from_module (GkmXdgModule *self, GkmObject *object, const gchar *filename)
+remove_object_from_module (GkmXdgModule *self, GkmObject *object,
+ const gchar *filename, GkmTransaction *transaction)
{
gkm_object_expose (object, FALSE);
+ if (transaction != NULL)
+ gkm_transaction_add (transaction, self, complete_remove_object, g_object_ref (object));
+
g_assert (g_hash_table_lookup (self->objects_by_path, filename) == object);
g_hash_table_remove (self->objects_by_path, filename);
}
@@ -195,14 +245,14 @@ file_load (GkmFileTracker *tracker, const gchar *path, GkmXdgModule *self)
/* And load the data into it */
} else if (gkm_serializable_load (GKM_SERIALIZABLE (object), NULL, data, n_data)) {
if (added)
- add_object_to_module (self, object, path);
+ add_object_to_module (self, object, path, NULL);
gkm_object_expose (object, TRUE);
} else {
g_message ("failed to load file in user store: %s", path);
if (!added) {
gkm_object_expose (object, FALSE);
- remove_object_from_module (self, object, path);
+ remove_object_from_module (self, object, path, NULL);
}
}
@@ -219,7 +269,7 @@ file_remove (GkmFileTracker *tracker, const gchar *path, GkmXdgModule *self)
object = g_hash_table_lookup (self->objects_by_path, path);
if (object != NULL)
- remove_object_from_module (self, object, path);
+ remove_object_from_module (self, object, path, NULL);
}
static gchar*
@@ -353,7 +403,7 @@ gkm_xdg_module_real_add_token_object (GkmModule *module, GkmTransaction *transac
actual = gkm_transaction_unique_file (transaction, self->directory, basename);
if (!gkm_transaction_get_failed (transaction)) {
filename = g_build_filename (self->directory, actual, NULL);
- add_object_to_module (self, object, filename);
+ add_object_to_module (self, object, filename, transaction);
g_free (filename);
}
@@ -404,16 +454,28 @@ gkm_xdg_module_real_remove_token_object (GkmModule *module, GkmTransaction *tran
{
GkmXdgModule *self = GKM_XDG_MODULE (module);
const gchar *filename;
+ GkmXdgTrust *trust;
- /* XXXX; need to implement for assertions */
- g_assert_not_reached ();
+ /* Always serialize the trust object for each assertion */
+ if (GKM_XDG_IS_ASSERTION (object)) {
+ trust = GKM_XDG_TRUST (gkm_assertion_get_trust_object (GKM_ASSERTION (object)));
+ gkm_xdg_trust_remove_assertion (trust, GKM_ASSERTION (object), transaction);
+
+ /* Remove the trust object if it has no assertions */
+ if (!gkm_xdg_trust_have_assertion (trust))
+ object = GKM_OBJECT (trust);
+ else
+ object = NULL;
+ }
- filename = lookup_filename_for_object (object);
- g_return_if_fail (filename != NULL);
- g_return_if_fail (g_hash_table_lookup (self->objects_by_path, filename) == object);
+ if (object && !gkm_transaction_get_failed (transaction)) {
+ filename = lookup_filename_for_object (object);
+ g_return_if_fail (filename != NULL);
+ g_return_if_fail (g_hash_table_lookup (self->objects_by_path, filename) == object);
- gkm_transaction_remove_file (transaction, filename);
- g_hash_table_remove (self->objects_by_path, filename);
+ gkm_transaction_remove_file (transaction, filename);
+ remove_object_from_module (self, object, filename, transaction);
+ }
}
static GObject*
diff --git a/pkcs11/xdg-store/gkm-xdg-trust.c b/pkcs11/xdg-store/gkm-xdg-trust.c
index 10a947a..20a4e30 100644
--- a/pkcs11/xdg-store/gkm-xdg-trust.c
+++ b/pkcs11/xdg-store/gkm-xdg-trust.c
@@ -71,6 +71,15 @@ static void gkm_xdg_trust_serializable (GkmSerializableIface *iface);
G_DEFINE_TYPE_EXTENDED (GkmXdgTrust, gkm_xdg_trust, GKM_TYPE_TRUST, 0,
G_IMPLEMENT_INTERFACE (GKM_TYPE_SERIALIZABLE, gkm_xdg_trust_serializable));
+static GQuark QDATA_ASSERTION_KEY = 0;
+
+/* Forward declarations */
+static void add_assertion_to_trust (GkmXdgTrust *self, GkmAssertion *assertion,
+ GkmTransaction *transaction);
+
+static void remove_assertion_from_trust (GkmXdgTrust *self, GkmAssertion *assertion,
+ GkmTransaction *transaction);
+
/* -----------------------------------------------------------------------------
* QUARKS
*/
@@ -273,17 +282,20 @@ parse_netscape_trust (NetscapeFlags *netscape, GQuark level, const gchar *purpos
}
static void
-dispose_each_assertion (gpointer key, gpointer value, gpointer user_data)
+check_and_unref_assertion (gpointer data)
{
- g_assert (GKM_IS_ASSERTION (value));
- g_object_run_dispose (G_OBJECT (value));
+ g_assert (GKM_IS_ASSERTION (data));
+ g_assert (g_object_get_qdata (data, QDATA_ASSERTION_KEY) != NULL);
+ g_object_run_dispose (data);
+ g_object_unref (data);
}
static GHashTable*
create_assertions (void)
{
return g_hash_table_new_full (egg_byte_array_hash, egg_byte_array_equal,
- (GDestroyNotify)g_byte_array_unref, gkm_util_dispose_unref);
+ (GDestroyNotify)g_byte_array_unref,
+ check_and_unref_assertion);
}
static GkmAssertion*
@@ -328,6 +340,82 @@ create_assertion (GkmXdgTrust *self, GNode *asn, NetscapeFlags *netscape)
return assertion;
}
+static void
+stash_assertion_key (GkmAssertion *assertion, GByteArray *key)
+{
+ g_assert (g_object_get_qdata (G_OBJECT (assertion), QDATA_ASSERTION_KEY) == NULL);
+ g_object_set_qdata_full (G_OBJECT (assertion), QDATA_ASSERTION_KEY,
+ g_byte_array_ref (key), (GDestroyNotify)g_byte_array_unref);
+}
+
+static GByteArray*
+lookup_assertion_key (GkmAssertion *assertion)
+{
+ return g_object_get_qdata (G_OBJECT (assertion), QDATA_ASSERTION_KEY);
+}
+
+static gboolean
+complete_add_assertion (GkmTransaction *transaction, GObject *object, gpointer user_data)
+{
+ GkmAssertion *assertion = GKM_ASSERTION (user_data);
+ GkmXdgTrust *self = GKM_XDG_TRUST (object);
+
+ if (gkm_transaction_get_failed (transaction))
+ remove_assertion_from_trust (self, assertion, NULL);
+ else
+ g_object_run_dispose (G_OBJECT (object));
+
+ g_object_unref (assertion);
+ return TRUE;
+}
+
+static void
+add_assertion_to_trust (GkmXdgTrust *self, GkmAssertion *assertion,
+ GkmTransaction *transaction)
+{
+ GByteArray *key;
+
+ key = lookup_assertion_key (assertion);
+ g_assert (key);
+
+ g_hash_table_insert (self->pv->assertions, g_byte_array_ref (key), assertion);
+ gkm_object_expose (GKM_OBJECT (assertion), gkm_object_is_exposed (GKM_OBJECT (self)));
+
+ if (transaction != NULL)
+ gkm_transaction_add (transaction, self, complete_add_assertion, g_object_ref (assertion));
+}
+
+static gboolean
+complete_remove_assertion (GkmTransaction *transaction, GObject *object, gpointer user_data)
+{
+ GkmXdgTrust *self = GKM_XDG_TRUST (object);
+ GkmAssertion *assertion = GKM_ASSERTION (user_data);
+
+ if (gkm_transaction_get_failed (transaction))
+ add_assertion_to_trust (self, assertion, NULL);
+
+ g_object_unref (assertion);
+ return TRUE;
+}
+
+static void
+remove_assertion_from_trust (GkmXdgTrust *self, GkmAssertion *assertion,
+ GkmTransaction *transaction)
+{
+ GByteArray *key;
+
+ key = lookup_assertion_key (assertion);
+ g_assert (key);
+
+ if (transaction != NULL)
+ gkm_transaction_add (transaction, self, complete_remove_assertion, g_object_ref (assertion));
+
+ gkm_object_expose (GKM_OBJECT (assertion), FALSE);
+
+ if (!g_hash_table_remove (self->pv->assertions, key))
+ g_return_if_reached ();
+}
+
static gboolean
load_assertions (GkmXdgTrust *self, GNode *asn)
{
@@ -369,6 +457,7 @@ load_assertions (GkmXdgTrust *self, GNode *asn)
/* Create a new assertion */
} else {
assertion = create_assertion (self, node, &netscape);
+ stash_assertion_key (assertion, key);
}
if (assertion)
@@ -377,7 +466,7 @@ load_assertions (GkmXdgTrust *self, GNode *asn)
}
/* Override the stored assertions and netscape trust */
- g_hash_table_foreach (self->pv->assertions, dispose_each_assertion, NULL);
+ g_hash_table_remove_all (self->pv->assertions);
g_hash_table_unref (self->pv->assertions);
self->pv->assertions = assertions;
memcpy (&self->pv->netscape, &netscape, sizeof (netscape));
@@ -386,15 +475,33 @@ load_assertions (GkmXdgTrust *self, GNode *asn)
}
static gboolean
+save_assertion (GNode *asn, GkmAssertion *assertion)
+{
+ const gchar *purpose;
+ const gchar *peer;
+ GQuark level;
+
+ level = assertion_type_to_level_enum (gkm_assertion_get_trust_type (assertion));
+ purpose = gkm_assertion_get_purpose (assertion);
+ peer = gkm_assertion_get_peer (assertion);
+
+ if (!egg_asn1x_set_oid_as_string (egg_asn1x_node (asn, "purpose", NULL), purpose) ||
+ !egg_asn1x_set_enumerated (egg_asn1x_node (asn, "level", NULL), level))
+ g_return_val_if_reached (FALSE);
+
+ if (peer && !egg_asn1x_set_string_as_utf8 (egg_asn1x_node (asn, "peer", NULL),
+ g_strdup (peer), g_free))
+ g_return_val_if_reached (FALSE);
+
+ return TRUE;
+}
+
+static gboolean
save_assertions (GkmXdgTrust *self, GNode *asn)
{
- GkmAssertion *assertion;
GHashTableIter iter;
GNode *pair, *node;
- const gchar *purpose;
- const gchar *peer;
gpointer value;
- GQuark level;
g_assert (GKM_XDG_IS_TRUST (self));
g_assert (asn);
@@ -404,21 +511,9 @@ save_assertions (GkmXdgTrust *self, GNode *asn)
g_hash_table_iter_init (&iter, self->pv->assertions);
while (g_hash_table_iter_next (&iter, NULL, &value)) {
- assertion = GKM_ASSERTION (value);
- level = assertion_type_to_level_enum (gkm_assertion_get_trust_type (assertion));
- purpose = gkm_assertion_get_purpose (assertion);
- peer = gkm_assertion_get_peer (assertion);
-
pair = egg_asn1x_append (node);
g_return_val_if_fail (pair, FALSE);
-
- egg_asn1x_set_oid_as_string (egg_asn1x_node (pair, "purpose", NULL), purpose);
- egg_asn1x_set_enumerated (egg_asn1x_node (pair, "level", NULL), level);
-
- if (peer) {
- egg_asn1x_set_string_as_utf8 (egg_asn1x_node (pair, "peer", NULL),
- g_strdup (peer), g_free);
- }
+ save_assertion (pair, GKM_ASSERTION (value));
}
return TRUE;
@@ -559,6 +654,7 @@ gkm_xdg_trust_class_init (GkmXdgTrustClass *klass)
gobject_class->finalize = gkm_xdg_trust_finalize;
gkm_class->get_attribute = gkm_xdg_trust_get_attribute;
+ QDATA_ASSERTION_KEY = g_quark_from_static_string ("gkm-xdg-trust-assertion-key");
g_type_class_add_private (klass, sizeof (GkmXdgTrustPrivate));
init_quarks ();
@@ -647,7 +743,7 @@ gkm_xdg_trust_serializable (GkmSerializableIface *iface)
* PUBLIC
*/
-GkmTrust*
+GkmXdgTrust*
gkm_xdg_trust_create_for_assertion (GkmModule *module, GkmManager *manager,
GkmTransaction *transaction,
CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
@@ -699,5 +795,77 @@ gkm_xdg_trust_create_for_assertion (GkmModule *module, GkmManager *manager,
gkm_attributes_consume (attrs, n_attrs, CKA_G_CERTIFICATE_VALUE, CKA_ISSUER,
CKA_SERIAL_NUMBER, G_MAXULONG);
- return GKM_TRUST (trust);
+ return trust;
+}
+
+GkmAssertion*
+gkm_xdg_trust_add_assertion (GkmXdgTrust *self, GkmAssertion *assertion,
+ GkmTransaction *transaction)
+{
+ GkmAssertion *previous;
+ GByteArray *key;
+ GNode *asn;
+ gpointer data;
+ gsize n_data;
+
+ g_return_val_if_fail (GKM_XDG_IS_TRUST (self), NULL);
+ g_return_val_if_fail (GKM_IS_ASSERTION (assertion), NULL);
+ g_return_val_if_fail (!transaction || GKM_IS_TRANSACTION (transaction), NULL);
+
+ /* Build up a key if we don't have one */
+ key = lookup_assertion_key (assertion);
+ if (key == NULL) {
+ asn = egg_asn1x_create (xdg_asn1_tab, "TrustAssertion");
+ g_return_val_if_fail (asn, NULL);
+
+ if (!save_assertion (asn, assertion))
+ g_return_val_if_reached (NULL);
+
+ data = egg_asn1x_encode (asn, NULL, &n_data);
+ g_return_val_if_fail (data, NULL);
+
+ key = g_byte_array_new ();
+ g_byte_array_append (key, data, n_data);
+ stash_assertion_key (assertion, key);
+ g_byte_array_unref (key);
+
+ g_free (data);
+ egg_asn1x_destroy (asn);
+
+ /* Already has a key, check if we alraedy have the assertion */
+ } else {
+ previous = g_hash_table_lookup (self->pv->assertions, key);
+
+ /* Just return previous assertion, don't add */
+ if (previous != NULL)
+ return previous;
+ }
+
+ add_assertion_to_trust (self, assertion, transaction);
+ return assertion;
+}
+
+void
+gkm_xdg_trust_remove_assertion (GkmXdgTrust *self, GkmAssertion *assertion,
+ GkmTransaction *transaction)
+{
+ GByteArray *key;
+
+ g_return_if_fail (GKM_XDG_IS_TRUST (self));
+ g_return_if_fail (GKM_IS_ASSERTION (assertion));
+ g_return_if_fail (!transaction || GKM_IS_TRANSACTION (transaction));
+
+ key = lookup_assertion_key (assertion);
+ g_return_if_fail (key);
+
+ /* Assertion needs to be from this trust object */
+ g_return_if_fail (g_hash_table_lookup (self->pv->assertions, key) != assertion);
+ remove_assertion_from_trust (self, assertion, transaction);
+}
+
+gboolean
+gkm_xdg_trust_have_assertion (GkmXdgTrust *self)
+{
+ g_return_val_if_fail (GKM_XDG_IS_TRUST (self), FALSE);
+ return g_hash_table_size (self->pv->assertions);
}
diff --git a/pkcs11/xdg-store/gkm-xdg-trust.h b/pkcs11/xdg-store/gkm-xdg-trust.h
index 2e22218..88bc872 100644
--- a/pkcs11/xdg-store/gkm-xdg-trust.h
+++ b/pkcs11/xdg-store/gkm-xdg-trust.h
@@ -50,14 +50,20 @@ struct _GkmXdgTrustClass {
GType gkm_xdg_trust_get_type (void);
-GkmTrust* gkm_xdg_trust_create_for_assertion (GkmModule *module,
+GkmXdgTrust* gkm_xdg_trust_create_for_assertion (GkmModule *module,
GkmManager *manager,
GkmTransaction *transaction,
CK_ATTRIBUTE_PTR attrs,
CK_ULONG n_attrs);
-GkmAssertion* gkm_xdg_trust_add_assertion (GkmTrust *trust,
- GkmTrustLevel level,
- const char *purpose);
+GkmAssertion* gkm_xdg_trust_add_assertion (GkmXdgTrust *trust,
+ GkmAssertion *assertion,
+ GkmTransaction *transaction);
+
+void gkm_xdg_trust_remove_assertion (GkmXdgTrust *trust,
+ GkmAssertion *assertion,
+ GkmTransaction *transaction);
+
+gboolean gkm_xdg_trust_have_assertion (GkmXdgTrust *trust);
#endif /* __GKM_XDG_TRUST_H__ */
diff --git a/pkcs11/xdg-store/tests/test-xdg-module.c b/pkcs11/xdg-store/tests/test-xdg-module.c
index cc26566..a3cd72d 100644
--- a/pkcs11/xdg-store/tests/test-xdg-module.c
+++ b/pkcs11/xdg-store/tests/test-xdg-module.c
@@ -134,6 +134,7 @@ test_xdg_module_open_session (gboolean writable)
static GkmModule *module = NULL;
static GkmSession *session = NULL;
+static CK_SLOT_ID slot_id = 0;
TESTING_EXTERNAL(xdg_module)
{
@@ -143,13 +144,19 @@ TESTING_EXTERNAL(xdg_module)
TESTING_SETUP(xdg_module_setup)
{
+ CK_SESSION_INFO info;
CK_RV rv;
module = test_xdg_module_initialize_and_enter ();
session = test_xdg_module_open_session (TRUE);
rv = gkm_module_C_Login (module, gkm_session_get_handle (session), CKU_USER, NULL, 0);
- g_assert (rv == CKR_OK);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+
+ rv = gkm_session_C_GetSessionInfo (session, &info);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+
+ slot_id = info.slotID;
}
TESTING_TEARDOWN(xdg_module_teardown)
@@ -275,3 +282,61 @@ TESTING_TEST (xdg_create_and_add_object)
gkm_assert_cmprv (rv, ==, CKR_OK);
gkm_assert_cmpulong (object, !=, 0);
}
+
+TESTING_TEST (xdg_destroy_object)
+{
+ CK_OBJECT_HANDLE object = 0;
+ CK_CERTIFICATE_TYPE ctype = CKC_X_509;
+ CK_ULONG n_objects = 0;
+ CK_BBOOL tval = CK_TRUE;
+ CK_RV rv;
+
+ CK_ATTRIBUTE attrs[] = {
+ { CKA_CERTIFICATE_TYPE, &ctype, sizeof (ctype) },
+ { CKA_TOKEN, &tval, sizeof (tval) }
+ };
+
+ rv = gkm_session_C_FindObjectsInit (session, attrs, G_N_ELEMENTS (attrs));
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+ rv = gkm_session_C_FindObjects (session, &object, 1, &n_objects);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+ gkm_assert_cmpulong (n_objects, ==, 1);
+ rv = gkm_session_C_FindObjectsFinal (session);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+
+ /* Destroy this object, which should be stored on the disk */
+ rv = gkm_session_C_DestroyObject (session, object);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+
+ /* Make sure it's really gone */
+ rv = gkm_session_C_DestroyObject (session, object);
+ gkm_assert_cmprv (rv, ==, CKR_OBJECT_HANDLE_INVALID);
+}
+
+TESTING_TEST (xdg_get_slot_info)
+{
+ CK_SLOT_INFO info;
+ const gchar *str;
+ CK_RV rv;
+
+ rv = gkm_module_C_GetSlotInfo (module, slot_id, &info);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+
+ str = g_strstr_len ((gchar*)info.slotDescription, sizeof (info.slotDescription),
+ "User Key Storage");
+ g_assert (str != NULL);
+}
+
+TESTING_TEST (xdg_get_token_info)
+{
+ CK_TOKEN_INFO info;
+ const gchar *str;
+ CK_RV rv;
+
+ rv = gkm_module_C_GetTokenInfo (module, slot_id, &info);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+
+ str = g_strstr_len ((gchar*)info.label, sizeof (info.label),
+ "User Key Storage");
+ g_assert (str != NULL);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]