[gnome-keyring/dbus-api] [secret-store] Complete GckSecretItem functionality and unit tests.



commit 330ff74a1b8e2e5dc2198654f13259295dde637f
Author: Stef Walter <stef memberwebs com>
Date:   Wed Aug 12 03:48:56 2009 +0000

    [secret-store] Complete GckSecretItem functionality and unit tests.
    
    Complete most basic GckSecretItem functionality, and write tests
    to cover all remaining collection and item functionality.

 pkcs11/gck/gck-object.c                           |    4 +-
 pkcs11/secret-store/gck-secret-binary.c           |   10 +
 pkcs11/secret-store/gck-secret-fields.c           |    3 +-
 pkcs11/secret-store/gck-secret-item.c             |  121 +++-----
 pkcs11/secret-store/gck-secret-item.h             |    5 -
 pkcs11/secret-store/gck-secret-textual.c          |    9 +
 pkcs11/secret-store/tests/Makefile.am             |    1 +
 pkcs11/secret-store/tests/unit-test-secret-item.c |  351 +++++++++++++++++++++
 8 files changed, 413 insertions(+), 91 deletions(-)
---
diff --git a/pkcs11/gck/gck-object.c b/pkcs11/gck/gck-object.c
index f7bd7f7..cf0b25a 100644
--- a/pkcs11/gck/gck-object.c
+++ b/pkcs11/gck/gck-object.c
@@ -498,13 +498,13 @@ gck_object_set_attribute (GckObject *self, GckSession *session,
 	check.pValue = 0;
 	check.ulValueLen = 0;
 	rv = gck_object_get_attribute (self, session, &check);
-	if (rv != CKR_OK && rv != CKR_ATTRIBUTE_SENSITIVE) {
+	if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
 		gck_transaction_fail (transaction, rv);
 		return;
 	}
 	
 	/* Check that the value will actually change */
-	if (rv == CKR_ATTRIBUTE_SENSITIVE || !gck_object_match (self, session, attr))
+	if (rv != CKR_OK || !gck_object_match (self, session, attr))
 		GCK_OBJECT_GET_CLASS (self)->set_attribute (self, session, transaction, attr);
 }
 
diff --git a/pkcs11/secret-store/gck-secret-binary.c b/pkcs11/secret-store/gck-secret-binary.c
index a17927c..c0d143c 100644
--- a/pkcs11/secret-store/gck-secret-binary.c
+++ b/pkcs11/secret-store/gck-secret-binary.c
@@ -493,7 +493,10 @@ generate_encrypted_data (EggBuffer *buffer, GckSecretCollection *collection)
 		label = gck_secret_object_get_label (obj);
 		buffer_add_utf8_string (buffer, label);
 
+#if 0
 		secret = gck_secret_item_get_secret (item);
+#endif
+g_assert_not_reached ();
 		password = NULL;
 		if (secret != NULL)
 			password = gck_secret_get_password (secret, &n_password);
@@ -732,11 +735,18 @@ setup_item_from_info (GckSecretItem *item, gboolean locked, ItemInfo *info)
 
 	if (locked) {
 		g_object_set_data (G_OBJECT (item), "compat-acl", NULL);
+#if 0
 		gck_secret_item_set_secret (item, NULL);
+#endif
+g_assert_not_reached ();
+
 		
 	} else {
 		secret = gck_secret_new_from_password (info->secret);
+#if 0
 		gck_secret_item_set_secret (item, secret);
+#endif 
+g_assert_not_reached ();
 		g_object_unref (secret);
 		g_object_set_data_full (G_OBJECT (item), "compat-acl", info->acl, gck_secret_compat_acl_free);
 		info->acl = NULL;
diff --git a/pkcs11/secret-store/gck-secret-fields.c b/pkcs11/secret-store/gck-secret-fields.c
index 317bf62..f87ec54 100644
--- a/pkcs11/secret-store/gck-secret-fields.c
+++ b/pkcs11/secret-store/gck-secret-fields.c
@@ -174,7 +174,7 @@ gck_secret_fields_parse (CK_ATTRIBUTE_PTR attr, GHashTable **fields)
 		}
 		
 		n_name = ptr - name;
-		value = ptr;
+		value = ++ptr;
 		ptr = memchr (ptr, 0, last - ptr);
 		
 		/* The last value */
@@ -182,6 +182,7 @@ gck_secret_fields_parse (CK_ATTRIBUTE_PTR attr, GHashTable **fields)
 			ptr = last;
 		
 		n_value = ptr - value;
+		++ptr;
 
 		/* Validate the name and value*/
 		if (!g_utf8_validate (name, n_name, NULL) || 
diff --git a/pkcs11/secret-store/gck-secret-item.c b/pkcs11/secret-store/gck-secret-item.c
index a607bc2..d7b4fa8 100644
--- a/pkcs11/secret-store/gck-secret-item.c
+++ b/pkcs11/secret-store/gck-secret-item.c
@@ -21,6 +21,7 @@
 
 #include "config.h"
 
+#include "gck-secret-data.h"
 #include "gck-secret-fields.h"
 #include "gck-secret-item.h"
 
@@ -34,14 +35,12 @@
 
 enum {
 	PROP_0,
-	PROP_SECRET,
 	PROP_COLLECTION,
 	PROP_FIELDS
 };
 
 struct _GckSecretItem {
 	GckSecretObject parent;
-	GckSecret *secret;
 	GHashTable *fields;
 	GckSecretCollection *collection;
 };
@@ -56,34 +55,15 @@ static gboolean
 complete_set_secret (GckTransaction *transaction, GObject *obj, gpointer user_data)
 {
 	GckSecretItem *self = GCK_SECRET_ITEM (obj);
-	GckSecret *old_secret = user_data;
 	
-	if (gck_transaction_get_failed (transaction)) {
-		gck_secret_item_set_secret (self, old_secret);
-	} else {
+	if (!gck_transaction_get_failed (transaction)) {
 		gck_object_notify_attribute (GCK_OBJECT (obj), CKA_VALUE);
-		g_object_notify (G_OBJECT (obj), "secret");
 		gck_secret_object_was_modified (GCK_SECRET_OBJECT (self));
 	}
 
-	if (old_secret)
-		g_object_unref (old_secret);
 	return TRUE;
 }
 
-static void
-begin_set_secret (GckSecretItem *self, GckTransaction *transaction, GckSecret *secret)
-{
-	g_assert (GCK_IS_SECRET_OBJECT (self));
-	g_assert (!gck_transaction_get_failed (transaction));
-	
-	if (self->secret)
-		g_object_ref (self->secret);
-	gck_transaction_add (transaction, self, complete_set_secret, self->secret);
-	gck_secret_item_set_secret (self, secret);
-}
-
-
 static gboolean
 complete_set_fields (GckTransaction *transaction, GObject *obj, gpointer user_data)
 {
@@ -125,31 +105,37 @@ gck_secret_item_real_is_locked (GckSecretObject *obj, GckSession *session)
 	GckSecretItem *self = GCK_SECRET_ITEM (obj);
 	if (!self->collection)
 		return TRUE;
-	return gck_secret_object_is_locked (GCK_SECRET_OBJECT (self), session);
+	return gck_secret_object_is_locked (GCK_SECRET_OBJECT (self->collection), session);
 }
 
 static CK_RV
 gck_secret_item_real_get_attribute (GckObject *base, GckSession *session, CK_ATTRIBUTE_PTR attr)
 {
 	GckSecretItem *self = GCK_SECRET_ITEM (base);
+	GckSecretData *sdata;
 	const gchar *identifier;
-	const gchar *password;
-	gsize n_password;
-	
+	const guchar *secret;
+	gsize n_secret = 0;
+
+	g_return_val_if_fail (self->collection, CKR_GENERAL_ERROR);
+
 	switch (attr->type) {
 	case CKA_VALUE:
-		if (gck_secret_item_real_is_locked (GCK_SECRET_OBJECT (self), session))
+		sdata = gck_secret_collection_unlocked_data (self->collection, session);
+		if (sdata == NULL)
 			return CKR_USER_NOT_LOGGED_IN;
-		g_return_val_if_fail (self->secret, CKR_GENERAL_ERROR);
-		password = gck_secret_get_password (self->secret, &n_password);
-		return gck_attribute_set_data (attr, password, n_password);
-		
+		identifier = gck_secret_object_get_identifier (GCK_SECRET_OBJECT (self));
+		secret = gck_secret_data_get_raw (sdata, identifier, &n_secret);
+		return gck_attribute_set_data (attr, secret, n_secret);
+
 	case CKA_G_COLLECTION:
 		g_return_val_if_fail (self->collection, CKR_GENERAL_ERROR);
 		identifier = gck_secret_object_get_identifier (GCK_SECRET_OBJECT (self->collection));
 		return gck_attribute_set_string (attr, identifier);
 
 	case CKA_G_FIELDS:
+		if (!self->fields)
+			return gck_attribute_set_data (attr, NULL, 0);
 		return gck_secret_fields_serialize (attr, self->fields);
 	}
 
@@ -161,21 +147,33 @@ gck_secret_item_real_set_attribute (GckObject *base, GckSession *session,
                                     GckTransaction *transaction, CK_ATTRIBUTE_PTR attr)
 {
 	GckSecretItem *self = GCK_SECRET_ITEM (base);
+	const gchar *identifier;
+	GckSecretData *sdata;
 	GHashTable *fields;
 	GckSecret *secret;
 	CK_RV rv;
 
+	if (!self->collection) {
+		gck_transaction_fail (transaction, CKR_GENERAL_ERROR);
+		g_return_if_reached ();
+	}
+
 	/* Check that the object is not locked */
-	if (!gck_secret_item_real_is_locked (GCK_SECRET_OBJECT (self), session)) {
+	sdata = gck_secret_collection_unlocked_data (self->collection, session);
+	if (sdata == NULL) {
 		gck_transaction_fail (transaction, CKR_USER_NOT_LOGGED_IN);
 		return;
 	}
 
 	switch (attr->type) {
 	case CKA_VALUE:
+		identifier = gck_secret_object_get_identifier (GCK_SECRET_OBJECT (self));
 		secret = gck_secret_new (attr->pValue, attr->ulValueLen);
-		begin_set_secret (self, transaction, secret);
-		break;
+		gck_secret_data_set_transacted (sdata, transaction, identifier, secret);
+		g_object_unref (secret);
+		if (!gck_transaction_get_failed (transaction))
+			gck_transaction_add (transaction, self, complete_set_secret, NULL);
+		return;
 
 	case CKA_G_FIELDS:
 		rv = gck_secret_fields_parse (attr, &fields);
@@ -183,9 +181,9 @@ gck_secret_item_real_set_attribute (GckObject *base, GckSession *session,
 			gck_transaction_fail (transaction, rv);
 		else
 			begin_set_fields (self, transaction, fields);
-		break;
+		return;
 	}
-	
+
 	GCK_OBJECT_CLASS (gck_secret_item_parent_class)->set_attribute (base, session, transaction, attr);
 }
 
@@ -213,9 +211,6 @@ gck_secret_item_set_property (GObject *obj, guint prop_id, const GValue *value,
 	GckSecretItem *self = GCK_SECRET_ITEM (obj);
 	
 	switch (prop_id) {
-	case PROP_SECRET:
-		gck_secret_item_set_secret (self, g_value_get_object (value));
-		break;
 	case PROP_COLLECTION:
 		g_return_if_fail (!self->collection);
 		self->collection = g_value_get_object (value);
@@ -239,9 +234,6 @@ gck_secret_item_get_property (GObject *obj, guint prop_id, GValue *value,
 	GckSecretItem *self = GCK_SECRET_ITEM (obj);
 	
 	switch (prop_id) {
-	case PROP_SECRET:
-		g_value_set_object (value, gck_secret_item_get_secret (self));
-		break;
 	case PROP_COLLECTION:
 		g_value_set_object (value, gck_secret_item_get_collection (self));
 		break;
@@ -264,8 +256,6 @@ gck_secret_item_dispose (GObject *obj)
 		                              (gpointer*)&(self->collection));
 	self->collection = NULL;
 	
-	gck_secret_item_set_secret (self, NULL);
-	
 	G_OBJECT_CLASS (gck_secret_item_parent_class)->dispose (obj);
 }
 
@@ -275,7 +265,6 @@ gck_secret_item_finalize (GObject *obj)
 	GckSecretItem *self = GCK_SECRET_ITEM (obj);
 	
 	g_assert (!self->collection);
-	g_assert (!self->secret);
 	
 	if (self->fields)
 		g_hash_table_unref (self->fields);
@@ -304,11 +293,7 @@ gck_secret_item_class_init (GckSecretItemClass *klass)
 
 	secret_class->is_locked = gck_secret_item_real_is_locked;
 
-	g_object_class_install_property (gobject_class, PROP_SECRET,
-	           g_param_spec_object ("secret", "Secret", "Item's Secret",
-	                                GCK_TYPE_SECRET, G_PARAM_READWRITE));
-
-	g_object_class_install_property (gobject_class, PROP_SECRET,
+	g_object_class_install_property (gobject_class, PROP_COLLECTION,
 	           g_param_spec_object ("collection", "Collection", "Item's Collection",
 	                                GCK_TYPE_SECRET_COLLECTION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
@@ -328,32 +313,6 @@ gck_secret_item_get_collection (GckSecretItem *self)
 	return self->collection;
 }
 
-GckSecret*
-gck_secret_item_get_secret (GckSecretItem *self)
-{
-	g_return_val_if_fail (GCK_IS_SECRET_ITEM (self), NULL);
-	return self->secret;
-}
-
-void
-gck_secret_item_set_secret (GckSecretItem *self, GckSecret *secret)
-{
-	g_return_if_fail (GCK_IS_SECRET_ITEM (self));
-	
-	if (secret == self->secret)
-		return;
-	
-	if (self->secret)
-		g_object_remove_weak_pointer (G_OBJECT (self->secret),
-		                              (gpointer*)&(self->secret));
-	self->secret = secret;
-	if (self->secret)
-		g_object_add_weak_pointer (G_OBJECT (self->secret),
-		                           (gpointer*)&(self->secret));
-	
-	g_object_notify (G_OBJECT (self), "secret");
-} 
-
 GHashTable*
 gck_secret_item_get_fields (GckSecretItem *self)
 {
@@ -366,16 +325,12 @@ gck_secret_item_set_fields (GckSecretItem *self, GHashTable *fields)
 {
 	g_return_if_fail (GCK_IS_SECRET_ITEM (self));
 	
-	if (fields == self->fields)
-		return;
-	
+	if (fields)
+		g_hash_table_ref (fields);
 	if (self->fields)
-		g_hash_table_unref (fields);
+		g_hash_table_unref (self->fields);
 	self->fields = fields;
-	if (self->fields)
-		g_hash_table_ref (fields);
 	
 	g_object_notify (G_OBJECT (self), "fields");
 	gck_object_notify_attribute (GCK_OBJECT (self), CKA_G_FIELDS);
-	gck_secret_object_was_modified (GCK_SECRET_OBJECT (self));
 }
diff --git a/pkcs11/secret-store/gck-secret-item.h b/pkcs11/secret-store/gck-secret-item.h
index efe718c..fd3344f 100644
--- a/pkcs11/secret-store/gck-secret-item.h
+++ b/pkcs11/secret-store/gck-secret-item.h
@@ -44,11 +44,6 @@ GType                  gck_secret_item_get_type               (void);
 
 GckSecretCollection*   gck_secret_item_get_collection         (GckSecretItem *self);
 
-GckSecret*             gck_secret_item_get_secret             (GckSecretItem *self);
-
-void                   gck_secret_item_set_secret             (GckSecretItem *self,
-                                                               GckSecret *secret);
-
 GHashTable*            gck_secret_item_get_fields             (GckSecretItem *self);
 
 void                   gck_secret_item_set_fields             (GckSecretItem *self,
diff --git a/pkcs11/secret-store/gck-secret-textual.c b/pkcs11/secret-store/gck-secret-textual.c
index b22defa..7f83937 100644
--- a/pkcs11/secret-store/gck-secret-textual.c
+++ b/pkcs11/secret-store/gck-secret-textual.c
@@ -328,7 +328,10 @@ generate_item (GKeyFile *file, GckSecretItem *item)
 	if (value != NULL)
 		g_key_file_set_string (file, groupname, "display-name", value);
 	
+#if 0
 	secret = gck_secret_item_get_secret (item);
+#endif
+g_assert_not_reached ();
 	if (secret != NULL) {
 		password = gck_secret_get_password (secret, &n_password);
 		/* TODO: What about non-textual passwords? */
@@ -381,10 +384,16 @@ parse_item (GKeyFile *file, GckSecretItem *item, const gchar **groups)
 
 	val = g_key_file_get_string (file, groupname, "secret", NULL);
 	if (val == NULL) {
+#if 0
 		gck_secret_item_set_secret (item, NULL);
+#endif
+g_assert_not_reached ();
 	} else {
 		secret = gck_secret_new ((guchar*)val, strlen (val));
+#if 0
 		gck_secret_item_set_secret (item, secret);
+#endif
+g_assert_not_reached ();
 		g_object_unref (secret);
 		g_free (val);
 	}
diff --git a/pkcs11/secret-store/tests/Makefile.am b/pkcs11/secret-store/tests/Makefile.am
index ed75635..bec3662 100644
--- a/pkcs11/secret-store/tests/Makefile.am
+++ b/pkcs11/secret-store/tests/Makefile.am
@@ -2,6 +2,7 @@ UNIT_AUTO = \
 	unit-test-secret-collection.c \
 	unit-test-secret-compat.c \
 	unit-test-secret-data.c \
+	unit-test-secret-item.c \
 	unit-test-secret-object.c \
 	test-secret-module.c test-secret-module.h
 
diff --git a/pkcs11/secret-store/tests/unit-test-secret-item.c b/pkcs11/secret-store/tests/unit-test-secret-item.c
new file mode 100644
index 0000000..1cad7fe
--- /dev/null
+++ b/pkcs11/secret-store/tests/unit-test-secret-item.c
@@ -0,0 +1,351 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* unit-test-secret-item.c: Test secret item
+
+   Copyright (C) 2009 Stefan Walter
+
+   The Gnome Keyring Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The Gnome Keyring Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Stef Walter <stef memberwebs com>
+*/
+
+#include "config.h"
+
+#include "run-auto-test.h"
+#include "test-secret-module.h"
+
+#include "gck-secret-collection.h"
+#include "gck-secret-fields.h"
+#include "gck-secret-item.h"
+
+#include "gck/gck-authenticator.h"
+#include "gck/gck-session.h"
+#include "gck/gck-transaction.h"
+
+#include "pkcs11/pkcs11i.h"
+
+#include <glib.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+static GckModule *module = NULL;
+static GckSession *session = NULL;
+static GckSecretCollection *collection = NULL;
+
+DEFINE_SETUP(secret_item)
+{
+	module = test_secret_module_initialize_and_enter ();
+	session = test_secret_module_open_session (TRUE);
+
+	collection = g_object_new (GCK_TYPE_SECRET_COLLECTION,
+	                           "module", module,
+	                           "identifier", "test",
+	                           NULL);
+}
+
+DEFINE_TEARDOWN(secret_item)
+{
+	if (collection)
+		g_object_unref (collection);
+	collection = NULL;
+
+	test_secret_module_leave_and_finalize ();
+	module = NULL;
+	session = NULL;
+
+}
+
+static void
+unlock_collection(void)
+{
+	GckAuthenticator *auth;
+	CK_RV rv;
+
+	/* Create authenticator, which unlocks collection */
+	rv = gck_authenticator_create (GCK_OBJECT (collection), NULL, 0, &auth); 
+	g_assert (rv == CKR_OK);
+	gck_session_add_session_object (session, NULL, GCK_OBJECT (auth));
+	g_object_unref (auth);
+}
+
+DEFINE_TEST(secret_item_create)
+{
+	GckSecretItem *item;
+
+	item = gck_secret_collection_create_item (collection, "the-identifier");
+	g_assert (GCK_IS_SECRET_ITEM (item));
+	g_assert_cmpstr (gck_secret_object_get_identifier (GCK_SECRET_OBJECT (item)), ==, "the-identifier");
+}
+
+DEFINE_TEST(secret_item_collection_get)
+{
+	GckSecretItem *item, *check;
+
+	item = gck_secret_collection_create_item (collection, "the-identifier");
+	g_assert (GCK_IS_SECRET_ITEM (item));
+
+	check = gck_secret_collection_get_item (collection, "the-identifier");
+	g_assert (item == check);
+}
+
+DEFINE_TEST(secret_item_collection_items)
+{
+	GList *l, *items;
+	const gchar *identifier;
+
+	gck_secret_collection_create_item (collection, "one-identifier");
+	gck_secret_collection_create_item (collection, "two-identifier");
+	gck_secret_collection_create_item (collection, "three-identifier");
+
+	items = gck_secret_collection_get_items (collection);
+	g_assert_cmpuint (g_list_length (items), ==, 3);
+	for (l = items; l; l = g_list_next (l)) {
+		identifier = gck_secret_object_get_identifier (l->data);
+		if (!g_str_equal (identifier, "one-identifier") &&
+		    !g_str_equal (identifier, "two-identifier") &&
+		    !g_str_equal (identifier, "three-identifier"))
+			g_assert_not_reached ();
+	}
+
+	g_list_free (items);
+}
+
+DEFINE_TEST(secret_item_collection_remove)
+{
+	GckSecretItem *item;
+
+	item = gck_secret_collection_create_item (collection, "the-identifier");
+	g_assert (gck_secret_collection_get_item (collection, "the-identifier") == item);
+
+	gck_secret_collection_remove_item (collection, item);
+	g_assert (gck_secret_collection_get_item (collection, "the-identifier") == NULL);
+}
+
+DEFINE_TEST(secret_item_is_locked)
+{
+	GckSecretItem *item;
+
+	item = gck_secret_collection_create_item (collection, "the-identifier");
+	g_assert (gck_secret_object_is_locked (GCK_SECRET_OBJECT (item), session) == 
+	          gck_secret_object_is_locked (GCK_SECRET_OBJECT (collection), session));
+
+	unlock_collection();
+
+	g_assert (gck_secret_object_is_locked (GCK_SECRET_OBJECT (item), session) == FALSE);
+}
+
+DEFINE_TEST(secret_item_get_collection)
+{
+	GckSecretItem *item;
+	item = gck_secret_collection_create_item (collection, "the-identifier");
+	g_assert (gck_secret_item_get_collection (item) == collection);
+}
+
+DEFINE_TEST(secret_item_tracks_collection)
+{
+	GckSecretItem *item;
+	item = gck_secret_collection_create_item (collection, "the-identifier");
+	g_object_ref (item);
+
+	unlock_collection();
+
+	/* At this point the item should be 'unlocked' */
+	g_assert (gck_secret_object_is_locked (GCK_SECRET_OBJECT (item), session) == FALSE);
+
+	g_object_unref (collection);
+	collection = NULL;
+
+	/* Collection went away */
+	g_assert (gck_secret_item_get_collection (item) == NULL);
+	g_assert (gck_secret_object_is_locked (GCK_SECRET_OBJECT (item), session) == TRUE);
+
+	g_object_unref (item);
+}
+
+DEFINE_TEST(secret_item_get_set_fields)
+{
+	GHashTable *fields = gck_secret_fields_new ();
+	GHashTable *check;
+	GckSecretItem *item;
+
+	item = gck_secret_collection_create_item (collection, "the-identifier");
+	gck_secret_item_set_fields (item, fields);
+	gck_secret_item_set_fields (item, fields);
+
+	check = gck_secret_item_get_fields (item);
+	g_assert (check == fields);
+
+	g_hash_table_unref (fields);
+}
+
+DEFINE_TEST(secret_item_collection_attr)
+{
+	gchar buffer[32];
+	CK_ATTRIBUTE check = { CKA_G_COLLECTION, buffer, 32 };
+	GckSecretItem *item;
+	CK_RV rv;
+
+	item = gck_secret_collection_create_item (collection, "the-identifier");
+	rv = gck_object_get_attribute (GCK_OBJECT (item), session, &check);
+	g_assert (rv == CKR_OK);
+	g_assert (check.ulValueLen == 4);
+	g_assert (memcmp (buffer, "test", 4) == 0);
+}
+
+DEFINE_TEST(secret_item_secret_attr)
+{
+	GckTransaction *transaction = gck_transaction_new ();
+	CK_ATTRIBUTE attr = { CKA_VALUE, "hello", 5 };
+	gchar buffer[32];
+	CK_ATTRIBUTE check = { CKA_VALUE, buffer, 32 };
+	GckSecretItem *item;
+	CK_RV rv;
+
+	unlock_collection ();
+
+	item = gck_secret_collection_create_item (collection, "the-identifier");
+	gck_object_set_attribute (GCK_OBJECT (item), session, transaction, &attr);
+	g_assert (gck_transaction_get_failed (transaction) == FALSE);
+	gck_transaction_complete (transaction);
+	g_assert (gck_transaction_get_result (transaction) == CKR_OK);
+
+	g_object_unref (transaction);
+
+	rv = gck_object_get_attribute (GCK_OBJECT (item), session, &check);
+	g_assert (rv == CKR_OK);
+	g_assert (check.ulValueLen == 5);
+	g_assert (memcmp (buffer, "hello", 5) == 0);
+}
+
+DEFINE_TEST(secret_item_secret_attr_locked)
+{
+	GckTransaction *transaction = gck_transaction_new ();
+	CK_ATTRIBUTE attr = { CKA_VALUE, "hello", 5 };
+	gchar buffer[32];
+	CK_ATTRIBUTE check = { CKA_VALUE, buffer, 32 };
+	GckSecretItem *item;
+	CK_RV rv;
+
+	item = gck_secret_collection_create_item (collection, "the-identifier");
+	gck_object_set_attribute (GCK_OBJECT (item), session, transaction, &attr);
+	g_assert (gck_transaction_get_failed (transaction) == TRUE);
+	gck_transaction_complete (transaction);
+	g_assert (gck_transaction_get_result (transaction) == CKR_USER_NOT_LOGGED_IN);
+
+	g_object_unref (transaction);
+
+	rv = gck_object_get_attribute (GCK_OBJECT (item), session, &check);
+	g_assert (rv == CKR_USER_NOT_LOGGED_IN);
+}
+
+DEFINE_TEST(secret_item_fields_attr)
+{
+	GckTransaction *transaction = gck_transaction_new ();
+	CK_ATTRIBUTE attr = { CKA_G_FIELDS, "name1\0value1\0name2\0value2", 26 };
+	gchar buffer[32];
+	CK_ATTRIBUTE check = { CKA_G_FIELDS, buffer, 32 };
+	GckSecretItem *item;
+	GHashTable *fields;
+	const gchar *value;
+	CK_RV rv;
+
+	unlock_collection ();
+
+	item = gck_secret_collection_create_item (collection, "the-identifier");
+	gck_object_set_attribute (GCK_OBJECT (item), session, transaction, &attr);
+	g_assert (gck_transaction_get_failed (transaction) == FALSE);
+	gck_transaction_complete (transaction);
+	g_assert (gck_transaction_get_result (transaction) == CKR_OK);
+
+	g_object_unref (transaction);
+
+	rv = gck_object_get_attribute (GCK_OBJECT (item), session, &check);
+	g_assert (rv == CKR_OK);
+	g_assert (check.ulValueLen == 26);
+	g_assert (memcmp (buffer, "name1\0value1\0name2\0value2", 26) == 0);
+
+	fields = gck_secret_item_get_fields (item);
+	g_assert (fields);
+	value = gck_secret_fields_get (fields, "name1");
+	g_assert_cmpstr (value, ==, "value1");
+	value = gck_secret_fields_get (fields, "name2");
+	g_assert_cmpstr (value, ==, "value2");
+}
+
+DEFINE_TEST(secret_item_fields_attr_locked)
+{
+	GckTransaction *transaction = gck_transaction_new ();
+	CK_ATTRIBUTE attr = { CKA_G_FIELDS, "name1\0value1\0name2\0value2", 26 };
+	GckSecretItem *item;
+
+	item = gck_secret_collection_create_item (collection, "the-identifier");
+	gck_object_set_attribute (GCK_OBJECT (item), session, transaction, &attr);
+	g_assert (gck_transaction_get_failed (transaction) == TRUE);
+	gck_transaction_complete (transaction);
+	g_assert (gck_transaction_get_result (transaction) == CKR_USER_NOT_LOGGED_IN);
+
+	g_object_unref (transaction);
+}
+
+DEFINE_TEST(secret_item_fields_attr_reverts)
+{
+	GckTransaction *transaction = gck_transaction_new ();
+	CK_ATTRIBUTE attr = { CKA_G_FIELDS, "new\0value\0", 10 };
+	gchar buffer[32];
+	CK_ATTRIBUTE check = { CKA_G_FIELDS, buffer, 32 };
+	GckSecretItem *item;
+	GHashTable *fields;
+	CK_RV rv;
+
+	unlock_collection ();
+
+	item = gck_secret_collection_create_item (collection, "the-identifier");
+
+	/* Set the old value like so */
+	fields = gck_secret_fields_new ();
+	gck_secret_fields_add (fields, "old", "value");
+	gck_secret_item_set_fields (item, fields);
+	g_hash_table_unref (fields);
+
+	/* Should show old value */
+	rv = gck_object_get_attribute (GCK_OBJECT (item), session, &check);
+	g_assert (rv == CKR_OK);
+	g_assert (check.ulValueLen == 10);
+	g_assert (memcmp (buffer, "old\0value\0", 10) == 0);
+
+	/* Set the new values */
+	gck_object_set_attribute (GCK_OBJECT (item), session, transaction, &attr);
+	g_assert (gck_transaction_get_failed (transaction) == FALSE);
+
+	/* Should have the new value */
+	rv = gck_object_get_attribute (GCK_OBJECT (item), session, &check);
+	g_assert (rv == CKR_OK);
+	g_assert (check.ulValueLen == 10);
+	g_assert (memcmp (buffer, "new\0value\0", 10) == 0);
+
+	/* Fail the transaction */
+	gck_transaction_fail (transaction, CKR_CANCEL);
+	gck_transaction_complete (transaction);
+
+	/* Should show the old value */
+	rv = gck_object_get_attribute (GCK_OBJECT (item), session, &check);
+	g_assert (rv == CKR_OK);
+	g_assert (check.ulValueLen == 10);
+	g_assert (memcmp (buffer, "old\0value\0", 10) == 0);
+
+	g_object_unref (transaction);
+}



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