[gnome-keyring/trust-store] [xdg-store] Implement writing of objects in xdg-store.
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-keyring/trust-store] [xdg-store] Implement writing of objects in xdg-store.
- Date: Sun, 19 Sep 2010 02:34:59 +0000 (UTC)
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]