[gnome-keyring/dbus-api] [secret-store] Complete loading/unlocking code for GckSecretCollection.
- From: Stefan Walter <stefw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-keyring/dbus-api] [secret-store] Complete loading/unlocking code for GckSecretCollection.
- Date: Sat, 15 Aug 2009 14:41:23 +0000 (UTC)
commit 2798e6b63edc34419e0dd44f3ef6e72ab4996d13
Author: Stef Walter <stef memberwebs com>
Date: Sat Aug 15 13:46:41 2009 +0000
[secret-store] Complete loading/unlocking code for GckSecretCollection.
Complete the loading and unlocking code for collections. Integrate loading
properly into GckSecretModule.
pkcs11/secret-store/gck-secret-binary.c | 17 +-
pkcs11/secret-store/gck-secret-collection.c | 230 +++++++++++++++-----
pkcs11/secret-store/gck-secret-collection.h | 9 +
pkcs11/secret-store/gck-secret-module.c | 45 ++--
pkcs11/secret-store/gck-secret-types.h | 3 +
.../secret-store/tests/unit-test-secret-binary.c | 33 +++
.../tests/unit-test-secret-collection.c | 209 ++++++++++++++++++
7 files changed, 471 insertions(+), 75 deletions(-)
---
diff --git a/pkcs11/secret-store/gck-secret-binary.c b/pkcs11/secret-store/gck-secret-binary.c
index e78c9d1..f21f236 100644
--- a/pkcs11/secret-store/gck-secret-binary.c
+++ b/pkcs11/secret-store/gck-secret-binary.c
@@ -375,18 +375,25 @@ static gboolean
decrypt_buffer (EggBuffer *buffer, GckSecret *master,
guchar salt[8], int iterations)
{
- const gchar *password;
+ const gchar *password = NULL;
gcry_cipher_hd_t cih;
gcry_error_t gerr;
guchar *key, *iv;
- gsize n_password;
+ gsize n_password = 0;
size_t pos;
g_assert (buffer->len % 16 == 0);
g_assert (16 == gcry_cipher_get_algo_blklen (GCRY_CIPHER_AES128));
g_assert (16 == gcry_cipher_get_algo_keylen (GCRY_CIPHER_AES128));
- password = gck_secret_get_password (master, &n_password);
+ /* No password is set, try an null password */
+ if (master == NULL) {
+ password = NULL;
+ n_password = 0;
+ } else {
+ password = gck_secret_get_password (master, &n_password);
+ }
+
if (!egg_symkey_generate_simple (GCRY_CIPHER_AES128, GCRY_MD_SHA256,
password, n_password, salt, 8, iterations, &key, &iv))
return FALSE;
@@ -623,7 +630,10 @@ gck_secret_binary_write (GckSecretCollection *collection, GckSecretData *sdata,
(guchar*)to_encrypt.buf + 16, to_encrypt.len - 16);
memcpy (to_encrypt.buf, digest, 16);
+ /* If no master password is set, we shouldn't be writing binary... */
master = gck_secret_data_get_master (sdata);
+ g_return_val_if_fail (master, GCK_DATA_FAILURE);
+
if (!encrypt_buffer (&to_encrypt, master, salt, hash_iterations)) {
egg_buffer_uninit (&buffer);
egg_buffer_uninit (&to_encrypt);
@@ -911,7 +921,6 @@ gck_secret_binary_read (GckSecretCollection *collection, GckSecretData *sdata,
if (sdata != NULL) {
master = gck_secret_data_get_master (sdata);
- g_return_val_if_fail (master, GCK_DATA_FAILURE);
if (!decrypt_buffer (&to_decrypt, master, salt, hash_iterations))
goto bail;
if (!verify_decrypted_buffer (&to_decrypt)) {
diff --git a/pkcs11/secret-store/gck-secret-collection.c b/pkcs11/secret-store/gck-secret-collection.c
index 90fdcfe..b4ab958 100644
--- a/pkcs11/secret-store/gck-secret-collection.c
+++ b/pkcs11/secret-store/gck-secret-collection.c
@@ -27,29 +27,57 @@
#include "gck-secret-item.h"
#include "gck-secret-textual.h"
+#include "gck/gck-authenticator.h"
+#include "gck/gck-secret.h"
#include "gck/gck-session.h"
#include <glib/gi18n.h>
+enum {
+ PROP_0,
+ PROP_FILENAME
+};
+
struct _GckSecretCollection {
GckSecretObject parent;
- GckSecretData *data;
+ GckSecretData *sdata;
GHashTable *items;
+ gchar *filename;
};
G_DEFINE_TYPE (GckSecretCollection, gck_secret_collection, GCK_TYPE_SECRET_OBJECT);
-#if 0
-static void gck_secret_collection_serializable (GckSerializableIface *iface);
-
-G_DEFINE_TYPE_EXTENDED (GckSecretCollection, gck_secret_collection, GCK_TYPE_SECRET_OBJECT, 0,
- G_IMPLEMENT_INTERFACE (GCK_TYPE_SERIALIZABLE, gck_secret_collection_serializable));
-#endif
-
/* -----------------------------------------------------------------------------
* INTERNAL
*/
+static GckDataResult
+load_collection_and_secret_data (GckSecretCollection *self, GckSecretData *sdata,
+ const gchar *path)
+{
+ GckDataResult res;
+ GError *error = NULL;
+ guchar *data;
+ gsize n_data;
+
+ /* Read in the keyring */
+ if (!g_file_get_contents (path, (gchar**)&data, &n_data, &error)) {
+ g_message ("problem reading keyring: %s: %s",
+ path, error && error->message ? error->message : "");
+ g_clear_error (&error);
+ return GCK_DATA_FAILURE;
+ }
+
+ /* Try to load from an encrypted file, and otherwise plain text */
+ res = gck_secret_binary_read (self, sdata, data, n_data);
+ if (res == GCK_DATA_UNRECOGNIZED)
+ res = gck_secret_textual_read (self, sdata, data, n_data);
+
+ g_free (data);
+
+ return res;
+}
+
static gboolean
find_unlocked_secret_data (GckAuthenticator *auth, GckObject *object, gpointer user_data)
{
@@ -61,7 +89,7 @@ find_unlocked_secret_data (GckAuthenticator *auth, GckObject *object, gpointer u
sdata = g_object_get_data (G_OBJECT (auth), "collection-secret-data");
if (sdata) {
- g_return_val_if_fail (sdata == self->data, FALSE);
+ g_return_val_if_fail (sdata == self->sdata, FALSE);
*result = sdata;
return TRUE;
}
@@ -74,13 +102,13 @@ track_secret_data (GckSecretCollection *self, GckSecretData *data)
{
g_return_if_fail (GCK_IS_SECRET_COLLECTION (self));
- if (self->data)
- g_object_remove_weak_pointer (G_OBJECT (self->data),
- (gpointer*)&(self->data));
- self->data = data;
- if (self->data)
- g_object_add_weak_pointer (G_OBJECT (self->data),
- (gpointer*)&self->data);
+ if (self->sdata)
+ g_object_remove_weak_pointer (G_OBJECT (self->sdata),
+ (gpointer*)&(self->sdata));
+ self->sdata = data;
+ if (self->sdata)
+ g_object_add_weak_pointer (G_OBJECT (self->sdata),
+ (gpointer*)&self->sdata);
}
static void
@@ -98,16 +126,58 @@ static CK_RV
gck_secret_collection_real_unlock (GckObject *obj, GckAuthenticator *auth)
{
GckSecretCollection *self = GCK_SECRET_COLLECTION (obj);
+ GckDataResult res;
GckSecretData *sdata;
+ GckSecret *master;
- sdata = g_object_new (GCK_TYPE_SECRET_DATA, NULL);
+ master = gck_authenticator_get_login (auth);
+
+ /* Already unlocked, make sure pin matches */
+ if (self->sdata) {
+ if (!gck_secret_equal (gck_secret_data_get_master (self->sdata), master))
+ return CKR_PIN_INCORRECT;
- /* TODO: Implement actual unlock work here */
+ /* Authenticator now tracks our secret data */
+ g_object_set_data_full (G_OBJECT (auth), "collection-secret-data",
+ g_object_ref (self->sdata), g_object_unref);
+ return CKR_OK;
+ }
- g_object_set_data_full (G_OBJECT (auth), "collection-secret-data", sdata, g_object_unref);
- track_secret_data (self, sdata);
+ /* New secret data object, setup master password */
+ sdata = g_object_new (GCK_TYPE_SECRET_DATA, NULL);
+ gck_secret_data_set_master (sdata, master);
+
+ /* Load the data from a file, and decrypt if necessary */
+ if (self->filename) {
+ res = load_collection_and_secret_data (self, sdata, self->filename);
+
+ /* No filename, password must be null */
+ } else {
+ if (gck_secret_equals (master, NULL, 0))
+ res = GCK_DATA_SUCCESS;
+ else
+ res = GCK_DATA_LOCKED;
+ }
- return CKR_OK;
+ switch (res) {
+ case GCK_DATA_SUCCESS:
+ g_object_set_data_full (G_OBJECT (auth), "collection-secret-data", sdata, g_object_unref);
+ track_secret_data (self, sdata);
+ return CKR_OK;
+ case GCK_DATA_LOCKED:
+ g_object_unref (sdata);
+ return CKR_PIN_INCORRECT;
+ case GCK_DATA_UNRECOGNIZED:
+ g_object_unref (sdata);
+ g_message ("unrecognized or invalid keyring: %s", self->filename);
+ return CKR_FUNCTION_FAILED;
+ case GCK_DATA_FAILURE:
+ g_object_unref (sdata);
+ g_message ("failed to read or parse keyring: %s", self->filename);
+ return CKR_GENERAL_ERROR;
+ default:
+ g_assert_not_reached ();
+ }
}
static gboolean
@@ -123,6 +193,39 @@ gck_secret_collection_init (GckSecretCollection *self)
self->items = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
}
+
+static void
+gck_secret_collection_set_property (GObject *obj, guint prop_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ GckSecretCollection *self = GCK_SECRET_COLLECTION (obj);
+
+ switch (prop_id) {
+ case PROP_FILENAME:
+ gck_secret_collection_set_filename (self, g_value_get_string (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gck_secret_collection_get_property (GObject *obj, guint prop_id, GValue *value,
+ GParamSpec *pspec)
+{
+ GckSecretCollection *self = GCK_SECRET_COLLECTION (obj);
+
+ switch (prop_id) {
+ case PROP_FILENAME:
+ g_value_set_string (value, gck_secret_collection_get_filename (self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
static void
gck_secret_collection_dispose (GObject *obj)
{
@@ -139,11 +242,14 @@ gck_secret_collection_finalize (GObject *obj)
{
GckSecretCollection *self = GCK_SECRET_COLLECTION (obj);
- g_assert (self->data == NULL);
+ g_assert (self->sdata == NULL);
g_hash_table_destroy (self->items);
self->items = NULL;
+ g_free (self->filename);
+ self->filename = NULL;
+
G_OBJECT_CLASS (gck_secret_collection_parent_class)->finalize (obj);
}
@@ -156,33 +262,21 @@ gck_secret_collection_class_init (GckSecretCollectionClass *klass)
gck_secret_collection_parent_class = g_type_class_peek_parent (klass);
+ gobject_class->set_property = gck_secret_collection_set_property;
+ gobject_class->get_property = gck_secret_collection_get_property;
gobject_class->dispose = gck_secret_collection_dispose;
gobject_class->finalize = gck_secret_collection_finalize;
gck_class->unlock = gck_secret_collection_real_unlock;
secret_class->is_locked = gck_secret_collection_real_is_locked;
-}
-
-#if 0
-static gboolean
-gck_secret_collection_real_load (GckSerializable *base, GckSecret *login, const guchar *data, gsize n_data)
-{
- GckSecretCollection *self = GCK_SECRET_COLLECTION (base);
- GckDataResult res;
-
- g_return_val_if_fail (GCK_IS_SECRET_COLLECTION (self), FALSE);
- g_return_val_if_fail (data, FALSE);
- g_return_val_if_fail (n_data, FALSE);
-
- res = gck_secret_binary_read (self, login, data, n_data);
- if (res == GCK_DATA_UNRECOGNIZED)
- res = gck_secret_textual_read (self, data, n_data);
- /* TODO: This doesn't transfer knowledge of 'wrong password' back up */
- return (res == GCK_DATA_SUCCESS);
+ g_object_class_install_property (gobject_class, PROP_FILENAME,
+ g_param_spec_string ("filename", "Filename", "Collection filename (without path)",
+ NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
}
+#if 0
static gboolean
gck_secret_collection_real_save (GckSerializable *base, GckSecret *login, guchar **data, gsize *n_data)
{
@@ -194,10 +288,10 @@ gck_secret_collection_real_save (GckSerializable *base, GckSecret *login, guchar
g_return_val_if_fail (data, FALSE);
g_return_val_if_fail (n_data, FALSE);
- if (!self->data)
+ if (!self->sdata)
g_return_val_if_reached (FALSE);
- master = gck_secret_data_get_master (self->data);
+ master = gck_secret_data_get_master (self->sdata);
if (master == NULL)
res = gck_secret_textual_write (self, data, n_data);
else
@@ -207,19 +301,31 @@ gck_secret_collection_real_save (GckSerializable *base, GckSecret *login, guchar
return (res == GCK_DATA_SUCCESS);
}
-static void
-gck_secret_collection_serializable (GckSerializableIface *iface)
-{
- iface->extension = ".keyring";
- iface->load = gck_secret_collection_real_load;
- iface->save = gck_secret_collection_real_save;
-}
#endif
/* -----------------------------------------------------------------------------
* PUBLIC
*/
+const gchar*
+gck_secret_collection_get_filename (GckSecretCollection *self)
+{
+ g_return_val_if_fail (GCK_IS_SECRET_COLLECTION (self), NULL);
+ return self->filename;
+}
+
+void
+gck_secret_collection_set_filename (GckSecretCollection *self, const gchar *filename)
+{
+ g_return_if_fail (GCK_IS_SECRET_COLLECTION (self));
+
+ if (self->filename == filename)
+ return;
+ g_free (self->filename);
+ self->filename = g_strdup (filename);
+ g_object_notify (G_OBJECT (self), "filename");
+}
+
GList*
gck_secret_collection_get_items (GckSecretCollection *self)
{
@@ -282,7 +388,7 @@ gck_secret_collection_unlocked_data (GckSecretCollection *self, GckSession *sess
/*
* Look for authenticator objects that this session has access
* to, and use those to find the secret data. If a secret data is
- * found, it should match the one we are tracking in self->data.
+ * found, it should match the one we are tracking in self->sdata.
*/
gck_session_for_each_authenticator (session, GCK_OBJECT (self),
@@ -290,3 +396,27 @@ gck_secret_collection_unlocked_data (GckSecretCollection *self, GckSession *sess
return sdata;
}
+
+void
+gck_secret_collection_unlocked_clear (GckSecretCollection *self)
+{
+ /*
+ * TODO: This is a tough one to implement. I'm holding off and wondering
+ * if we don't need it, perhaps? As it currently stands, what needs to happen
+ * here is we need to find each and every authenticator that references the
+ * secret data for this collection and completely delete those objects.
+ */
+ g_warning ("Clearing of secret data needs implementing");
+ track_secret_data (self, NULL);
+}
+
+GckDataResult
+gck_secret_collection_load (GckSecretCollection *self)
+{
+ g_return_val_if_fail (GCK_IS_SECRET_COLLECTION (self), GCK_DATA_FAILURE);
+
+ if (!self->filename)
+ return GCK_DATA_SUCCESS;
+
+ return load_collection_and_secret_data (self, self->sdata, self->filename);
+}
diff --git a/pkcs11/secret-store/gck-secret-collection.h b/pkcs11/secret-store/gck-secret-collection.h
index 2bddd35..2f00cc9 100644
--- a/pkcs11/secret-store/gck-secret-collection.h
+++ b/pkcs11/secret-store/gck-secret-collection.h
@@ -41,6 +41,13 @@ struct _GckSecretCollectionClass {
GType gck_secret_collection_get_type (void);
+GckDataResult gck_secret_collection_load (GckSecretCollection *self);
+
+const gchar* gck_secret_collection_get_filename (GckSecretCollection *self);
+
+void gck_secret_collection_set_filename (GckSecretCollection *self,
+ const gchar *filename);
+
GList* gck_secret_collection_get_items (GckSecretCollection *self);
GckSecretItem* gck_secret_collection_get_item (GckSecretCollection *self,
@@ -52,6 +59,8 @@ GckSecretItem* gck_secret_collection_create_item (GckSecretCollection
void gck_secret_collection_remove_item (GckSecretCollection *self,
GckSecretItem *item);
+void gck_secret_collection_unlocked_clear (GckSecretCollection *self);
+
GckSecretData* gck_secret_collection_unlocked_data (GckSecretCollection *self,
GckSession *session);
diff --git a/pkcs11/secret-store/gck-secret-module.c b/pkcs11/secret-store/gck-secret-module.c
index 1090d66..40cafae 100644
--- a/pkcs11/secret-store/gck-secret-module.c
+++ b/pkcs11/secret-store/gck-secret-module.c
@@ -26,7 +26,6 @@
#include "gck-secret-store.h"
#include "gck/gck-file-tracker.h"
-#include "gck/gck-serializable.h"
#include <fcntl.h>
#include <string.h>
@@ -84,55 +83,59 @@ GCK_DEFINE_MODULE (gck_secret_module, GCK_TYPE_SECRET_MODULE);
*/
static void
-file_load (GckFileTracker *tracker, const gchar *path, GckSecretModule *self)
+on_file_load (GckFileTracker *tracker, const gchar *path, GckSecretModule *self)
{
GckSecretCollection *collection;
- GError *error = NULL;
GckManager *manager;
+ GckDataResult res;
gboolean created;
gchar *basename;
- guchar *data;
- gsize n_data;
manager = gck_module_get_manager (GCK_MODULE (self));
g_return_if_fail (manager);
- /* Read in the keyring */
- if (!g_file_get_contents (path, (gchar**)&data, &n_data, &error)) {
- g_warning ("couldn't load keyring: %s: %s",
- path, error && error->message ? error->message : "");
- return;
- }
-
/* Do we have one for this path yet? */
basename = g_path_get_basename (path);
collection = g_hash_table_lookup (self->collections, basename);
if (collection == NULL) {
created = TRUE;
- g_assert ("unimplemented");
-#if 0
collection = g_object_new (GCK_TYPE_SECRET_COLLECTION,
"module", self,
"identifier", basename,
+ "filename", path,
NULL);
-#endif
}
- if (gck_serializable_load (GCK_SERIALIZABLE (collection), NULL, data, n_data)) {
+ res = gck_secret_collection_load (collection);
+
+ switch (res) {
+ case GCK_DATA_SUCCESS:
if (created) {
g_hash_table_replace (self->collections, basename, collection);
gck_manager_register_object (manager, GCK_OBJECT (collection));
basename = NULL;
}
+ break;
+ case GCK_DATA_LOCKED:
+ g_message ("master password for keyring changed without our knowledge: %s", path);
+ gck_secret_collection_unlocked_clear (collection);
+ break;
+ case GCK_DATA_UNRECOGNIZED:
+ g_message ("keyring was in an invalid or unrecognized format: %s", path);
+ break;
+ case GCK_DATA_FAILURE:
+ g_message ("failed to parse keyring: %s", path);
+ break;
+ default:
+ g_assert_not_reached ();
}
g_free (basename);
- g_free (data);
}
static void
-file_remove (GckFileTracker *tracker, const gchar *path, GckSecretModule *self)
+on_file_remove (GckFileTracker *tracker, const gchar *path, GckSecretModule *self)
{
gchar *basename;
@@ -194,9 +197,9 @@ gck_secret_module_constructor (GType type, guint n_props, GObjectConstructParam
}
self->tracker = gck_file_tracker_new (self->directory, "*.keyrings", NULL);
- g_signal_connect (self->tracker, "file-added", G_CALLBACK (file_load), self);
- g_signal_connect (self->tracker, "file-changed", G_CALLBACK (file_load), self);
- g_signal_connect (self->tracker, "file-removed", G_CALLBACK (file_remove), self);
+ g_signal_connect (self->tracker, "file-added", G_CALLBACK (on_file_load), self);
+ g_signal_connect (self->tracker, "file-changed", G_CALLBACK (on_file_load), self);
+ g_signal_connect (self->tracker, "file-removed", G_CALLBACK (on_file_remove), self);
return G_OBJECT (self);
}
diff --git a/pkcs11/secret-store/gck-secret-types.h b/pkcs11/secret-store/gck-secret-types.h
index 923cd7f..af64578 100644
--- a/pkcs11/secret-store/gck-secret-types.h
+++ b/pkcs11/secret-store/gck-secret-types.h
@@ -22,6 +22,9 @@
#ifndef __GCK_SECRET_TYPES_H__
#define __GCK_SECRET_TYPES_H__
+#include "gck/gck-types.h"
+#include "gck/gck-data-types.h"
+
typedef struct _GckSecretCollection GckSecretCollection;
typedef struct _GckSecretData GckSecretData;
typedef struct _GckSecretItem GckSecretItem;
diff --git a/pkcs11/secret-store/tests/unit-test-secret-binary.c b/pkcs11/secret-store/tests/unit-test-secret-binary.c
index 7f92c5d..7393037 100644
--- a/pkcs11/secret-store/tests/unit-test-secret-binary.c
+++ b/pkcs11/secret-store/tests/unit-test-secret-binary.c
@@ -112,6 +112,39 @@ DEFINE_TEST(binary_read_wrong_format)
g_assert (res == GCK_DATA_UNRECOGNIZED);
}
+DEFINE_TEST(binary_read_wrong_master)
+{
+ GckDataResult res;
+ GckSecret *master;
+ guchar *data;
+ gsize n_data;
+
+ master = gck_secret_new_from_password ("wrong");
+ gck_secret_data_set_master (sdata, master);
+ g_object_unref (master);
+
+ data = test_read_testdata ("encrypted.keyring", &n_data);
+ res = gck_secret_binary_read (collection, sdata, data, n_data);
+ g_free (data);
+
+ g_assert (res == GCK_DATA_LOCKED);
+}
+
+DEFINE_TEST(binary_read_sdata_but_no_master)
+{
+ GckDataResult res;
+ guchar *data;
+ gsize n_data;
+
+ gck_secret_data_set_master (sdata, NULL);
+
+ data = test_read_testdata ("encrypted.keyring", &n_data);
+ res = gck_secret_binary_read (collection, sdata, data, n_data);
+ g_free (data);
+
+ g_assert (res == GCK_DATA_LOCKED);
+}
+
DEFINE_TEST(binary_write)
{
GckDataResult res;
diff --git a/pkcs11/secret-store/tests/unit-test-secret-collection.c b/pkcs11/secret-store/tests/unit-test-secret-collection.c
index 7d1c8e4..747aedd 100644
--- a/pkcs11/secret-store/tests/unit-test-secret-collection.c
+++ b/pkcs11/secret-store/tests/unit-test-secret-collection.c
@@ -93,3 +93,212 @@ DEFINE_TEST(secret_collection_unlocked_data)
g_assert (GCK_IS_SECRET_DATA (sdata));
g_assert (!gck_secret_object_is_locked (GCK_SECRET_OBJECT (collection), session));
}
+
+DEFINE_TEST(secret_collection_get_filename)
+{
+ GckSecretCollection *other;
+ const gchar *filename;
+
+ other = g_object_new (GCK_TYPE_SECRET_COLLECTION,
+ "module", module,
+ "identifier", "test",
+ "filename", "/tmp/filename.keyring",
+ NULL);
+
+ filename = gck_secret_collection_get_filename (other);
+ g_assert_cmpstr (filename, ==, "/tmp/filename.keyring");
+
+ g_object_unref (other);
+}
+
+DEFINE_TEST(secret_collection_set_filename)
+{
+ const gchar *filename;
+
+ gck_secret_collection_set_filename (collection, "/tmp/filename.keyring");
+
+ filename = gck_secret_collection_get_filename (collection);
+ g_assert_cmpstr (filename, ==, "/tmp/filename.keyring");
+}
+
+DEFINE_TEST(secret_collection_load_unlock_plain)
+{
+ GckAuthenticator *auth;
+ GckSecretData *sdata;
+ GckDataResult res;
+ gchar *filename;
+ CK_RV rv;
+
+ filename = g_build_filename (test_dir_testdata (), "plain.keyring", NULL);
+ gck_secret_collection_set_filename (collection, filename);
+ g_free (filename);
+
+ /* Load the data in the file */
+ res = gck_secret_collection_load (collection);
+ g_assert (res == GCK_DATA_SUCCESS);
+
+ /* Unlock the keyring, which should load again */
+ 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);
+
+ sdata = gck_secret_collection_unlocked_data (collection, session);
+ g_assert (sdata != NULL && GCK_IS_SECRET_DATA (sdata));
+ test_secret_collection_validate (collection, sdata);
+}
+
+DEFINE_TEST(secret_collection_load_unlock_encrypted)
+{
+ GckAuthenticator *auth;
+ GckSecretData *sdata;
+ GckDataResult res;
+ gchar *filename;
+ CK_RV rv;
+
+ filename = g_build_filename (test_dir_testdata (), "encrypted.keyring", NULL);
+ gck_secret_collection_set_filename (collection, filename);
+ g_free (filename);
+
+ /* Load the data in the file */
+ res = gck_secret_collection_load (collection);
+ g_assert (res == GCK_DATA_SUCCESS);
+
+ /* Unlock the keyring, which should load again */
+ rv = gck_authenticator_create (GCK_OBJECT (collection), (guchar*)"my-keyring-password", 19, &auth);
+ g_assert (rv == CKR_OK);
+ gck_session_add_session_object (session, NULL, GCK_OBJECT (auth));
+ g_object_unref (auth);
+
+ sdata = gck_secret_collection_unlocked_data (collection, session);
+ g_assert (sdata != NULL && GCK_IS_SECRET_DATA (sdata));
+ test_secret_collection_validate (collection, sdata);
+}
+
+DEFINE_TEST(secret_collection_load_unlock_bad_password)
+{
+ GckAuthenticator *auth;
+ GckDataResult res;
+ gchar *filename;
+ CK_RV rv;
+
+ filename = g_build_filename (test_dir_testdata (), "encrypted.keyring", NULL);
+ gck_secret_collection_set_filename (collection, filename);
+ g_free (filename);
+
+ /* Load the data in the file */
+ res = gck_secret_collection_load (collection);
+ g_assert (res == GCK_DATA_SUCCESS);
+
+ /* Unlock the keyring, which should load again */
+ rv = gck_authenticator_create (GCK_OBJECT (collection), (guchar*)"wrong", 5, &auth);
+ g_assert (rv == CKR_PIN_INCORRECT);
+}
+
+DEFINE_TEST(secret_collection_unlock_without_load)
+{
+ GckAuthenticator *auth;
+ GckSecretData *sdata;
+ gchar *filename;
+ CK_RV rv;
+
+ filename = g_build_filename (test_dir_testdata (), "encrypted.keyring", NULL);
+ gck_secret_collection_set_filename (collection, filename);
+ g_free (filename);
+
+ /* Unlock the keyring, which should load it */
+ rv = gck_authenticator_create (GCK_OBJECT (collection), (guchar*)"my-keyring-password", 19, &auth);
+ g_assert (rv == CKR_OK);
+ gck_session_add_session_object (session, NULL, GCK_OBJECT (auth));
+ g_object_unref (auth);
+
+ sdata = gck_secret_collection_unlocked_data (collection, session);
+ g_assert (sdata != NULL && GCK_IS_SECRET_DATA (sdata));
+ test_secret_collection_validate (collection, sdata);
+}
+
+DEFINE_TEST(secret_collection_twice_unlock)
+{
+ GckAuthenticator *auth;
+ GckSecretData *sdata;
+ gchar *filename;
+ CK_RV rv;
+
+ filename = g_build_filename (test_dir_testdata (), "encrypted.keyring", NULL);
+ gck_secret_collection_set_filename (collection, filename);
+ g_free (filename);
+
+ /* Unlock the keyring, which should load */
+ rv = gck_authenticator_create (GCK_OBJECT (collection), (guchar*)"my-keyring-password", 19, &auth);
+ g_assert (rv == CKR_OK);
+ gck_session_add_session_object (session, NULL, GCK_OBJECT (auth));
+ g_object_unref (auth);
+
+ /* Unlock the keyring again, which should not reload */
+ rv = gck_authenticator_create (GCK_OBJECT (collection), (guchar*)"my-keyring-password", 19, &auth);
+ g_assert (rv == CKR_OK);
+ gck_session_add_session_object (session, NULL, GCK_OBJECT (auth));
+ g_object_unref (auth);
+
+ sdata = gck_secret_collection_unlocked_data (collection, session);
+ g_assert (sdata != NULL && GCK_IS_SECRET_DATA (sdata));
+ test_secret_collection_validate (collection, sdata);
+}
+
+DEFINE_TEST(secret_collection_twice_unlock_bad_password)
+{
+ GckAuthenticator *auth;
+ GckSecretData *sdata;
+ gchar *filename;
+ CK_RV rv;
+
+ filename = g_build_filename (test_dir_testdata (), "encrypted.keyring", NULL);
+ gck_secret_collection_set_filename (collection, filename);
+ g_free (filename);
+
+ /* Unlock the keyring, which should load */
+ rv = gck_authenticator_create (GCK_OBJECT (collection), (guchar*)"my-keyring-password", 19, &auth);
+ g_assert (rv == CKR_OK);
+ gck_session_add_session_object (session, NULL, GCK_OBJECT (auth));
+ g_object_unref (auth);
+
+ /* Unlock the keyring again, wrong password */
+ rv = gck_authenticator_create (GCK_OBJECT (collection), (guchar*)"wrong", 5, &auth);
+ g_assert (rv == CKR_PIN_INCORRECT);
+
+ sdata = gck_secret_collection_unlocked_data (collection, session);
+ g_assert (sdata != NULL && GCK_IS_SECRET_DATA (sdata));
+ test_secret_collection_validate (collection, sdata);
+}
+
+DEFINE_TEST(secret_collection_memory_unlock)
+{
+ GckAuthenticator *auth;
+ GckDataResult res;
+ CK_RV rv;
+
+ /* Load the data in the file */
+ res = gck_secret_collection_load (collection);
+ g_assert (res == GCK_DATA_SUCCESS);
+
+ /* Unlock the keyring, which should load again */
+ 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_collection_memory_unlock_bad_password)
+{
+ GckAuthenticator *auth;
+ GckDataResult res;
+ CK_RV rv;
+
+ /* Load the data in the file */
+ res = gck_secret_collection_load (collection);
+ g_assert (res == GCK_DATA_SUCCESS);
+
+ /* Unlock the keyring, which should load again */
+ rv = gck_authenticator_create (GCK_OBJECT (collection), (guchar*)"wrong", 5, &auth);
+ g_assert (rv == CKR_PIN_INCORRECT);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]