[gcr] gck: Rename GckObjectAttributes to GckObjectCache
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gcr] gck: Rename GckObjectAttributes to GckObjectCache
- Date: Thu, 8 Dec 2011 20:23:49 +0000 (UTC)
commit 55961a2887b5636c256367a3013c662adccf5928
Author: Stef Walter <stefw collabora co uk>
Date: Thu Dec 8 14:30:23 2011 +0100
gck: Rename GckObjectAttributes to GckObjectCache
* And allow updating of the attributes, in particula adding
attributes that are discovered.
* Add a gck_object_cache_lookup() methods which load attributes
and then updates the cache if the object has a cache.
docs/reference/gck/gck.types | 2 +-
gck/Makefile.am | 2 +-
gck/gck-enumerator.c | 10 +-
gck/gck-object-attributes.c | 111 -----------
gck/gck-object-cache.c | 352 +++++++++++++++++++++++++++++++++++
gck/gck.h | 70 ++++++--
gck/gck.symbols | 13 +-
gck/tests/test-gck-enumerator.c | 27 ++-
gcr/gcr-key-mechanisms.c | 23 +--
gcr/gcr-key-renderer.c | 146 +++++++++++++--
gcr/gcr-subject-public-key.c | 52 ++++--
gcr/tests/test-subject-public-key.c | 27 +++-
12 files changed, 636 insertions(+), 199 deletions(-)
---
diff --git a/docs/reference/gck/gck.types b/docs/reference/gck/gck.types
index 773f02a..a1a8375 100644
--- a/docs/reference/gck/gck.types
+++ b/docs/reference/gck/gck.types
@@ -10,6 +10,6 @@ gck_slot_get_type
gck_session_info_get_type
gck_session_get_type
gck_object_get_type
-gck_object_attributes_get_type
+gck_object_cache_get_type
gck_password_get_type
gck_uri_data_get_type
diff --git a/gck/Makefile.am b/gck/Makefile.am
index aab5feb..b761819 100644
--- a/gck/Makefile.am
+++ b/gck/Makefile.am
@@ -41,7 +41,7 @@ PUBLIC_FILES = \
gck-module.c \
gck-modules.c \
gck-object.c \
- gck-object-attributes.c \
+ gck-object-cache.c \
gck-password.c \
gck-session.c \
gck-slot.c \
diff --git a/gck/gck-enumerator.c b/gck/gck-enumerator.c
index 0d37e7b..4e60f71 100644
--- a/gck/gck-enumerator.c
+++ b/gck/gck-enumerator.c
@@ -86,7 +86,7 @@ struct _GckEnumeratorState {
/* The type of objects to create */
GType object_type;
gpointer object_class;
- GckObjectAttributesIface *object_iface;
+ GckObjectCacheIface *object_iface;
/* state_slots */
GList *slots;
@@ -511,15 +511,15 @@ state_results (GckEnumeratorState *args,
}
/* If no request for attributes, just go forward */
- if (args->object_iface == NULL || args->object_iface->n_attribute_types == 0) {
+ if (args->object_iface == NULL || args->object_iface->n_default_types == 0) {
g_queue_push_tail (args->results, result);
continue;
}
gck_builder_init (&builder);
- for (i = 0; i < args->object_iface->n_attribute_types; ++i)
- gck_builder_add_empty (&builder, args->object_iface->attribute_types[i]);
+ for (i = 0; i < args->object_iface->n_default_types; ++i)
+ gck_builder_add_empty (&builder, args->object_iface->default_types[i]);
/* Ask for attribute sizes */
template = _gck_builder_prepare_in (&builder, &n_template);
@@ -1046,7 +1046,7 @@ check_out_enumerator_state (GckEnumerator *self)
state->object_class = g_type_class_peek (state->object_type);
g_assert (state->object_class == self->pv->object_class);
state->object_iface = g_type_interface_peek (state->object_class,
- GCK_TYPE_OBJECT_ATTRIBUTES);
+ GCK_TYPE_OBJECT_CACHE);
g_type_class_ref (state->object_type);
}
diff --git a/gck/gck-object-cache.c b/gck/gck-object-cache.c
new file mode 100644
index 0000000..38b912e
--- /dev/null
+++ b/gck/gck-object-cache.c
@@ -0,0 +1,352 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gck-object-cache.c - the GObject PKCS#11 wrapper library
+
+ Copyright (C) 2011 Collabora Ltd.
+
+ 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 <stefw collabora co uk>
+*/
+
+#include "config.h"
+
+#include "gck.h"
+#include "gck-private.h"
+
+#include <string.h>
+
+/**
+ * SECTION:gck-object-cache
+ * @title: GckObjectCache
+ * @short_description: An interface which holds attributes for a PKCS\#11 object
+ *
+ * #GckObjectCache is an interface implemented by derived classes of
+ * #GckObject to indicate which attributes they'd like an enumerator to retrieve.
+ * These attributes are then cached on the object and can be retrieved through
+ * the #GckObjectCache:attributes property.
+ */
+
+/**
+ * GckObjectCacheIface:
+ * @interface: parent interface
+ * @default_types: (array length=n_default_types): attribute types that an
+ * enumerator should retrieve
+ * @n_default_types: number of attribute types to be retrieved
+ *
+ * Interface for #GckObjectCache. If the @default_types field is set by
+ * a implementing class, then the a #GckEnumerator which has been setup using
+ * gck_enumerator_set_object_type()
+ */
+
+typedef GckObjectCacheIface GckObjectCacheInterface;
+G_DEFINE_INTERFACE (GckObjectCache, gck_object_cache, GCK_TYPE_OBJECT);
+
+static void
+gck_object_cache_default_init (GckObjectCacheIface *iface)
+{
+ static volatile gsize initialized = 0;
+ if (g_once_init_enter (&initialized)) {
+
+ /**
+ * GckObjectCache:attributes:
+ *
+ * The attributes cached on this object.
+ */
+ g_object_interface_install_property (iface,
+ g_param_spec_boxed ("attributes", "Attributes", "PKCS#11 Attributes",
+ GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ g_once_init_leave (&initialized, 1);
+ }
+}
+
+/**
+ * gck_object_cache_get_attributes:
+ * @object: an object with attributes
+ *
+ * Gets the attributes cached on this object.
+ *
+ * Returns: (transfer full) (allow-none): the attributes
+ */
+GckAttributes *
+gck_object_cache_get_attributes (GckObjectCache *object)
+{
+ GckAttributes *attributes = NULL;
+ g_return_val_if_fail (GCK_IS_OBJECT_CACHE (object), NULL);
+ g_object_get (object, "attributes", &attributes, NULL);
+ return attributes;
+}
+
+void
+gck_object_cache_set_attributes (GckObjectCache *object,
+ GckAttributes *attributes)
+{
+ g_return_if_fail (GCK_IS_OBJECT_CACHE (object));
+
+ gck_attributes_ref_sink (attributes);
+ g_object_set (object, "attributes", attributes, NULL);
+ gck_attributes_unref (attributes);
+}
+
+/**
+ * gck_object_cache_add_attributes:
+ * @object: an object with attributes
+ * @attributes: the attributes to cache
+ *
+ * Adds the attributes to the set cached on this object.
+ */
+void
+gck_object_cache_add_attributes (GckObjectCache *object,
+ GckAttributes *attributes)
+{
+ GckObjectCacheIface *iface;
+
+ g_return_if_fail (GCK_IS_OBJECT_CACHE (object));
+ g_return_if_fail (attributes != NULL);
+
+ iface = GCK_OBJECT_CACHE_GET_INTERFACE (object);
+ g_return_if_fail (iface->add_attributes != NULL);
+
+ gck_attributes_ref_sink (attributes);
+ (iface->add_attributes) (object, attributes);
+ gck_attributes_unref (attributes);
+}
+
+gboolean
+gck_object_cache_update (GckObjectCache *object,
+ const gulong *attr_types,
+ gint n_attr_types,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GckObjectCacheIface *iface;
+ GckAttributes *attrs;
+
+ g_return_val_if_fail (GCK_IS_OBJECT_CACHE (object), FALSE);
+ g_return_val_if_fail (attr_types != NULL || n_attr_types == 0, FALSE);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ iface = GCK_OBJECT_CACHE_GET_INTERFACE (object);
+
+ if (attr_types == NULL) {
+ attr_types = iface->default_types;
+ n_attr_types = iface->n_default_types;
+
+ if (attr_types == NULL || n_attr_types == 0) {
+ g_warning ("no attribute types passed to gck_object_cache_update() "
+ "and no default types on object.");
+ return FALSE;
+ }
+ }
+
+ attrs = gck_object_get_full (GCK_OBJECT (object),
+ attr_types, n_attr_types,
+ cancellable, error);
+
+ if (attrs != NULL) {
+ gck_object_cache_add_attributes (object, attrs);
+ gck_attributes_unref (attrs);
+ }
+
+ return attrs != NULL;
+}
+
+static void
+on_cache_object_get (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+ GckAttributes *attrs;
+ GError *error = NULL;
+
+ attrs = gck_object_get_finish (GCK_OBJECT (source), result, &error);
+ if (error == NULL) {
+ gck_object_cache_add_attributes (GCK_OBJECT_CACHE (source), attrs);
+ gck_attributes_unref (attrs);
+ } else {
+ g_simple_async_result_take_error (res, error);
+ }
+
+ g_simple_async_result_complete (res);
+ g_object_unref (res);
+}
+void
+gck_object_cache_update_async (GckObjectCache *object,
+ const gulong *attr_types,
+ gint n_attr_types,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GckObjectCacheIface *iface;
+ GSimpleAsyncResult *res;
+
+ g_return_if_fail (GCK_IS_OBJECT_CACHE (object));
+ g_return_if_fail (attr_types != NULL || n_attr_types == 0);
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+ iface = GCK_OBJECT_CACHE_GET_INTERFACE (object);
+
+ if (attr_types == NULL) {
+ attr_types = iface->default_types;
+ n_attr_types = iface->n_default_types;
+
+ if (attr_types == NULL || n_attr_types == 0) {
+ g_warning ("no attribute types passed to gck_object_cache_update_async() "
+ "and no default types on object.");
+ return;
+ }
+ }
+
+ res = g_simple_async_result_new (G_OBJECT (object), callback, user_data,
+ gck_object_cache_update_async);
+
+ gck_object_get_async (GCK_OBJECT (object), attr_types, n_attr_types,
+ cancellable, on_cache_object_get, g_object_ref (res));
+
+ g_object_unref (res);
+}
+
+gboolean
+gck_object_cache_update_finish (GckObjectCache *object,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (GCK_IS_OBJECT_CACHE (object), FALSE);
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (object),
+ gck_object_cache_update_async), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+check_have_attributes (GckAttributes *attrs,
+ const gulong *attr_types,
+ gint n_attr_types)
+{
+ gint i;
+
+ if (attrs == NULL)
+ return FALSE;
+
+ for (i = 0; i < n_attr_types; i++) {
+ if (!gck_attributes_find (attrs, attr_types[i]))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+GckAttributes *
+gck_object_cache_lookup (GckObject *object,
+ const gulong *attr_types,
+ gint n_attr_types,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GckAttributes *attrs;
+ GckObjectCache *cache;
+
+ g_return_val_if_fail (GCK_IS_OBJECT (object), NULL);
+ g_return_val_if_fail (attr_types != NULL || n_attr_types == 0, NULL);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ if (GCK_IS_OBJECT_CACHE (object)) {
+ cache = GCK_OBJECT_CACHE (object);
+ attrs = gck_object_cache_get_attributes (cache);
+ if (check_have_attributes (attrs, attr_types, n_attr_types))
+ return attrs;
+ gck_attributes_unref (attrs);
+
+ if (!gck_object_cache_update (cache, attr_types, n_attr_types,
+ cancellable, error))
+ return NULL;
+
+ return gck_object_cache_get_attributes (cache);
+
+ } else {
+ return gck_object_get_full (object, attr_types, n_attr_types,
+ cancellable, error);
+ }
+}
+
+void
+gck_object_cache_lookup_async (GckObject *object,
+ const gulong *attr_types,
+ gint n_attr_types,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+ GckAttributes *attrs;
+ GckObjectCache *cache;
+ gboolean have;
+
+ g_return_if_fail (GCK_IS_OBJECT (object));
+ g_return_if_fail (attr_types != NULL || n_attr_types == 0);
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+ if (GCK_IS_OBJECT_CACHE (object)) {
+ cache = GCK_OBJECT_CACHE (object);
+ attrs = gck_object_cache_get_attributes (cache);
+ have = check_have_attributes (attrs, attr_types, n_attr_types);
+ gck_attributes_unref (attrs);
+
+ if (have) {
+ res = g_simple_async_result_new (G_OBJECT (cache), callback, user_data,
+ gck_object_cache_lookup_async);
+ g_simple_async_result_complete_in_idle (res);
+ g_object_unref (res);
+ } else {
+ gck_object_cache_update_async (cache, attr_types, n_attr_types,
+ cancellable, callback, user_data);
+ }
+ } else {
+ gck_object_get_async (object, attr_types, n_attr_types, cancellable,
+ callback, user_data);
+ }
+}
+
+GckAttributes *
+gck_object_cache_lookup_finish (GckObject *object,
+ GAsyncResult *result,
+ GError **error)
+{
+ GckObjectCache *cache;
+
+ g_return_val_if_fail (GCK_IS_OBJECT (object), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ if (GCK_IS_OBJECT_CACHE (object)) {
+ cache = GCK_OBJECT_CACHE (object);
+ if (!g_simple_async_result_is_valid (result, G_OBJECT (object),
+ gck_object_cache_lookup_async))
+ if (!gck_object_cache_update_finish (cache, result, error))
+ return NULL;
+ return gck_object_cache_get_attributes (cache);
+ } else {
+
+ return gck_object_get_finish (object, result, error);
+ }
+}
diff --git a/gck/gck.h b/gck/gck.h
index c4a5bbf..c0f67dd 100644
--- a/gck/gck.h
+++ b/gck/gck.h
@@ -386,7 +386,7 @@ typedef struct _GckSlot GckSlot;
typedef struct _GckModule GckModule;
typedef struct _GckSession GckSession;
typedef struct _GckObject GckObject;
-typedef struct _GckObjectAttributes GckObjectAttributes;
+typedef struct _GckObjectCache GckObjectCache;
typedef struct _GckEnumerator GckEnumerator;
typedef struct _GckUriData GckUriData;
@@ -1392,29 +1392,69 @@ GckAttributes* gck_object_get_template_finish (GckObject *self,
* OBJECT ATTRIBUTES
*/
-#define GCK_TYPE_OBJECT_ATTRIBUTES (gck_object_attributes_get_type ())
-#define GCK_OBJECT_ATTRIBUTES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCK_TYPE_OBJECT_ATTRIBUTES, GckObjectAttributes))
-#define GCK_IS_OBJECT_ATTRIBUTES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCK_TYPE_OBJECT_ATTRIBUTES))
-#define GCK_OBJECT_ATTRIBUTES_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GCK_TYPE_OBJECT_ATTRIBUTES, GckObjectAttributesIface))
+#define GCK_TYPE_OBJECT_CACHE (gck_object_cache_get_type ())
+#define GCK_OBJECT_CACHE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCK_TYPE_OBJECT_CACHE, GckObjectCache))
+#define GCK_IS_OBJECT_CACHE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCK_TYPE_OBJECT_CACHE))
+#define GCK_OBJECT_CACHE_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GCK_TYPE_OBJECT_CACHE, GckObjectCacheIface))
-typedef struct _GckObjectAttributesIface GckObjectAttributesIface;
+typedef struct _GckObjectCacheIface GckObjectCacheIface;
-struct _GckObjectAttributesIface {
+struct _GckObjectCacheIface {
GTypeInterface interface;
- const gulong *attribute_types;
- gint n_attribute_types;
+ const gulong * default_types;
+ gint n_default_types;
+
+ void (* add_attributes) (GckObjectCache *object,
+ GckAttributes *attributes);
/*< private >*/
gpointer reserved[6];
};
-GType gck_object_attributes_get_type (void) G_GNUC_CONST;
-
-GckAttributes * gck_object_attributes_get_attributes (GckObjectAttributes *object);
-
-void gck_object_attributes_set_attributes (GckObjectAttributes *object,
- GckAttributes *attributes);
+GType gck_object_cache_get_type (void) G_GNUC_CONST;
+
+GckAttributes * gck_object_cache_get_attributes (GckObjectCache *object);
+
+void gck_object_cache_set_attributes (GckObjectCache *object,
+ GckAttributes *attributes);
+
+void gck_object_cache_add_attributes (GckObjectCache *object,
+ GckAttributes *attributes);
+
+gboolean gck_object_cache_update (GckObjectCache *object,
+ const gulong *attr_types,
+ gint n_attr_types,
+ GCancellable *cancellable,
+ GError **error);
+
+void gck_object_cache_update_async (GckObjectCache *object,
+ const gulong *attr_types,
+ gint n_attr_types,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gboolean gck_object_cache_update_finish (GckObjectCache *object,
+ GAsyncResult *result,
+ GError **error);
+
+GckAttributes * gck_object_cache_lookup (GckObject *object,
+ const gulong *attr_types,
+ gint n_attr_types,
+ GCancellable *cancellable,
+ GError **error);
+
+void gck_object_cache_lookup_async (GckObject *object,
+ const gulong *attr_types,
+ gint n_attr_types,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+GckAttributes * gck_object_cache_lookup_finish (GckObject *object,
+ GAsyncResult *result,
+ GError **error);
/* ------------------------------------------------------------------------
* PASSWORD
diff --git a/gck/gck.symbols b/gck/gck.symbols
index 9cd3f94..6258dee 100644
--- a/gck/gck.symbols
+++ b/gck/gck.symbols
@@ -131,9 +131,16 @@ gck_modules_object_for_uri
gck_modules_objects_for_uri
gck_modules_token_for_uri
gck_modules_tokens_for_uri
-gck_object_attributes_get_attributes
-gck_object_attributes_get_type
-gck_object_attributes_set_attributes
+gck_object_cache_add_attributes
+gck_object_cache_get_attributes
+gck_object_cache_get_type
+gck_object_cache_lookup
+gck_object_cache_lookup_async
+gck_object_cache_lookup_finish
+gck_object_cache_set_attributes
+gck_object_cache_update
+gck_object_cache_update_async
+gck_object_cache_update_finish
gck_object_destroy
gck_object_destroy_async
gck_object_destroy_finish
diff --git a/gck/tests/test-gck-enumerator.c b/gck/tests/test-gck-enumerator.c
index 7c3a429..1ed1ab5 100644
--- a/gck/tests/test-gck-enumerator.c
+++ b/gck/tests/test-gck-enumerator.c
@@ -404,15 +404,15 @@ typedef struct {
} MockObjectClass;
GType mock_object_get_type (void) G_GNUC_CONST;
-static void mock_object_attributes_init (GckObjectAttributesIface *iface);
+static void mock_object_cache_init (GckObjectCacheIface *iface);
#define MOCK_TYPE_OBJECT (mock_object_get_type())
#define MOCK_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), MOCK_TYPE_OBJECT, MockObject))
#define MOCK_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), MOCK_TYPE_OBJECT))
G_DEFINE_TYPE_WITH_CODE (MockObject, mock_object, GCK_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GCK_TYPE_OBJECT_ATTRIBUTES,
- mock_object_attributes_init);
+ G_IMPLEMENT_INTERFACE (GCK_TYPE_OBJECT_CACHE,
+ mock_object_cache_init);
);
static void
@@ -480,10 +480,25 @@ mock_object_class_init (MockObjectClass *klass)
}
static void
-mock_object_attributes_init (GckObjectAttributesIface *iface)
+mock_object_add_attributes (GckObjectCache *object,
+ GckAttributes *attrs)
{
- iface->attribute_types = mock_attribute_types;
- iface->n_attribute_types = G_N_ELEMENTS (mock_attribute_types);
+ GckBuilder builder = GCK_BUILDER_INIT;
+ MockObject *self = MOCK_OBJECT (object);
+
+ gck_builder_add_all (&builder, self->attrs);
+ gck_builder_set_all (&builder, attrs);
+
+ gck_attributes_unref (self->attrs);
+ self->attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
+}
+
+static void
+mock_object_cache_init (GckObjectCacheIface *iface)
+{
+ iface->default_types = mock_attribute_types;
+ iface->n_default_types = G_N_ELEMENTS (mock_attribute_types);
+ iface->add_attributes = mock_object_add_attributes;
}
static void
diff --git a/gcr/gcr-key-mechanisms.c b/gcr/gcr-key-mechanisms.c
index 8728323..b21ccbb 100644
--- a/gcr/gcr-key-mechanisms.c
+++ b/gcr/gcr-key-mechanisms.c
@@ -97,8 +97,8 @@ _gcr_key_mechanisms_check (GckObject *key,
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), GCK_INVALID);
g_return_val_if_fail (error == NULL || *error == NULL, GCK_INVALID);
- if (GCK_IS_OBJECT_ATTRIBUTES (key)) {
- attrs = gck_object_attributes_get_attributes (GCK_OBJECT_ATTRIBUTES (key));
+ if (GCK_IS_OBJECT_CACHE (key)) {
+ attrs = gck_object_cache_get_attributes (GCK_OBJECT_CACHE (key));
if (!check_have_attributes (attrs, attr_types, G_N_ELEMENTS (attr_types))) {
gck_attributes_unref (attrs);
attrs = NULL;
@@ -143,7 +143,7 @@ on_check_get_attributes (GObject *source,
CheckClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
GError *error = NULL;
- closure->attrs = gck_object_get_finish (GCK_OBJECT (source), result, &error);
+ closure->attrs = gck_object_cache_lookup_finish (GCK_OBJECT (source), result, &error);
if (error != NULL)
g_simple_async_result_take_error (res, error);
@@ -163,7 +163,6 @@ _gcr_key_mechanisms_check_async (GckObject *key,
gulong attr_types[] = { action_attr_type };
CheckClosure *closure;
GSimpleAsyncResult *res;
- GckAttributes *attrs;
g_return_if_fail (GCK_IS_OBJECT (key));
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
@@ -176,20 +175,8 @@ _gcr_key_mechanisms_check_async (GckObject *key,
closure->action_attr_type = action_attr_type;
g_simple_async_result_set_op_res_gpointer (res, closure, check_closure_free);
- if (GCK_IS_OBJECT_ATTRIBUTES (key)) {
- attrs = gck_object_attributes_get_attributes (GCK_OBJECT_ATTRIBUTES (key));
- if (check_have_attributes (attrs, attr_types, G_N_ELEMENTS (attr_types))) {
- g_simple_async_result_set_op_res_gpointer (res, attrs, gck_attributes_unref);
- g_simple_async_result_complete_in_idle (res);
- g_object_unref (res);
- return;
- }
-
- gck_attributes_unref (attrs);
- }
-
- gck_object_get_async (key, attr_types, G_N_ELEMENTS (attr_types),
- cancellable, on_check_get_attributes, g_object_ref (res));
+ gck_object_cache_lookup_async (key, attr_types, G_N_ELEMENTS (attr_types),
+ cancellable, on_check_get_attributes, g_object_ref (res));
g_object_unref (res);
diff --git a/gcr/gcr-key-renderer.c b/gcr/gcr-key-renderer.c
index 333c719..0bfb2c7 100644
--- a/gcr/gcr-key-renderer.c
+++ b/gcr/gcr-key-renderer.c
@@ -24,10 +24,14 @@
#include "gcr-fingerprint.h"
#include "gcr-icons.h"
#include "gcr-renderer.h"
+#include "gcr-subject-public-key.h"
#include "gcr-viewer.h"
#include "gck/gck.h"
+#include "egg/egg-asn1x.h"
+#include "egg/egg-bytes.h"
+
#include <gdk/gdk.h>
#include <glib/gi18n-lib.h>
@@ -47,14 +51,18 @@
enum {
PROP_0,
PROP_LABEL,
- PROP_ATTRIBUTES
+ PROP_ATTRIBUTES,
+ PROP_OBJECT
};
struct _GcrKeyRendererPrivate {
guint key_size;
gchar *label;
GckAttributes *attributes;
+ GckObject *object;
GIcon *icon;
+ gulong notify_sig;
+ EggBytes *spk;
};
static void gcr_key_renderer_renderer_iface (GcrRendererIface *iface);
@@ -82,6 +90,32 @@ calculate_label (GcrKeyRenderer *self)
return g_strdup (_("Key"));
}
+static GckAttributes *
+calculate_attrs (GcrKeyRenderer *self)
+{
+ if (self->pv->attributes)
+ return gck_attributes_ref (self->pv->attributes);
+
+ if (GCK_IS_OBJECT_CACHE (self->pv->object))
+ return gck_object_cache_get_attributes (GCK_OBJECT_CACHE (self->pv->object));
+
+ return NULL;
+}
+
+static guchar *
+calculate_fingerprint (GcrKeyRenderer *self,
+ GckAttributes *attrs,
+ GChecksumType algorithm,
+ gsize *n_fingerprint)
+{
+ if (self->pv->spk)
+ return gcr_fingerprint_from_subject_public_key_info (egg_bytes_get_data (self->pv->spk),
+ egg_bytes_get_size (self->pv->spk),
+ algorithm, n_fingerprint);
+
+ return gcr_fingerprint_from_attributes (attrs, algorithm, n_fingerprint);
+}
+
static gint
calculate_rsa_key_size (GckAttributes *attrs)
{
@@ -129,9 +163,61 @@ calculate_key_size (GckAttributes *attrs, gulong key_type)
return -1;
}
-/* -----------------------------------------------------------------------------
- * OBJECT
- */
+static void
+on_subject_public_key (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GcrKeyRenderer *self = GCR_KEY_RENDERER (user_data);
+ GError *error = NULL;
+ GNode *node;
+
+ node = _gcr_subject_public_key_load_finish (result, &error);
+ if (error != NULL) {
+ g_message ("couldn't load key information: %s", error->message);
+ g_clear_error (&error);
+
+ } else {
+ if (self->pv->spk)
+ egg_bytes_unref (self->pv->spk);
+ self->pv->spk = NULL;
+
+ self->pv->spk = egg_asn1x_encode (node, NULL);
+ if (self->pv->spk == NULL)
+ g_warning ("invalid subjectPublicKey loaded: %s",
+ egg_asn1x_message (node));
+ egg_asn1x_destroy (node);
+
+ gcr_renderer_emit_data_changed (GCR_RENDERER (self));
+ }
+
+ g_object_unref (self);
+}
+
+static void
+update_subject_public_key (GcrKeyRenderer *self)
+{
+ if (self->pv->spk)
+ egg_bytes_unref (self->pv->spk);
+ self->pv->spk = NULL;
+
+ if (!self->pv->object)
+ return;
+
+ _gcr_subject_public_key_load_async (self->pv->object, NULL,
+ on_subject_public_key,
+ g_object_ref (self));
+}
+
+static void
+on_object_cache_attributes (GObject *obj,
+ GParamSpec *spec,
+ gpointer user_data)
+{
+ GcrKeyRenderer *self = GCR_KEY_RENDERER (user_data);
+ update_subject_public_key (self);
+ gcr_renderer_emit_data_changed (GCR_RENDERER (self));
+}
static void
gcr_key_renderer_init (GcrKeyRenderer *self)
@@ -143,6 +229,18 @@ gcr_key_renderer_init (GcrKeyRenderer *self)
static void
gcr_key_renderer_dispose (GObject *obj)
{
+ GcrKeyRenderer *self = GCR_KEY_RENDERER (obj);
+
+ if (self->pv->spk)
+ egg_bytes_unref (self->pv->spk);
+ self->pv->spk = NULL;
+
+ if (self->pv->object && self->pv->notify_sig) {
+ g_signal_handler_disconnect (self->pv->object, self->pv->notify_sig);
+ self->pv->notify_sig = 0;
+ }
+ g_clear_object (&self->pv->object);
+
G_OBJECT_CLASS (gcr_key_renderer_parent_class)->dispose (obj);
}
@@ -183,6 +281,16 @@ gcr_key_renderer_set_property (GObject *obj, guint prop_id, const GValue *value,
self->pv->attributes = g_value_dup_boxed (value);
gcr_renderer_emit_data_changed (GCR_RENDERER (self));
break;
+ case PROP_OBJECT:
+ g_return_if_fail (!self->pv->object);
+ self->pv->object = g_value_dup_object (value);
+ if (self->pv->object && GCK_IS_OBJECT_CACHE (self->pv->object))
+ self->pv->notify_sig = g_signal_connect (self->pv->object,
+ "notify::attributes",
+ G_CALLBACK (on_object_cache_attributes),
+ self);
+ on_object_cache_attributes (G_OBJECT (self->pv->object), NULL, self);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -200,7 +308,10 @@ gcr_key_renderer_get_property (GObject *obj, guint prop_id, GValue *value,
g_value_take_string (value, calculate_label (self));
break;
case PROP_ATTRIBUTES:
- g_value_set_boxed (value, self->pv->attributes);
+ g_value_take_boxed (value, calculate_attrs (self));
+ break;
+ case PROP_OBJECT:
+ g_value_set_object (value, self->pv->object);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
@@ -225,6 +336,10 @@ gcr_key_renderer_class_init (GcrKeyRendererClass *klass)
g_object_class_override_property (gobject_class, PROP_LABEL, "label");
g_object_class_override_property (gobject_class, PROP_ATTRIBUTES, "attributes");
+ g_object_class_install_property (gobject_class, PROP_OBJECT,
+ g_param_spec_object ("object", "Object", "Key Object", GCK_TYPE_OBJECT,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
/* Register this as a view which can be loaded */
gck_builder_add_ulong (&builder, CKA_CLASS, CKO_PRIVATE_KEY);
gcr_renderer_register (GCR_TYPE_KEY_RENDERER, gck_builder_end (&builder));
@@ -236,6 +351,7 @@ gcr_key_renderer_real_render (GcrRenderer *renderer, GcrViewer *viewer)
GcrKeyRenderer *self;
GcrDisplayView *view;
const gchar *text = "";
+ GckAttributes *attrs;
gpointer fingerprint;
gsize n_fingerprint;
gchar *display;
@@ -256,15 +372,17 @@ gcr_key_renderer_real_render (GcrRenderer *renderer, GcrViewer *viewer)
_gcr_display_view_begin (view, renderer);
- if (!self->pv->attributes) {
+ attrs = calculate_attrs (self);
+ if (attrs == NULL) {
_gcr_display_view_end (view, renderer);
return;
}
- if (!gck_attributes_find_ulong (self->pv->attributes, CKA_CLASS, &klass) ||
- !gck_attributes_find_ulong (self->pv->attributes, CKA_KEY_TYPE, &key_type)) {
+ if (!gck_attributes_find_ulong (attrs, CKA_CLASS, &klass) ||
+ !gck_attributes_find_ulong (attrs, CKA_KEY_TYPE, &key_type)) {
g_warning ("private key does not have the CKA_CLASS and CKA_KEY_TYPE attributes");
_gcr_display_view_end (view, renderer);
+ gck_attributes_unref (attrs);
return;
}
@@ -292,7 +410,7 @@ gcr_key_renderer_real_render (GcrRenderer *renderer, GcrViewer *viewer)
_gcr_display_view_append_content (view, renderer, text, NULL);
- size = calculate_key_size (self->pv->attributes, key_type);
+ size = calculate_key_size (attrs, key_type);
if (size >= 0) {
display = g_strdup_printf (ngettext ("%d bit", "%d bits", size), size);
_gcr_display_view_append_content (view, renderer, _("Strength"), display);
@@ -301,7 +419,6 @@ gcr_key_renderer_real_render (GcrRenderer *renderer, GcrViewer *viewer)
_gcr_display_view_start_details (view, renderer);
-
if (key_type == CKK_RSA)
text = _("RSA");
else if (key_type == CKK_DSA)
@@ -310,7 +427,7 @@ gcr_key_renderer_real_render (GcrRenderer *renderer, GcrViewer *viewer)
text = _("Unknown");
_gcr_display_view_append_value (view, renderer, _("Algorithm"), text, FALSE);
- size = calculate_key_size (self->pv->attributes, key_type);
+ size = calculate_key_size (attrs, key_type);
if (size < 0)
display = g_strdup (_("Unknown"));
else
@@ -321,20 +438,19 @@ gcr_key_renderer_real_render (GcrRenderer *renderer, GcrViewer *viewer)
/* Fingerprints */
_gcr_display_view_append_heading (view, renderer, _("Fingerprints"));
- fingerprint = gcr_fingerprint_from_attributes (self->pv->attributes,
- G_CHECKSUM_SHA1, &n_fingerprint);
+ fingerprint = calculate_fingerprint (self, attrs, G_CHECKSUM_SHA1, &n_fingerprint);
if (fingerprint) {
_gcr_display_view_append_hex (view, renderer, _("SHA1"), fingerprint, n_fingerprint);
g_free (fingerprint);
}
- fingerprint = gcr_fingerprint_from_attributes (self->pv->attributes,
- G_CHECKSUM_SHA256, &n_fingerprint);
+ fingerprint = calculate_fingerprint (self, attrs, G_CHECKSUM_SHA256, &n_fingerprint);
if (fingerprint) {
_gcr_display_view_append_hex (view, renderer, _("SHA256"), fingerprint, n_fingerprint);
g_free (fingerprint);
}
_gcr_display_view_end (view, renderer);
+ gck_attributes_unref (attrs);
}
static void
diff --git a/gcr/gcr-subject-public-key.c b/gcr/gcr-subject-public-key.c
index a3293f1..0e238fc 100644
--- a/gcr/gcr-subject-public-key.c
+++ b/gcr/gcr-subject-public-key.c
@@ -65,6 +65,7 @@ load_object_basics (GckObject *object,
gulong *type,
GError **lerror)
{
+ gulong attr_types[] = { CKA_CLASS, CKA_KEY_TYPE, CKA_CERTIFICATE_TYPE };
GckAttributes *attrs;
GError *error = NULL;
@@ -76,8 +77,8 @@ load_object_basics (GckObject *object,
return TRUE;
}
- attrs = gck_object_get (object, cancellable, &error,
- CKA_CLASS, CKA_KEY_TYPE, CKA_CERTIFICATE_TYPE, GCK_INVALID);
+ attrs = gck_object_cache_lookup (object, attr_types, G_N_ELEMENTS (attr_types),
+ cancellable, &error);
if (error != NULL) {
_gcr_debug ("couldn't load: %s", error->message);
g_propagate_error (lerror, error);
@@ -107,6 +108,7 @@ load_x509_attributes (GckObject *object,
GCancellable *cancellable,
GError **lerror)
{
+ gulong attr_types[] = { CKA_VALUE };
GckAttributes *attrs;
GError *error = NULL;
@@ -115,8 +117,8 @@ load_x509_attributes (GckObject *object,
return TRUE;
}
- attrs = gck_object_get (object, cancellable, &error,
- CKA_VALUE, GCK_INVALID);
+ attrs = gck_object_cache_lookup (object, attr_types, G_N_ELEMENTS (attr_types),
+ cancellable, &error);
if (error != NULL) {
_gcr_debug ("couldn't load: %s", error->message);
g_propagate_error (lerror, error);
@@ -148,6 +150,7 @@ load_rsa_attributes (GckObject *object,
GCancellable *cancellable,
GError **lerror)
{
+ gulong attr_types[] = { CKA_MODULUS, CKA_PUBLIC_EXPONENT };
GckAttributes *attrs;
GError *error = NULL;
@@ -156,8 +159,8 @@ load_rsa_attributes (GckObject *object,
return TRUE;
}
- attrs = gck_object_get (object, cancellable, &error,
- CKA_MODULUS, CKA_PUBLIC_EXPONENT, GCK_INVALID);
+ attrs = gck_object_cache_lookup (object, attr_types, G_N_ELEMENTS (attr_types),
+ cancellable, &error);
if (error != NULL) {
_gcr_debug ("couldn't load rsa attributes: %s", error->message);
g_propagate_error (lerror, error);
@@ -176,26 +179,37 @@ lookup_public_key (GckObject *object,
GError **lerror)
{
GckBuilder builder = GCK_BUILDER_INIT;
+ gulong attr_types[] = { CKA_ID };
+ GckAttributes *attrs;
GError *error = NULL;
GckSession *session;
GckObject *result;
+ const GckAttribute *id;
GList *objects;
- guchar *id;
- gsize n_id;
- id = gck_object_get_data (object, CKA_ID, cancellable, &n_id, &error);
+ attrs = gck_object_cache_lookup (object, attr_types, G_N_ELEMENTS (attr_types),
+ cancellable, &error);
if (error != NULL) {
_gcr_debug ("couldn't load private key id: %s", error->message);
g_propagate_error (lerror, error);
return NULL;
}
+ id = gck_attributes_find (attrs, CKA_ID);
+ if (id == NULL || gck_attribute_is_invalid (id)) {
+ gck_attributes_unref (attrs);
+ _gcr_debug ("couldn't load private key id");
+ g_set_error (lerror, GCK_ERROR, CKR_ATTRIBUTE_TYPE_INVALID,
+ gck_message_from_rv (CKR_ATTRIBUTE_TYPE_INVALID));
+ return NULL;
+ }
+
gck_builder_add_ulong (&builder, CKA_CLASS, CKO_PUBLIC_KEY);
- gck_builder_take_data (&builder, CKA_ID, id, n_id);
- session = gck_object_get_session (object);
+ gck_builder_add_owned (&builder, id);
+ gck_attributes_unref (attrs);
+ session = gck_object_get_session (object);
objects = gck_session_find_objects (session, gck_builder_end (&builder), cancellable, &error);
-
g_object_unref (session);
if (error != NULL) {
@@ -238,6 +252,7 @@ load_dsa_attributes (GckObject *object,
GCancellable *cancellable,
GError **lerror)
{
+ gulong attr_types[] = { CKA_PRIME, CKA_SUBPRIME, CKA_BASE, CKA_VALUE };
GError *error = NULL;
GckAttributes *loaded;
GckObject *publi;
@@ -259,9 +274,8 @@ load_dsa_attributes (GckObject *object,
if (!publi)
return FALSE;
- loaded = gck_object_get (publi, cancellable, &error,
- CKA_PRIME, CKA_SUBPRIME, CKA_BASE, CKA_VALUE,
- GCK_INVALID);
+ loaded = gck_object_cache_lookup (publi, attr_types, G_N_ELEMENTS (attr_types),
+ cancellable, &error);
g_object_unref (publi);
if (error != NULL) {
@@ -373,12 +387,12 @@ static void
lookup_attributes (GckObject *object,
GckBuilder *builder)
{
- GckObjectAttributes *oakey;
+ GckObjectCache *oakey;
GckAttributes *attrs;
- if (GCK_IS_OBJECT_ATTRIBUTES (object)) {
- oakey = GCK_OBJECT_ATTRIBUTES (object);
- attrs = gck_object_attributes_get_attributes (oakey);
+ if (GCK_IS_OBJECT_CACHE (object)) {
+ oakey = GCK_OBJECT_CACHE (object);
+ attrs = gck_object_cache_get_attributes (oakey);
if (attrs != NULL) {
gck_builder_add_all (builder, attrs);
gck_attributes_unref (attrs);
diff --git a/gcr/tests/test-subject-public-key.c b/gcr/tests/test-subject-public-key.c
index eaee3c7..bcd232c 100644
--- a/gcr/tests/test-subject-public-key.c
+++ b/gcr/tests/test-subject-public-key.c
@@ -419,9 +419,9 @@ typedef struct { GckObject parent; GckAttributes *attrs; } MockObject;
typedef struct { GckObjectClass parent; } MockObjectClass;
GType mock_object_get_type (void) G_GNUC_CONST;
-static void mock_object_attributes_init (GckObjectAttributesIface *iface);
+static void mock_object_cache_init (GckObjectCacheIface *iface);
G_DEFINE_TYPE_WITH_CODE (MockObject, mock_object, GCK_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GCK_TYPE_OBJECT_ATTRIBUTES, mock_object_attributes_init)
+ G_IMPLEMENT_INTERFACE (GCK_TYPE_OBJECT_CACHE, mock_object_cache_init)
);
static void
@@ -462,17 +462,34 @@ static void
mock_object_class_init (MockObjectClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
gobject_class->get_property = mock_object_get_property;
gobject_class->set_property = mock_object_set_property;
gobject_class->finalize = mock_object_finalize;
+
g_object_class_override_property (gobject_class, PROP_ATTRIBUTES, "attributes");
}
static void
-mock_object_attributes_init (GckObjectAttributesIface *iface)
+mock_object_add_attributes (GckObjectCache *object,
+ GckAttributes *attrs)
+{
+ GckBuilder builder = GCK_BUILDER_INIT;
+ MockObject *self = (MockObject *)object;
+
+ gck_builder_add_all (&builder, self->attrs);
+ gck_builder_set_all (&builder, attrs);
+
+ gck_attributes_unref (self->attrs);
+ self->attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
+}
+
+static void
+mock_object_cache_init (GckObjectCacheIface *iface)
{
- iface->attribute_types = NULL;
- iface->n_attribute_types = 0;
+ iface->default_types = NULL;
+ iface->n_default_types = 0;
+ iface->add_attributes = mock_object_add_attributes;
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]