[gnome-keyring/dbus-api] [secret-store] Add basic incomplete concpet of GckSecretData



commit 21dc1fc5a4dee83d2b67b040b503dfaad3062acb
Author: Stefan Walter <Stefan Walter>
Date:   Sat Aug 8 02:09:41 2009 +0000

    [secret-store] Add basic incomplete concpet of GckSecretData
    
    Secret data is the sensitive data in a keyring. This remains in
    memory as long as the collection/keyring is unlocked by some
    session.

 pkcs11/secret-store/Makefile.am             |    1 +
 pkcs11/secret-store/gck-secret-collection.c |   54 +++++--
 pkcs11/secret-store/gck-secret-collection.h |    8 +-
 pkcs11/secret-store/gck-secret-data.c       |  223 +++++++++++++++++++++++++++
 pkcs11/secret-store/gck-secret-data.h       |   74 +++++++++
 pkcs11/secret-store/gck-secret-types.h      |    1 +
 6 files changed, 347 insertions(+), 14 deletions(-)
---
diff --git a/pkcs11/secret-store/Makefile.am b/pkcs11/secret-store/Makefile.am
index aa13981..e56c31a 100644
--- a/pkcs11/secret-store/Makefile.am
+++ b/pkcs11/secret-store/Makefile.am
@@ -16,6 +16,7 @@ libgck_secret_store_la_SOURCES = \
 	gck-secret-binary.c gck-secret-binary.h \
 	gck-secret-collection.h gck-secret-collection.c \
 	gck-secret-compat.h gck-secret-compat.c \
+	gck-secret-data.h gck-secret-data.c \
 	gck-secret-fields.h gck-secret-fields.c \
 	gck-secret-item.h gck-secret-item.c \
 	gck-secret-module.h gck-secret-module.c \
diff --git a/pkcs11/secret-store/gck-secret-collection.c b/pkcs11/secret-store/gck-secret-collection.c
index ac31756..c440a63 100644
--- a/pkcs11/secret-store/gck-secret-collection.c
+++ b/pkcs11/secret-store/gck-secret-collection.c
@@ -23,6 +23,7 @@
 
 #include "gck-secret-binary.h"
 #include "gck-secret-collection.h"
+#include "gck-secret-data.h"
 #include "gck-secret-textual.h"
 
 #include "egg/egg-buffer.h"
@@ -33,13 +34,13 @@
 
 enum {
 	PROP_0,
+	PROP_DATA
 };
 
 struct _GckSecretCollection {
 	GckSecretObject parent;
-	GHashTable *secrets;
+	GckSecretData *data;
 	GList *items;
-	gchar *password;
 };
 
 static void gck_secret_collection_serializable (GckSerializableIface *iface);
@@ -72,7 +73,7 @@ gck_secret_collection_get_attribute (GckObject *base, GckSession *session, CK_AT
 static void
 gck_secret_collection_init (GckSecretCollection *self)
 {
-	self->secrets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+
 }
 
 static GObject*
@@ -88,10 +89,11 @@ static void
 gck_secret_collection_set_property (GObject *obj, guint prop_id, const GValue *value, 
                                     GParamSpec *pspec)
 {
-#if 0
 	GckSecretCollection *self = GCK_SECRET_COLLECTION (obj);
-#endif
 	switch (prop_id) {
+	case PROP_DATA:
+		gck_secret_collection_set_data (self, g_value_get_object (value));
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
 		break;
@@ -102,10 +104,11 @@ static void
 gck_secret_collection_get_property (GObject *obj, guint prop_id, GValue *value, 
                                     GParamSpec *pspec)
 {
-#if 0
 	GckSecretCollection *self = GCK_SECRET_COLLECTION (obj);
-#endif
 	switch (prop_id) {
+	case PROP_DATA:
+		g_value_set_object (value, gck_secret_collection_get_data (self));
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
 		break;
@@ -117,7 +120,7 @@ gck_secret_collection_dispose (GObject *obj)
 {
 	GckSecretCollection *self = GCK_SECRET_COLLECTION (obj);
 
-	g_hash_table_remove_all (self->secrets);
+	gck_secret_collection_set_data (self, NULL);
 
 	G_OBJECT_CLASS (gck_secret_collection_parent_class)->dispose (obj);
 }
@@ -127,9 +130,7 @@ gck_secret_collection_finalize (GObject *obj)
 {
 	GckSecretCollection *self = GCK_SECRET_COLLECTION (obj);
 
-	if (self->secrets)
-		g_hash_table_destroy (self->secrets);
-	self->secrets = NULL;
+	g_assert (self->data == NULL);
 
 	G_OBJECT_CLASS (gck_secret_collection_parent_class)->finalize (obj);
 }
@@ -149,6 +150,10 @@ gck_secret_collection_class_init (GckSecretCollectionClass *klass)
 	gobject_class->get_property = gck_secret_collection_get_property;
 
 	gck_class->get_attribute = gck_secret_collection_get_attribute;
+
+	g_object_class_install_property (gobject_class, PROP_DATA,
+	           g_param_spec_object ("data", "Data", "Secret Item Data",
+	                                GCK_TYPE_SECRET_DATA, G_PARAM_READWRITE));
 }
 
 static gboolean
@@ -179,10 +184,13 @@ 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);
 
+	g_assert (FALSE && "TODO: Must complete");
+#if 0
 	if (self->password == NULL)
 		res = gck_secret_textual_write (self, data, n_data);
 	else
 		res = gck_secret_binary_write (self, data, n_data);
+#endif
 
 	/* TODO: This doesn't transfer knowledge of 'no password' back up */
 	return (res == GCK_DATA_SUCCESS);
@@ -201,6 +209,7 @@ gck_secret_collection_serializable (GckSerializableIface *iface)
  * PUBLIC
  */
 
+#if 0
 GckSecret*
 gck_secret_collection_lookup_secret (GckSecretCollection *self,
                                      const gchar *identifier)
@@ -209,6 +218,7 @@ gck_secret_collection_lookup_secret (GckSecretCollection *self,
 	g_return_val_if_fail (identifier, NULL);
 	return g_hash_table_lookup (self->secrets, identifier);
 }
+#endif
 
 GList*
 gck_secret_collection_get_items (GckSecretCollection *self)
@@ -216,3 +226,25 @@ gck_secret_collection_get_items (GckSecretCollection *self)
 	g_return_val_if_fail (GCK_IS_SECRET_COLLECTION (self), NULL);
 	return g_list_copy (self->items);
 }
+
+GckSecretData*
+gck_secret_collection_get_data (GckSecretCollection *self)
+{
+	g_return_val_if_fail (GCK_IS_SECRET_COLLECTION (self), NULL);
+	return self->data;
+}
+
+void
+gck_secret_collection_set_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);
+	g_object_notify (G_OBJECT (self), "data");
+}
diff --git a/pkcs11/secret-store/gck-secret-collection.h b/pkcs11/secret-store/gck-secret-collection.h
index f91d121..6568a4e 100644
--- a/pkcs11/secret-store/gck-secret-collection.h
+++ b/pkcs11/secret-store/gck-secret-collection.h
@@ -60,9 +60,11 @@ GckSecretItem*       gck_secret_collection_create_item     (GckSecretCollection
 void                 gck_secret_collection_remove_item     (GckSecretCollection *self,
                                                             GckSecretItem *item);
 
-GckSecret*            gck_secret_collection_lookup_secret  (GckSecretCollection *self,
-                                                            const gchar *identifier);
+GckSecretData*       gck_secret_collection_get_data        (GckSecretCollection *self);
+
+void                 gck_secret_collection_set_data        (GckSecretCollection *self,
+                                                            GckSecretData *data);
 
-const gchar *        gck_secret_collection_get_master_password (GckSecretCollection *self);
+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
new file mode 100644
index 0000000..d1b4058
--- /dev/null
+++ b/pkcs11/secret-store/gck-secret-data.c
@@ -0,0 +1,223 @@
+/* 
+ * gnome-keyring
+ * 
+ * Copyright (C) 2009 Stefan Walter
+ * 
+ * This program is free software; you can redistribute it and/or modify 
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *  
+ * This program 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
+ * Lesser General Public License for more details.
+ *  
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include "config.h"
+
+#include "gck-secret-data.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;
+};
+
+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);
+}
+
+static void
+gck_secret_data_finalize (GObject *obj)
+{
+	GckSecretData *self = GCK_SECRET_DATA (obj);
+
+	if (self->secrets)
+		g_hash_table_destroy (self->secrets);
+	self->secrets = NULL;
+
+	gck_secret_data_clear_key (self);
+	
+	G_OBJECT_CLASS (gck_secret_data_parent_class)->finalize (obj);
+}
+
+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;
+}
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC
+ */
+
+const guchar*
+gck_secret_data_get_secret (GckSecretData *self, const gchar *identifier,
+                            gsize *n_secret)
+{
+	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;
+}
+
+void
+gck_secret_data_add_secret (GckSecretData *self, const gchar *identifier,
+                            const guchar *secret, gsize n_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));
+}
+
+void
+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)
+{
+	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;
+}
+
+void
+gck_secret_data_clear_key (GckSecretData *self)
+{
+	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;
+	
+	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;
+}
diff --git a/pkcs11/secret-store/gck-secret-data.h b/pkcs11/secret-store/gck-secret-data.h
new file mode 100644
index 0000000..54134b0
--- /dev/null
+++ b/pkcs11/secret-store/gck-secret-data.h
@@ -0,0 +1,74 @@
+/* 
+ * gnome-keyring
+ * 
+ * Copyright (C) 2009 Stefan Walter
+ * 
+ * This program is free software; you can redistribute it and/or modify 
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *  
+ * This program 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
+ * Lesser General Public License for more details.
+ *  
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __GCK_SECRET_DATA_H__
+#define __GCK_SECRET_DATA_H__
+
+#include <glib-object.h>
+
+#include "gck-secret-types.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))
+#define GCK_IS_SECRET_DATA(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCK_TYPE_SECRET_DATA))
+#define GCK_IS_SECRET_DATA_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GCK_TYPE_SECRET_DATA))
+#define GCK_SECRET_DATA_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GCK_TYPE_SECRET_DATA, GckSecretDataClass))
+
+typedef struct _GckSecretDataClass GckSecretDataClass;
+
+struct _GckSecretDataClass {
+	GObjectClass parent_class;
+};
+
+GType                gck_secret_data_get_type        (void);
+
+const guchar*        gck_secret_data_get_secret      (GckSecretData *self,
+                                                      const gchar *identifer,
+                                                      gsize *n_secret);
+
+void                 gck_secret_data_add_secret      (GckSecretData *self,
+                                                      const gchar *identifer,
+                                                      const guchar *secret,
+                                                      gsize n_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);
+
+void                 gck_secret_data_clear_key       (GckSecretData *self);
+
+gboolean             gck_secret_data_has_key         (GckSecretData *self);
+
+#endif /* __GCK_SECRET_DATA_H__ */
diff --git a/pkcs11/secret-store/gck-secret-types.h b/pkcs11/secret-store/gck-secret-types.h
index 603e128..923cd7f 100644
--- a/pkcs11/secret-store/gck-secret-types.h
+++ b/pkcs11/secret-store/gck-secret-types.h
@@ -23,6 +23,7 @@
 #define __GCK_SECRET_TYPES_H__
 
 typedef struct _GckSecretCollection GckSecretCollection;
+typedef struct _GckSecretData GckSecretData;
 typedef struct _GckSecretItem GckSecretItem;
 typedef struct _GckSecretObject GckSecretObject;
 typedef struct _GckSecretModule GckSecretModule;



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