[gnome-keyring/dbus-api] [gck] Make exposing pkcs11 object part of transaction.
- From: Stefan Walter <stefw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-keyring/dbus-api] [gck] Make exposing pkcs11 object part of transaction.
- Date: Sun, 8 Nov 2009 02:06:03 +0000 (UTC)
commit 3599153c060ec3fa864ef8bf5779b40416976cef
Author: Stef Walter <stef memberwebs com>
Date: Sat Nov 7 22:42:44 2009 +0000
[gck] Make exposing pkcs11 object part of transaction.
When a transaction fails, and an object was exposed (ie: made
available through PKCS#11) we should revert the exposure.
pkcs11/gck/gck-object.c | 35 +++++++++++++++++++++
pkcs11/gck/gck-object.h | 6 ++++
pkcs11/gck/gck-session.c | 4 +-
pkcs11/gck/tests/test-module.c | 29 ++++++++++++++++++
pkcs11/gck/tests/test-module.h | 2 +
pkcs11/gck/tests/unit-test-object.c | 57 +++++++++++++++++++++++++++++++++++
6 files changed, 131 insertions(+), 2 deletions(-)
---
diff --git a/pkcs11/gck/gck-object.c b/pkcs11/gck/gck-object.c
index 5b0dba6..b9bcc1c 100644
--- a/pkcs11/gck/gck-object.c
+++ b/pkcs11/gck/gck-object.c
@@ -140,6 +140,18 @@ complete_destroy (GckTransaction *transaction, GObject *unused, gpointer user_da
return TRUE;
}
+static gboolean
+complete_expose (GckTransaction *transaction, GObject *obj, gpointer user_data)
+{
+ GckObject *self = GCK_OBJECT (obj);
+ gboolean expose = GPOINTER_TO_UINT (user_data);
+
+ if (gck_transaction_get_failed (transaction))
+ gck_object_expose (self, !expose);
+
+ return TRUE;
+}
+
/* -----------------------------------------------------------------------------
* OBJECT
*/
@@ -755,6 +767,13 @@ gck_object_destroy (GckObject *self, GckTransaction *transaction)
g_object_unref (self);
}
+gboolean
+gck_object_is_exposed (GckObject *self)
+{
+ g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
+ return self->pv->exposed;
+}
+
void
gck_object_expose (GckObject *self, gboolean expose)
{
@@ -766,3 +785,19 @@ gck_object_expose (GckObject *self, gboolean expose)
if (self->pv->exposed != expose)
g_signal_emit (self, signals[EXPOSE_OBJECT], 0, expose);
}
+
+void
+gck_object_expose_full (GckObject *self, GckTransaction *transaction, gboolean expose)
+{
+ if (!expose && !self)
+ return;
+
+ g_return_if_fail (GCK_IS_OBJECT (self));
+ g_return_if_fail (!transaction || !gck_transaction_get_failed (transaction));
+
+ if (self->pv->exposed != expose) {
+ if (transaction)
+ gck_transaction_add (transaction, self, complete_expose, GUINT_TO_POINTER (expose));
+ gck_object_expose (self, expose);
+ }
+}
diff --git a/pkcs11/gck/gck-object.h b/pkcs11/gck/gck-object.h
index 53c9b64..29988e1 100644
--- a/pkcs11/gck/gck-object.h
+++ b/pkcs11/gck/gck-object.h
@@ -87,9 +87,15 @@ CK_RV gck_object_unlock (GckObject *self,
void gck_object_destroy (GckObject *self,
GckTransaction *transaction);
+gboolean gck_object_is_exposed (GckObject *self);
+
void gck_object_expose (GckObject *self,
gboolean expose);
+void gck_object_expose_full (GckObject *self,
+ GckTransaction *transaction,
+ gboolean expose);
+
gboolean gck_object_match (GckObject *self,
GckSession *session,
CK_ATTRIBUTE_PTR attr);
diff --git a/pkcs11/gck/gck-session.c b/pkcs11/gck/gck-session.c
index afe3c12..7a37f55 100644
--- a/pkcs11/gck/gck-session.c
+++ b/pkcs11/gck/gck-session.c
@@ -316,7 +316,7 @@ remove_object (GckSession *self, GckTransaction *transaction, GckObject *object)
g_object_ref (object);
- gck_object_expose (object, FALSE);
+ gck_object_expose_full (object, transaction, FALSE);
if (!g_hash_table_remove (self->pv->objects, object))
g_return_if_reached ();
g_object_set (object, "store", NULL, NULL);
@@ -351,7 +351,7 @@ add_object (GckSession *self, GckTransaction *transaction, GckObject *object)
g_hash_table_insert (self->pv->objects, object, g_object_ref (object));
g_object_set_data (G_OBJECT (object), "owned-by-session", self);
g_object_set (object, "store", self->pv->store, NULL);
- gck_object_expose (object, TRUE);
+ gck_object_expose_full (object, transaction, TRUE);
if (transaction)
gck_transaction_add (transaction, self, (GckTransactionFunc)complete_add,
diff --git a/pkcs11/gck/tests/test-module.c b/pkcs11/gck/tests/test-module.c
index e36071d..1cd7f82 100644
--- a/pkcs11/gck/tests/test-module.c
+++ b/pkcs11/gck/tests/test-module.c
@@ -23,11 +23,14 @@
#include "config.h"
#include "test-module.h"
+#include "run-auto-test.h"
/* Include all the module entry points */
#include "gck/gck-module-ep.h"
GCK_DEFINE_MODULE (test_module, GCK_TYPE_MODULE);
+#include "gck/gck-certificate.h"
+
GckModule*
test_module_initialize_and_enter (void)
{
@@ -84,3 +87,29 @@ test_module_open_session (gboolean writable)
return session;
}
+
+GckObject*
+test_module_object_new (GckSession *session)
+{
+ GckObject *object;
+
+ CK_BBOOL token = CK_FALSE;
+ CK_OBJECT_CLASS klass = CKO_CERTIFICATE;
+ CK_CERTIFICATE_TYPE type = CKC_X_509;
+
+ gsize n_data;
+ guchar *data = test_read_testdata ("test-certificate-1.der", &n_data);
+
+ CK_ATTRIBUTE attrs[] = {
+ { CKA_TOKEN, &token, sizeof (token) },
+ { CKA_CLASS, &klass, sizeof (klass) },
+ { CKA_CERTIFICATE_TYPE, &type, sizeof (type) },
+ { CKA_VALUE, data, n_data },
+ };
+
+ if (gck_session_create_object_for_factory (session, GCK_FACTORY_CERTIFICATE->factory,
+ attrs, G_N_ELEMENTS (attrs), &object) == CKR_OK)
+ return object;
+
+ return NULL;
+}
diff --git a/pkcs11/gck/tests/test-module.h b/pkcs11/gck/tests/test-module.h
index 631dd5b..32fece1 100644
--- a/pkcs11/gck/tests/test-module.h
+++ b/pkcs11/gck/tests/test-module.h
@@ -40,4 +40,6 @@ void test_module_leave_and_finalize (void);
GckSession* test_module_open_session (gboolean writable);
+GckObject* test_module_object_new (GckSession *session);
+
#endif /* TESTMODULE_H_ */
diff --git a/pkcs11/gck/tests/unit-test-object.c b/pkcs11/gck/tests/unit-test-object.c
index 3cb323a..54e3f29 100644
--- a/pkcs11/gck/tests/unit-test-object.c
+++ b/pkcs11/gck/tests/unit-test-object.c
@@ -28,6 +28,7 @@
#include "gck/gck-object.h"
#include "gck/gck-session.h"
#include "gck/gck-module.h"
+#include "gck/gck-transaction.h"
#include "pkcs11g.h"
@@ -243,3 +244,59 @@ DEFINE_TEST(object_create_auto_destruct_bad_value)
rv = gck_session_C_CreateObject (session, attrs, G_N_ELEMENTS (attrs), &handle);
g_assert (rv == CKR_ATTRIBUTE_VALUE_INVALID);
}
+
+DEFINE_TEST(object_expose)
+{
+ CK_OBJECT_HANDLE handle;
+ GckManager *manager;
+ GckObject *check, *object;
+
+ manager = gck_session_get_manager (session);
+ object = test_module_object_new (session);
+
+ handle = gck_object_get_handle (object);
+ gck_object_expose (object, TRUE);
+
+ /* Now it should have a handle, and be visible */
+ check = gck_manager_find_by_handle (manager, handle);
+ g_assert (check == object);
+
+ gck_object_expose (object, FALSE);
+
+ /* Now should be invisible */
+ check = gck_manager_find_by_handle (manager, handle);
+ g_assert (check == NULL);
+}
+
+DEFINE_TEST(object_expose_transaction)
+{
+ CK_OBJECT_HANDLE handle;
+ GckManager *manager;
+ GckObject *check, *object;
+ GckTransaction *transaction;
+
+ manager = gck_session_get_manager (session);
+ object = test_module_object_new (session);
+
+ handle = gck_object_get_handle (object);
+ transaction = gck_transaction_new ();
+
+ /* Should be hidden */
+ gck_object_expose (object, FALSE);
+ check = gck_manager_find_by_handle (manager, handle);
+ g_assert (check == NULL);
+
+ /* Now it should have a handle, and be visible */
+ gck_object_expose_full (object, transaction, TRUE);
+ check = gck_manager_find_by_handle (manager, handle);
+ g_assert (check == object);
+
+ gck_transaction_fail (transaction, CKR_GENERAL_ERROR);
+ gck_transaction_complete (transaction);
+
+ /* Now should be invisible */
+ check = gck_manager_find_by_handle (manager, handle);
+ g_assert (check == NULL);
+
+ g_object_unref (transaction);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]