[gnome-keyring/dbus-api] [secret-store] Use GckSecret in GckSecretData.
- From: Stefan Walter <stefw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-keyring/dbus-api] [secret-store] Use GckSecret in GckSecretData.
- Date: Sat, 8 Aug 2009 03:24:01 +0000 (UTC)
commit 33eb206ab77e2bff56b5309184fa9eed92087a88
Author: Stef Walter <stef memberwebs com>
Date: Sat Aug 8 03:22:32 2009 +0000
[secret-store] Use GckSecret in GckSecretData.
Use GckSecret objects to hold master password and secrets in a
GckSecretData. Also change binary storage using GckSecret
to hold master password. Unit tests for GckSecretData.
pkcs11/secret-store/gck-secret-binary.c | 39 +++---
pkcs11/secret-store/gck-secret-binary.h | 5 +-
pkcs11/secret-store/gck-secret-collection.c | 25 +---
pkcs11/secret-store/gck-secret-collection.h | 2 -
pkcs11/secret-store/gck-secret-data.c | 153 ++++-----------------
pkcs11/secret-store/gck-secret-data.h | 35 ++----
pkcs11/secret-store/tests/Makefile.am | 3 +-
pkcs11/secret-store/tests/unit-test-secret-data.c | 93 +++++++++++++
8 files changed, 165 insertions(+), 190 deletions(-)
---
diff --git a/pkcs11/secret-store/gck-secret-binary.c b/pkcs11/secret-store/gck-secret-binary.c
index 6bcbbe1..d07a418 100644
--- a/pkcs11/secret-store/gck-secret-binary.c
+++ b/pkcs11/secret-store/gck-secret-binary.c
@@ -329,22 +329,23 @@ convert_to_integer (const gchar *string, guint32 *result)
*/
static gboolean
-encrypt_buffer (EggBuffer *buffer,
- const char *password,
- guchar salt[8],
- int iterations)
+encrypt_buffer (EggBuffer *buffer, GckSecret *master,
+ guchar salt[8], int iterations)
{
+ const gchar *password;
gcry_cipher_hd_t cih;
gcry_error_t gerr;
guchar *key, *iv;
+ gsize n_password;
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);
if (!egg_symkey_generate_simple (GCRY_CIPHER_AES128, GCRY_MD_SHA256,
- password, -1, salt, 8, iterations, &key, &iv))
+ password, n_password, salt, 8, iterations, &key, &iv))
return FALSE;
gerr = gcry_cipher_open (&cih, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, 0);
@@ -378,22 +379,23 @@ encrypt_buffer (EggBuffer *buffer,
}
static gboolean
-decrypt_buffer (EggBuffer *buffer,
- const char *password,
- guchar salt[8],
- int iterations)
+decrypt_buffer (EggBuffer *buffer, GckSecret *master,
+ guchar salt[8], int iterations)
{
+ const gchar *password;
gcry_cipher_hd_t cih;
gcry_error_t gerr;
guchar *key, *iv;
+ gsize n_password;
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);
if (!egg_symkey_generate_simple (GCRY_CIPHER_AES128, GCRY_MD_SHA256,
- password, -1, salt, 8, iterations, &key, &iv))
+ password, n_password, salt, 8, iterations, &key, &iv))
return FALSE;
gerr = gcry_cipher_open (&cih, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, 0);
@@ -554,10 +556,9 @@ generate_hashed_items (GckSecretCollection *collection, EggBuffer *buffer)
}
GckDataResult
-gck_secret_binary_write (GckSecretCollection *collection, guchar **data, gsize *n_data)
+gck_secret_binary_write (GckSecretCollection *collection, GckSecret *master,
+ guchar **data, gsize *n_data)
{
- guint flags;
- const gchar *password;
GckSecretObject *obj;
EggBuffer to_encrypt;
guchar digest[16];
@@ -565,6 +566,7 @@ gck_secret_binary_write (GckSecretCollection *collection, guchar **data, gsize *
gint hash_iterations;
gint lock_timeout;
guchar salt[8];
+ guint flags;
int i;
/* In case the world changes on us... */
@@ -624,8 +626,7 @@ gck_secret_binary_write (GckSecretCollection *collection, guchar **data, gsize *
(guchar*)to_encrypt.buf + 16, to_encrypt.len - 16);
memcpy (to_encrypt.buf, digest, 16);
- password = gck_secret_collection_get_master_password (collection);
- if (!encrypt_buffer (&to_encrypt, password, salt, hash_iterations)) {
+ if (!encrypt_buffer (&to_encrypt, master, salt, hash_iterations)) {
egg_buffer_uninit (&buffer);
egg_buffer_uninit (&to_encrypt);
return GCK_DATA_FAILURE;
@@ -754,7 +755,8 @@ free_item_info (ItemInfo *info)
}
gint
-gck_secret_binary_read (GckSecretCollection *collection, const guchar *data, gsize n_data)
+gck_secret_binary_read (GckSecretCollection *collection, GckSecret *master,
+ const guchar *data, gsize n_data)
{
gsize offset;
guchar major, minor, crypto, hash;
@@ -845,10 +847,9 @@ gck_secret_binary_read (GckSecretCollection *collection, const guchar *data, gsi
/* Copy the data into to_decrypt into non-pageable memory */
egg_buffer_init_static (&to_decrypt, buffer.buf + offset, crypto_size);
- password = gck_secret_collection_get_master_password (collection);
- if (password != NULL) {
+ if (master != NULL) {
- if (!decrypt_buffer (&to_decrypt, password, salt, hash_iterations))
+ if (!decrypt_buffer (&to_decrypt, master, salt, hash_iterations))
goto bail;
if (!verify_decrypted_buffer (&to_decrypt)) {
res = GCK_DATA_LOCKED;
diff --git a/pkcs11/secret-store/gck-secret-binary.h b/pkcs11/secret-store/gck-secret-binary.h
index f87c1d7..cfa66a8 100644
--- a/pkcs11/secret-store/gck-secret-binary.h
+++ b/pkcs11/secret-store/gck-secret-binary.h
@@ -25,12 +25,15 @@
#include "gck-secret-collection.h"
#include "gck/gck-data-types.h"
+#include "gck/gck-types.h"
-GckDataResult gck_secret_binary_read (GckSecretCollection *collection,
+GckDataResult gck_secret_binary_read (GckSecretCollection *collection,
+ GckSecret *master,
const guchar *data,
gsize n_data);
GckDataResult gck_secret_binary_write (GckSecretCollection *collection,
+ GckSecret *master,
guchar **data,
gsize *n_data);
diff --git a/pkcs11/secret-store/gck-secret-collection.c b/pkcs11/secret-store/gck-secret-collection.c
index c440a63..f88877d 100644
--- a/pkcs11/secret-store/gck-secret-collection.c
+++ b/pkcs11/secret-store/gck-secret-collection.c
@@ -166,7 +166,7 @@ gck_secret_collection_real_load (GckSerializable *base, GckSecret *login, const
g_return_val_if_fail (data, FALSE);
g_return_val_if_fail (n_data, FALSE);
- res = gck_secret_binary_read (self, data, n_data);
+ res = gck_secret_binary_read (self, login, data, n_data);
if (res == GCK_DATA_UNRECOGNIZED)
res = gck_secret_textual_read (self, data, n_data);
@@ -178,19 +178,21 @@ static gboolean
gck_secret_collection_real_save (GckSerializable *base, GckSecret *login, guchar **data, gsize *n_data)
{
GckSecretCollection *self = GCK_SECRET_COLLECTION (base);
+ GckSecret *master;
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);
- g_assert (FALSE && "TODO: Must complete");
-#if 0
- if (self->password == NULL)
+ if (!self->data)
+ g_return_val_if_reached (FALSE);
+
+ master = gck_secret_data_get_master (self->data);
+ if (master == NULL)
res = gck_secret_textual_write (self, data, n_data);
else
- res = gck_secret_binary_write (self, data, n_data);
-#endif
+ res = gck_secret_binary_write (self, master, data, n_data);
/* TODO: This doesn't transfer knowledge of 'no password' back up */
return (res == GCK_DATA_SUCCESS);
@@ -209,17 +211,6 @@ gck_secret_collection_serializable (GckSerializableIface *iface)
* PUBLIC
*/
-#if 0
-GckSecret*
-gck_secret_collection_lookup_secret (GckSecretCollection *self,
- const gchar *identifier)
-{
- g_return_val_if_fail (GCK_IS_SECRET_COLLECTION (self), NULL);
- g_return_val_if_fail (identifier, NULL);
- return g_hash_table_lookup (self->secrets, identifier);
-}
-#endif
-
GList*
gck_secret_collection_get_items (GckSecretCollection *self)
{
diff --git a/pkcs11/secret-store/gck-secret-collection.h b/pkcs11/secret-store/gck-secret-collection.h
index 6568a4e..b453c33 100644
--- a/pkcs11/secret-store/gck-secret-collection.h
+++ b/pkcs11/secret-store/gck-secret-collection.h
@@ -65,6 +65,4 @@ GckSecretData* gck_secret_collection_get_data (GckSecretCollection
void gck_secret_collection_set_data (GckSecretCollection *self,
GckSecretData *data);
-const gchar* gck_secret_collection_get_master_password (GckSecretCollection *self);
-
#endif /* __GCK_SECRET_COLLECTION_H__ */
diff --git a/pkcs11/secret-store/gck-secret-data.c b/pkcs11/secret-store/gck-secret-data.c
index d1b4058..b1862ed 100644
--- a/pkcs11/secret-store/gck-secret-data.c
+++ b/pkcs11/secret-store/gck-secret-data.c
@@ -23,72 +23,29 @@
#include "gck-secret-data.h"
+#include "gck/gck-secret.h"
+#include "gck/gck-util.h"
+
#include "egg/egg-secure-memory.h"
#include <glib/gi18n.h>
-enum {
- PROP_0,
-};
-
struct _GckSecretData {
GObject parent;
GHashTable *secrets;
- guint key_iterations;
- guchar *key_salt;
- gsize n_key_salt;
- guchar *key_encryption;
- gsize n_key_encryption;
+ GckSecret *master;
};
-typedef struct _Secret {
- guchar *data;
- gsize n_data;
-} Secret;
-
G_DEFINE_TYPE (GckSecretData, gck_secret_data, G_TYPE_OBJECT);
/* -----------------------------------------------------------------------------
- * INTERNAL
- */
-
-static void
-free_secret (gpointer data)
-{
- Secret *secret = data;
- egg_secure_clear (secret->data, secret->n_data);
- egg_secure_free (secret->data);
- g_slice_free (Secret, secret);
-}
-
-static Secret*
-new_secret (const guchar *data, gsize n_data)
-{
- Secret *secret = g_slice_new0 (Secret);
- secret->data = egg_secure_alloc (n_data);
- memcpy (secret->data, data, n_data);
- secret->n_data = n_data;
- return secret;
-}
-
-/* -----------------------------------------------------------------------------
* OBJECT
*/
static void
gck_secret_data_init (GckSecretData *self)
{
- self->secrets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, free_secret);
-}
-
-static void
-gck_secret_data_dispose (GObject *obj)
-{
- GckSecretData *self = GCK_SECRET_DATA (obj);
-
- g_hash_table_remove_all (self->secrets);
-
- G_OBJECT_CLASS (gck_secret_data_parent_class)->dispose (obj);
+ self->secrets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
}
static void
@@ -100,7 +57,9 @@ gck_secret_data_finalize (GObject *obj)
g_hash_table_destroy (self->secrets);
self->secrets = NULL;
- gck_secret_data_clear_key (self);
+ if (self->master)
+ g_object_unref (self->master);
+ self->master = NULL;
G_OBJECT_CLASS (gck_secret_data_parent_class)->finalize (obj);
}
@@ -109,10 +68,7 @@ static void
gck_secret_data_class_init (GckSecretDataClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
gck_secret_data_parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->dispose = gck_secret_data_dispose;
gobject_class->finalize = gck_secret_data_finalize;
}
@@ -120,33 +76,23 @@ gck_secret_data_class_init (GckSecretDataClass *klass)
* PUBLIC
*/
-const guchar*
-gck_secret_data_get_secret (GckSecretData *self, const gchar *identifier,
- gsize *n_secret)
+GckSecret*
+gck_secret_data_get_secret (GckSecretData *self, const gchar *identifier)
{
- Secret *secret;
-
g_return_val_if_fail (GCK_IS_SECRET_DATA (self), NULL);
g_return_val_if_fail (identifier, NULL);
- g_return_val_if_fail (n_secret, NULL);
-
- secret = g_hash_table_lookup (self->secrets, identifier);
- if (!secret)
- return NULL;
- *n_secret = secret->n_data;
- return secret->data;
+ return g_hash_table_lookup (self->secrets, identifier);
}
void
-gck_secret_data_add_secret (GckSecretData *self, const gchar *identifier,
- const guchar *secret, gsize n_secret)
+gck_secret_data_set_secret (GckSecretData *self, const gchar *identifier,
+ GckSecret *secret)
{
g_return_if_fail (GCK_IS_SECRET_DATA (self));
g_return_if_fail (identifier);
- g_return_if_fail (!secret || n_secret);
-
- g_hash_table_replace (self->secrets, g_strdup (identifier),
- new_secret (secret, n_secret));
+ g_return_if_fail (GCK_IS_SECRET (secret));
+ g_hash_table_replace (self->secrets, g_strdup (identifier),
+ g_object_ref (secret));
}
void
@@ -154,70 +100,25 @@ gck_secret_data_remove_secret (GckSecretData *self, const gchar *identifier)
{
g_return_if_fail (GCK_IS_SECRET_DATA (self));
g_return_if_fail (identifier);
-
g_hash_table_remove (self->secrets, identifier);
}
-
-void
-gck_secret_data_get_key (GckSecretData *self, const guchar **key,
- gsize *n_key, const guchar **salt,
- gsize *n_salt, guint *iterations)
-{
- g_return_if_fail (GCK_IS_SECRET_DATA (self));
- g_return_if_fail (key && n_key);
- g_return_if_fail (salt && n_salt);
- g_return_if_fail (iterations);
-
- *key = self->key_encryption;
- *n_key = self->n_key_encryption;
- *salt = self->key_salt;
- *n_salt = self->n_key_salt;
- *iterations = self->key_iterations;
-}
-
-void
-gck_secret_data_set_key (GckSecretData *self, const guchar *key,
- gsize n_key, const guchar *salt,
- gsize n_salt, guint iterations)
+GckSecret*
+gck_secret_data_get_master (GckSecretData *self)
{
- g_return_if_fail (GCK_IS_SECRET_DATA (self));
- g_return_if_fail (key);
- g_return_if_fail (salt);
-
- egg_secure_free (self->key_encryption);
- self->key_encryption = egg_secure_alloc (n_key);
- memcpy (self->key_encryption, key, n_key);
- self->n_key_encryption = n_key;
-
- g_free (self->key_salt);
- self->key_salt = g_malloc0 (n_salt);
- memcpy (self->key_salt, salt, n_salt);
- self->n_key_salt = n_salt;
-
- self->key_iterations = iterations;
+ g_return_val_if_fail (GCK_IS_SECRET_DATA (self), NULL);
+ return self->master;
}
void
-gck_secret_data_clear_key (GckSecretData *self)
+gck_secret_data_set_master (GckSecretData *self, GckSecret *master)
{
g_return_if_fail (GCK_IS_SECRET_DATA (self));
-
- self->key_iterations = 0;
-
- g_free (self->key_salt);
- self->key_salt = NULL;
- self->n_key_salt = 0;
+ g_return_if_fail (!master || GCK_IS_SECRET (master));
- egg_secure_clear (self->key_encryption, self->n_key_encryption);
- egg_secure_free (self->key_encryption);
- self->key_encryption = NULL;
- self->n_key_encryption = 0;
-}
-
-gboolean
-gck_secret_data_has_key (GckSecretData *self)
-{
- g_return_val_if_fail (GCK_IS_SECRET_DATA (self), FALSE);
- return self->key_encryption != NULL;
+ if (master)
+ g_object_ref (master);
+ if (self->master)
+ g_object_unref (self->master);
+ self->master = master;
}
diff --git a/pkcs11/secret-store/gck-secret-data.h b/pkcs11/secret-store/gck-secret-data.h
index 54134b0..48a3f0d 100644
--- a/pkcs11/secret-store/gck-secret-data.h
+++ b/pkcs11/secret-store/gck-secret-data.h
@@ -26,6 +26,8 @@
#include "gck-secret-types.h"
+#include "gck/gck-secret.h"
+
#define GCK_TYPE_SECRET_DATA (gck_secret_data_get_type ())
#define GCK_SECRET_DATA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCK_TYPE_SECRET_DATA, GckSecretData))
#define GCK_SECRET_DATA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCK_TYPE_SECRET_DATA, GckSecretDataClass))
@@ -41,34 +43,19 @@ struct _GckSecretDataClass {
GType gck_secret_data_get_type (void);
-const guchar* gck_secret_data_get_secret (GckSecretData *self,
- const gchar *identifer,
- gsize *n_secret);
+GckSecret* gck_secret_data_get_secret (GckSecretData *self,
+ const gchar *identifier);
-void gck_secret_data_add_secret (GckSecretData *self,
- const gchar *identifer,
- const guchar *secret,
- gsize n_secret);
+void gck_secret_data_set_secret (GckSecretData *self,
+ const gchar *identifier,
+ GckSecret *secret);
void gck_secret_data_remove_secret (GckSecretData *self,
- const gchar *identifer);
-
-void gck_secret_data_get_key (GckSecretData *self,
- const guchar **key,
- gsize *n_key,
- const guchar **salt,
- gsize *n_salt,
- guint *iterations);
-
-void gck_secret_data_set_key (GckSecretData *self,
- const guchar *key,
- gsize n_key,
- const guchar *salt,
- gsize n_salt,
- guint iterations);
+ const gchar *identifier);
-void gck_secret_data_clear_key (GckSecretData *self);
+GckSecret* gck_secret_data_get_master (GckSecretData *self);
-gboolean gck_secret_data_has_key (GckSecretData *self);
+void gck_secret_data_set_master (GckSecretData *self,
+ GckSecret *master);
#endif /* __GCK_SECRET_DATA_H__ */
diff --git a/pkcs11/secret-store/tests/Makefile.am b/pkcs11/secret-store/tests/Makefile.am
index d91d4be..5ccc28b 100644
--- a/pkcs11/secret-store/tests/Makefile.am
+++ b/pkcs11/secret-store/tests/Makefile.am
@@ -1,5 +1,6 @@
UNIT_AUTO = \
- unit-test-secret-compat.c
+ unit-test-secret-compat.c \
+ unit-test-secret-data.c
UNIT_PROMPT =
diff --git a/pkcs11/secret-store/tests/unit-test-secret-data.c b/pkcs11/secret-store/tests/unit-test-secret-data.c
new file mode 100644
index 0000000..7460b46
--- /dev/null
+++ b/pkcs11/secret-store/tests/unit-test-secret-data.c
@@ -0,0 +1,93 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* unit-test-secret-compat.c: Test secret compat files
+
+ Copyright (C) 2008 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 "gck-secret-data.h"
+
+#include <glib.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+DEFINE_TEST(secret_data_new)
+{
+ GckSecretData *data = g_object_new (GCK_TYPE_SECRET_DATA, NULL);
+ g_assert (GCK_IS_SECRET_DATA (data));
+ g_object_unref (data);
+}
+
+DEFINE_TEST(secret_data_get_set)
+{
+ GckSecretData *data = g_object_new (GCK_TYPE_SECRET_DATA, NULL);
+ GckSecret *secret = gck_secret_new_from_password ("barn");
+ GckSecret *check;
+
+ gck_secret_data_set_secret (data, "my-identifier", secret);
+ g_object_unref (secret);
+
+ check = gck_secret_data_get_secret (data, "my-identifier");
+ g_assert (GCK_IS_SECRET (check));
+ g_assert (secret == check);
+ g_assert (gck_secret_equals (check, (guchar*)"barn", -1));
+
+ g_object_unref (data);
+}
+
+DEFINE_TEST(secret_data_remove)
+{
+ GckSecretData *data = g_object_new (GCK_TYPE_SECRET_DATA, NULL);
+ GckSecret *secret = gck_secret_new_from_password ("barn");
+
+ gck_secret_data_set_secret (data, "my-identifier", secret);
+ g_object_unref (secret);
+
+ secret = gck_secret_data_get_secret (data, "my-identifier");
+ g_assert (GCK_IS_SECRET (secret));
+
+ gck_secret_data_remove_secret (data, "my-identifier");
+ secret = gck_secret_data_get_secret (data, "my-identifier");
+ g_assert (!secret);
+
+ g_object_unref (data);
+}
+
+DEFINE_TEST(secret_data_get_set_master)
+{
+ GckSecretData *data = g_object_new (GCK_TYPE_SECRET_DATA, NULL);
+ GckSecret *master = gck_secret_new_from_password ("master");
+ GckSecret *check;
+
+ gck_secret_data_set_master (data, master);
+ g_object_unref (master);
+
+ check = gck_secret_data_get_master (data);
+ g_assert (GCK_IS_SECRET (check));
+ g_assert (master == check);
+ g_assert (gck_secret_equals (check, (guchar*)"master", -1));
+
+ g_object_unref (data);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]