[gnome-keyring/trust-store] [xdg-store] Implement writing of objects in xdg-store.



commit 390e1e37d332418d814282a8e26383312e920b19
Author: Stef Walter <stef memberwebs com>
Date:   Sun Sep 19 02:33:51 2010 +0000

    [xdg-store] Implement writing of objects in xdg-store.
    
    Implement writing of objects to disk in xdg-store.

 pkcs11/xdg-store/gkm-xdg-module.c |  169 ++++++++++++++++++++++++++++++++++++-
 pkcs11/xdg-store/gkm-xdg-trust.c  |   11 ++-
 2 files changed, 175 insertions(+), 5 deletions(-)
---
diff --git a/pkcs11/xdg-store/gkm-xdg-module.c b/pkcs11/xdg-store/gkm-xdg-module.c
index 1e7d81d..2147d90 100644
--- a/pkcs11/xdg-store/gkm-xdg-module.c
+++ b/pkcs11/xdg-store/gkm-xdg-module.c
@@ -25,10 +25,15 @@
 #include "gkm-xdg-store.h"
 #include "gkm-xdg-trust.h"
 
+#include "egg/egg-asn1x.h"
+#include "egg/egg-asn1-defs.h"
+#include "egg/egg-dn.h"
 #include "egg/egg-error.h"
+#include "egg/egg-hex.h"
 
 #include "gkm/gkm-file-tracker.h"
 #include "gkm/gkm-serializable.h"
+#include "gkm/gkm-transaction.h"
 #include "gkm/gkm-util.h"
 
 #include <string.h>
@@ -72,6 +77,8 @@ static const CK_TOKEN_INFO user_module_token_info = {
 
 #define UNUSED_VALUE (GUINT_TO_POINTER (1))
 
+#define UNWANTED_FILENAME_CHARS  ":/\\<>|\t\n\r\v "
+
 G_DEFINE_TYPE (GkmXdgModule, gkm_xdg_module, GKM_TYPE_MODULE);
 
 /* -----------------------------------------------------------------------------
@@ -110,6 +117,23 @@ type_from_path (const gchar *path)
 	return 0;
 }
 
+static const gchar*
+lookup_filename_for_object (GkmObject *object)
+{
+	return g_object_get_data (G_OBJECT (object), "xdg-module-filename");
+}
+
+static void
+add_object_to_module (GkmXdgModule *self, GkmObject *object, const gchar *filename)
+{
+	g_assert (!g_hash_table_lookup (self->objects_by_path, filename));
+	g_hash_table_insert (self->objects_by_path, g_strdup (filename), g_object_ref (object));
+
+	g_assert (!lookup_filename_for_object (object));
+	g_object_set_data_full (G_OBJECT (object), "xdg-module-filename",
+	                        g_strdup (filename), g_free);
+}
+
 static void
 file_load (GkmFileTracker *tracker, const gchar *path, GkmXdgModule *self)
 {
@@ -161,7 +185,7 @@ file_load (GkmFileTracker *tracker, const gchar *path, GkmXdgModule *self)
 	/* And load the data into it */
 	} else if (gkm_serializable_load (GKM_SERIALIZABLE (object), NULL, data, n_data)) {
 		if (added)
-			g_hash_table_insert (self->objects_by_path, g_strdup (path), g_object_ref (object));
+			add_object_to_module (self, object, path);
 		gkm_object_expose (object, TRUE);
 
 	} else {
@@ -181,6 +205,67 @@ file_remove (GkmFileTracker *tracker, const gchar *path, GkmXdgModule *self)
 	g_hash_table_remove (self->objects_by_path, path);
 }
 
+static gchar*
+name_for_subject (gconstpointer subject, gsize n_subject)
+{
+	GNode *asn;
+	gchar *name;
+
+	g_assert (subject);
+	g_assert (n_subject);
+
+	asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Name", subject, n_subject);
+	g_return_val_if_fail (asn, NULL);
+
+	name = egg_dn_read_part (egg_asn1x_node (asn, "rdnSequence", NULL), "CN");
+	egg_asn1x_destroy (asn);
+
+	return name;
+}
+
+static gchar*
+guess_basename_for_object (GkmObject *object)
+{
+	GkmSerializableIface *serial;
+	const gchar *ext;
+	gchar *filename;
+	gchar *name = NULL;
+	guchar *data;
+	gsize n_data;
+
+	g_assert (GKM_IS_OBJECT (object));
+	g_assert (GKM_IS_SERIALIZABLE (object));
+
+	/* Figure out the extension and prefix */
+	serial = GKM_SERIALIZABLE_GET_INTERFACE (object);
+	ext = serial->extension;
+	g_return_val_if_fail (ext, NULL);
+
+	/* First we try to use the CN of a subject */
+	data = gkm_object_get_attribute_data (object, NULL, CKA_SUBJECT, &n_data);
+	if (data && n_data)
+		name = name_for_subject (data, n_data);
+	g_free (data);
+
+	/* Next we try hex encoding the ID */
+	if (name == NULL) {
+		data = gkm_object_get_attribute_data (object, NULL, CKA_ID, &n_data);
+		if (data && n_data)
+			name = egg_hex_encode (data, n_data);
+		g_free (data);
+	}
+
+	if (name == NULL)
+		name = g_strdup_printf ("object-%08x", ABS (g_random_int ()));
+
+	/* Build up the identifier */
+	filename = g_strconcat (name, ext, NULL);
+	g_strdelimit (filename, UNWANTED_FILENAME_CHARS, '_');
+
+	g_free (name);
+	return filename;
+}
+
 /* -----------------------------------------------------------------------------
  * OBJECT
  */
@@ -218,6 +303,85 @@ gkm_xdg_module_real_refresh_token (GkmModule *base)
 	return CKR_OK;
 }
 
+static void
+gkm_xdg_module_real_add_token_object (GkmModule *module, GkmTransaction *transaction,
+                                      GkmObject *object)
+{
+	GkmXdgModule *self;
+	gchar *basename;
+	gchar *actual;
+	gchar *filename;
+
+	self = GKM_XDG_MODULE (module);
+
+	/* Double check that the object is in fact serializable */
+	if (!GKM_IS_SERIALIZABLE (object)) {
+		g_message ("can't store object of type '%s' on token", G_OBJECT_TYPE_NAME (object));
+		gkm_transaction_fail (transaction, CKR_TEMPLATE_INCONSISTENT);
+		return;
+	}
+
+	g_return_if_fail (lookup_filename_for_object (object) == NULL);
+
+	basename = guess_basename_for_object (object);
+	g_return_if_fail (basename);
+
+	actual = gkm_transaction_unique_file (transaction, self->directory, basename);
+	if (!gkm_transaction_get_failed (transaction)) {
+		filename = g_build_filename (self->directory, actual, NULL);
+		add_object_to_module (self, object, filename);
+		g_free (filename);
+	}
+
+	g_free (actual);
+	g_free (basename);
+}
+
+static void
+gkm_xdg_module_real_store_token_object (GkmModule *module, GkmTransaction *transaction,
+                                        GkmObject *object)
+{
+	GkmXdgModule *self = GKM_XDG_MODULE (module);
+	const gchar *filename;
+	gpointer data;
+	gsize n_data;
+
+	/* Double check that the object is in fact serializable */
+	if (!GKM_IS_SERIALIZABLE (object)) {
+		g_message ("can't store object of type '%s' on token", G_OBJECT_TYPE_NAME (object));
+		gkm_transaction_fail (transaction, CKR_TEMPLATE_INCONSISTENT);
+		return;
+	}
+
+	/* Serialize the object in question */
+	if (!gkm_serializable_save (GKM_SERIALIZABLE (object), NULL, &data, &n_data)) {
+		gkm_transaction_fail (transaction, CKR_FUNCTION_FAILED);
+		g_return_if_reached ();
+	}
+
+	filename = lookup_filename_for_object (object);
+	g_return_if_fail (filename != NULL);
+	g_return_if_fail (g_hash_table_lookup (self->objects_by_path, filename) == object);
+
+	gkm_transaction_write_file (transaction, filename, data, n_data);
+	g_free (data);
+}
+
+static void
+gkm_xdg_module_real_remove_token_object (GkmModule *module, GkmTransaction *transaction,
+                                         GkmObject *object)
+{
+	GkmXdgModule *self = GKM_XDG_MODULE (module);
+	const gchar *filename;
+
+	filename = lookup_filename_for_object (object);
+	g_return_if_fail (filename != NULL);
+	g_return_if_fail (g_hash_table_lookup (self->objects_by_path, filename) == object);
+
+	gkm_transaction_remove_file (transaction, filename);
+	g_hash_table_remove (self->objects_by_path, filename);
+}
+
 static GObject*
 gkm_xdg_module_constructor (GType type, guint n_props, GObjectConstructParam *props)
 {
@@ -291,6 +455,9 @@ gkm_xdg_module_class_init (GkmXdgModuleClass *klass)
 	module_class->get_token_info = gkm_xdg_module_real_get_token_info;
 	module_class->parse_argument = gkm_xdg_module_real_parse_argument;
 	module_class->refresh_token = gkm_xdg_module_real_refresh_token;
+	module_class->add_token_object = gkm_xdg_module_real_add_token_object;
+	module_class->store_token_object = gkm_xdg_module_real_store_token_object;
+	module_class->remove_token_object = gkm_xdg_module_real_remove_token_object;
 }
 
 /* ----------------------------------------------------------------------------
diff --git a/pkcs11/xdg-store/gkm-xdg-trust.c b/pkcs11/xdg-store/gkm-xdg-trust.c
index 89235d1..99d3d3d 100644
--- a/pkcs11/xdg-store/gkm-xdg-trust.c
+++ b/pkcs11/xdg-store/gkm-xdg-trust.c
@@ -51,7 +51,7 @@ extern const ASN1_ARRAY_TYPE xdg_asn1_tab[];
 
 static void gkm_xdg_trust_serializable (GkmSerializableIface *iface);
 
-G_DEFINE_TYPE_EXTENDED (GkmXdgTrust, gkm_xdg_trust, GKM_XDG_TYPE_TRUST, 0,
+G_DEFINE_TYPE_EXTENDED (GkmXdgTrust, gkm_xdg_trust, GKM_TYPE_OBJECT, 0,
                         G_IMPLEMENT_INTERFACE (GKM_TYPE_SERIALIZABLE, gkm_xdg_trust_serializable));
 
 enum {
@@ -163,7 +163,7 @@ trust_get_der (GkmXdgTrust *self, const gchar *part, CK_ATTRIBUTE_PTR attr)
 	node = egg_asn1x_node (self->pv->asn, "reference", "certReference", NULL);
 	g_return_val_if_fail (node, CKR_GENERAL_ERROR);
 
-	node = egg_asn1x_node (self->pv->asn, part, NULL);
+	node = egg_asn1x_node (node, part, NULL);
 	if (node == NULL)
 		return CKR_ATTRIBUTE_TYPE_INVALID;
 
@@ -349,7 +349,7 @@ factory_create_trust (GkmSession *session, GkmTransaction *transaction,
 	asn = egg_asn1x_create (xdg_asn1_tab, "trust-1");
 	g_return_val_if_fail (asn, NULL);
 
-	egg_asn1x_set_integer_as_raw (egg_asn1x_node (asn, "reference", "certReference", "serial", NULL),
+	egg_asn1x_set_integer_as_raw (egg_asn1x_node (asn, "reference", "certReference", "serialNumber", NULL),
 	                              g_memdup (serial->pValue, serial->ulValueLen),
 	                              serial->ulValueLen, g_free);
 
@@ -358,7 +358,7 @@ factory_create_trust (GkmSession *session, GkmTransaction *transaction,
 	                           issuer->ulValueLen, g_free);
 
 	if (subject)
-		egg_asn1x_set_raw_element (egg_asn1x_node (asn, "reference", "certReference", "issuer", NULL),
+		egg_asn1x_set_raw_element (egg_asn1x_node (asn, "reference", "certReference", "subject", NULL),
 		                           g_memdup (subject->pValue, issuer->ulValueLen),
 		                           issuer->ulValueLen, g_free);
 
@@ -468,6 +468,8 @@ gkm_xdg_trust_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE_
 		return gkm_attribute_set_bool (attr, CK_FALSE);
 	case CKA_CLASS:
 		return gkm_attribute_set_ulong (attr, CKO_NETSCAPE_TRUST);
+	case CKA_MODIFIABLE:
+		return gkm_attribute_set_bool (attr, CK_TRUE);
 
 	/* Key restrictions */
 	case CKA_TRUST_DIGITAL_SIGNATURE:
@@ -736,5 +738,6 @@ gkm_xdg_trust_get_factory (void)
 		factory_create_trust
 	};
 
+	init_quarks ();
 	return &factory;
 }



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