[gnome-keyring/ui-widgets: 5/7] [gcr] Create new view interface and implement for certificates.



commit 512141527a7675e399d7b597c145a9e55e8b11d9
Author: Stef Walter <stef memberwebs com>
Date:   Mon Jun 21 02:36:43 2010 +0000

    [gcr] Create new view interface and implement for certificates.

 gcr/Makefile.am              |    4 +-
 gcr/gcr-certificate-widget.c |  198 +++++++++++++++++++++++++++++------------
 gcr/gcr-simple-certificate.c |   71 +++++++---------
 gcr/gcr-simple-certificate.h |    3 +
 gcr/gcr-view.c               |  144 ++++++++++++++++++++++++++++++
 gcr/gcr-view.h               |   53 +++++++++++
 gcr/template/gcr-zzz.c       |   59 +++++++++++++
 gcr/template/gcr-zzz.h       |   45 ++++++++++
 gp11/gp11-attributes.c       |   39 ++++++++
 gp11/gp11.h                  |    7 ++-
 10 files changed, 523 insertions(+), 100 deletions(-)
---
diff --git a/gcr/Makefile.am b/gcr/Makefile.am
index bba15bb..c4b205f 100644
--- a/gcr/Makefile.am
+++ b/gcr/Makefile.am
@@ -23,7 +23,8 @@ inc_HEADERS = \
 	gcr-importer.h \
 	gcr-parser.h \
 	gcr-types.h \
-	gcr-unlock-options-widget.h
+	gcr-unlock-options-widget.h \
+	gcr-view.h
 
 # ------------------------------------------------------------------
 # LIBRARY
@@ -57,6 +58,7 @@ libgcr_la_SOURCES = \
 	gcr-simple-certificate.c gcr-simple-certificate.h \
 	gcr-types.h \
 	gcr-unlock-options-widget.c gcr-unlock-options-widget.h \
+	gcr-view.c gcr-view.h \
 	$(BUILT_SOURCES)
 
 libgcr_la_CFLAGS = \
diff --git a/gcr/gcr-certificate-widget.c b/gcr/gcr-certificate-widget.c
index 7b81d7f..7d178a6 100644
--- a/gcr/gcr-certificate-widget.c
+++ b/gcr/gcr-certificate-widget.c
@@ -23,8 +23,12 @@
 #include "gcr-certificate-widget.h"
 #include "gcr-display-view.h"
 #include "gcr-icons.h"
+#include "gcr-simple-certificate.h"
+#include "gcr-view.h"
 
-#include "egg/egg-asn1.h"
+#include "egg/egg-asn1x.h"
+#include "egg/egg-asn1-defs.h"
+#include "egg/egg-dn.h"
 #include "egg/egg-oid.h"
 #include "egg/egg-hex.h"
 
@@ -33,49 +37,71 @@
 
 enum {
 	PROP_0,
-	PROP_CERTIFICATE
+	PROP_CERTIFICATE,
+	PROP_LABEL,
+	PROP_ATTRIBUTES
 };
 
 struct _GcrCertificateWidgetPrivate {
 	GcrCertificate *certificate;
 	GcrDisplayView *view;
 	guint key_size;
+	gchar *label;
+	GP11Attributes *attributes;
 };
 
-G_DEFINE_TYPE (GcrCertificateWidget, gcr_certificate_widget, GTK_TYPE_ALIGNMENT);
+static void gcr_view_iface_init (GcrViewIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GcrCertificateWidget, gcr_certificate_widget, GTK_TYPE_ALIGNMENT,
+                         G_IMPLEMENT_INTERFACE (GCR_TYPE_VIEW, gcr_view_iface_init));
 
 /* -----------------------------------------------------------------------------
  * INTERNAL
  */
 
+static gchar*
+calculate_label (GcrCertificateWidget *self, GNode *asn)
+{
+	gchar *label;
+
+	if (self->pv->label)
+		return g_strdup (self->pv->label);
+
+	if (self->pv->attributes) {
+		if (gp11_attributes_find_string (self->pv->attributes, CKA_LABEL, &label))
+			return label;
+	}
+
+	if (asn != NULL) {
+		label = egg_dn_read_part (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), "CN");
+		if (label != NULL)
+			return label;
+	}
+
+	return g_strdup (_("Certificate"));
+}
+
 static gboolean
-append_extension (GcrCertificateWidget *self, ASN1_TYPE asn,
+append_extension (GcrCertificateWidget *self, GNode *asn,
                   const guchar *data, gsize n_data, gint index)
 {
+	GNode *node;
 	GQuark oid;
-	gchar *name, *display;
+	gchar *display;
 	gsize n_value;
 	const guchar *value;
 	const gchar *text;
 	gboolean critical;
-	int len, res;
 
 	/* Make sure it is present */
-	len = 0;
-	name = g_strdup_printf ("tbsCertificate.extensions.?%u", index);
-	res = asn1_read_value (asn, name, NULL, &len);
-	g_free (name);
-
-	if (res == ASN1_ELEMENT_NOT_FOUND)
+	node = egg_asn1x_node (asn, "tbsCertificate", "extensions", index, NULL);
+	if (node == NULL)
 		return FALSE;
 
 	/* Dig out the OID */
-	name = g_strdup_printf ("tbsCertificate.extensions.?%u.extnID", index);
-	oid = egg_asn1_read_oid (asn, name);
-	g_free (name);
+	oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (node, "extnID", NULL));
 	g_return_val_if_fail (oid, FALSE);
 
-
 	_gcr_display_view_append_heading (self->pv->view, _("Extension"));
 
 
@@ -85,9 +111,7 @@ append_extension (GcrCertificateWidget *self, ASN1_TYPE asn,
 
 
 	/* Extension value */
-	name = g_strdup_printf ("tbsCertificate.extensions.?%u.extnValue", index);
-	value = egg_asn1_read_content (asn, data, n_data, name, &n_value);
-	g_free (name);
+	value = egg_asn1x_get_raw_value (egg_asn1x_node (node, "extnValue", NULL), &n_value);
 
 	/* TODO: Parsing of extensions that we understand */
 	display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1);
@@ -96,10 +120,8 @@ append_extension (GcrCertificateWidget *self, ASN1_TYPE asn,
 
 
 	/* Critical */
-	name = g_strdup_printf ("tbsCertificate.extensions.?%u.critical", index);
-	if (egg_asn1_read_boolean (asn, name, &critical))
+	if (egg_asn1x_get_boolean (egg_asn1x_node (node, "critical", NULL), &critical))
 		_gcr_display_view_append_value (self->pv->view, _("Critical"), critical ? _("Yes") : _("No"), FALSE);
-	g_free (name);
 
 	return TRUE;
 }
@@ -135,7 +157,7 @@ on_parsed_dn_part (guint index, GQuark oid, const guchar *value,
 		g_assert_not_reached ();
 	}
 
-	display = egg_asn1_dn_print_value (oid, value, n_value);
+	display = egg_dn_print_value (oid, value, n_value);
 	if (display == NULL)
 		display = g_strdup ("");
 
@@ -148,12 +170,13 @@ static void
 refresh_display (GcrCertificateWidget *self)
 {
 	const guchar *data, *value;
-	gsize n_data, n_value;
+	gsize n_data, n_value, n_raw;
 	const gchar *text;
-	guint version, size;
-	guint index;
+	gpointer raw;
+	gulong version;
+	guint bits, index;
 	gchar *display;
-	ASN1_TYPE asn;
+	GNode *asn;
 	GQuark oid;
 	GDate date;
 
@@ -165,21 +188,22 @@ refresh_display (GcrCertificateWidget *self)
 	data = gcr_certificate_get_der_data (self->pv->certificate, &n_data);
 	g_return_if_fail (data);
 
-	asn = egg_asn1_decode ("PKIX1.Certificate", data, n_data);
+	asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data, n_data);
 	g_return_if_fail (asn);
 
-	/* TODO: Calculate name properly */
-	_gcr_display_view_append_title (self->pv->view, "Certificate Name");
+	display = calculate_label (self, asn);
+	_gcr_display_view_append_title (self->pv->view, display);
+	g_free (display);
 
-	display = egg_asn1_read_dn_part (asn, "tbsCertificate.subject.rdnSequence", "CN");
+	display = egg_dn_read_part (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), "CN");
 	_gcr_display_view_append_content (self->pv->view, _("Identity"), display);
 	g_free (display);
 
-	display = egg_asn1_read_dn_part (asn, "tbsCertificate.issuer.rdnSequence", "CN");
+	display = egg_dn_read_part (egg_asn1x_node (asn, "tbsCertificate", "issuer", "rdnSequence", NULL), "CN");
 	_gcr_display_view_append_content (self->pv->view, _("Verified by"), display);
 	g_free (display);
 
-	if (egg_asn1_read_date (asn, "tbsCertificate.validity.notAfter", &date)) {
+	if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notAfter", NULL), &date)) {
 		display = g_malloc0 (128);
 		if (!g_date_strftime (display, 128, "%x", &date))
 			g_return_if_reached ();
@@ -191,34 +215,35 @@ refresh_display (GcrCertificateWidget *self)
 
 	/* The subject */
 	_gcr_display_view_append_heading (self->pv->view, _("Subject Name"));
-	egg_asn1_dn_parse (asn, "tbsCertificate.subject.rdnSequence", on_parsed_dn_part, self);
+	egg_dn_parse (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), on_parsed_dn_part, self);
 
 	/* The Issuer */
 	_gcr_display_view_append_heading (self->pv->view, _("Issuer Name"));
-	egg_asn1_dn_parse (asn, "tbsCertificate.issuer.rdnSequence", on_parsed_dn_part, self);
+	egg_dn_parse (egg_asn1x_node (asn, "tbsCertificate", "issuer", "rdnSequence", NULL), on_parsed_dn_part, self);
 
 	/* The Issued Parameters */
 	_gcr_display_view_append_heading (self->pv->view, _("Issued Certificate"));
 
-	if (!egg_asn1_read_uint (asn, "tbsCertificate.version", &version))
+	if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "tbsCertificate", "version", NULL), &version))
 		g_return_if_reached ();
-	display = g_strdup_printf ("%u", version + 1);
+	display = g_strdup_printf ("%lu", version + 1);
 	_gcr_display_view_append_value (self->pv->view, _("Version"), display, FALSE);
 	g_free (display);
 
-	value = egg_asn1_read_content (asn, data, n_data, "tbsCertificate.serialNumber", &n_value);
-	g_return_if_fail (value);
-	display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1);
+	raw = egg_asn1x_get_integer_as_raw (egg_asn1x_node (asn, "tbsCertificate", "serialNumber", NULL), NULL, &n_raw);
+	g_return_if_fail (raw);
+	display = egg_hex_encode_full (raw, n_raw, TRUE, ' ', 1);
 	_gcr_display_view_append_value (self->pv->view, _("Serial Number"), display, TRUE);
 	g_free (display);
+	g_free (raw);
 
 	display = g_malloc0 (128);
-	if (egg_asn1_read_date (asn, "tbsCertificate.validity.notBefore", &date)) {
+	if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notBefore", NULL), &date)) {
 		if (!g_date_strftime (display, 128, "%Y-%m-%d", &date))
 			g_return_if_reached ();
 		_gcr_display_view_append_value (self->pv->view, _("Not Valid Before"), display, FALSE);
 	}
-	if (egg_asn1_read_date (asn, "tbsCertificate.validity.notAfter", &date)) {
+	if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notAfter", NULL), &date)) {
 		if (!g_date_strftime (display, 128, "%Y-%m-%d", &date))
 			g_return_if_reached ();
 		_gcr_display_view_append_value (self->pv->view, _("Not Valid After"), display, FALSE);
@@ -228,49 +253,54 @@ refresh_display (GcrCertificateWidget *self)
 	/* Signature */
 	_gcr_display_view_append_heading (self->pv->view, _("Signature"));
 
-	oid = egg_asn1_read_oid (asn, "signatureAlgorithm.algorithm");
+	oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "signatureAlgorithm", "algorithm", NULL));
 	text = egg_oid_get_description (oid);
 	_gcr_display_view_append_value (self->pv->view, _("Signature Algorithm"), text, FALSE);
 
-	value = egg_asn1_read_content (asn, data, n_data, "signatureAlgorithm.parameters", &n_value);
+	value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "signatureAlgorithm", "parameters", NULL), &n_value);
 	if (value && n_value) {
 		display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1);
 		_gcr_display_view_append_value (self->pv->view, _("Signature Parameters"), display, TRUE);
 		g_free (display);
 	}
 
-	value = egg_asn1_read_content (asn, data, n_data, "signature", &n_value);
-	g_return_if_fail (value);
-	display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1);
+	raw = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "signature", NULL), NULL, &bits);
+	g_return_if_fail (raw);
+	display = egg_hex_encode_full (raw, bits / 8, TRUE, ' ', 1);
 	_gcr_display_view_append_value (self->pv->view, _("Signature"), display, TRUE);
 	g_free (display);
+	g_free (raw);
 
 	/* Public Key Info */
 	_gcr_display_view_append_heading (self->pv->view, _("Public Key Info"));
 
-	oid = egg_asn1_read_oid (asn, "tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm");
+	oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo",
+	                                                  "algorithm", "algorithm", NULL));
 	text = egg_oid_get_description (oid);
 	_gcr_display_view_append_value (self->pv->view, _("Key Algorithm"), text, FALSE);
 
-	value = egg_asn1_read_content (asn, data, n_data, "tbsCertificate.subjectPublicKeyInfo.algorithm.parameters", &n_value);
+	value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo",
+	                                                   "algorithm", "parameters", NULL), &n_value);
 	if (value && n_value) {
 		display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1);
 		_gcr_display_view_append_value (self->pv->view, _("Key Parameters"), display, TRUE);
 		g_free (display);
 	}
 
-	size = gcr_certificate_get_key_size (self->pv->certificate);
-	if (size > 0) {
-		display = g_strdup_printf ("%u", size);
+	bits = gcr_certificate_get_key_size (self->pv->certificate);
+	if (bits > 0) {
+		display = g_strdup_printf ("%u", bits);
 		_gcr_display_view_append_value (self->pv->view, _("Key Size"), display, FALSE);
 		g_free (display);
 	}
 
-	value = egg_asn1_read_content (asn, data, n_data, "tbsCertificate.subjectPublicKeyInfo.subjectPublicKey", &n_value);
-	g_return_if_fail (value);
-	display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1);
+	raw = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo",
+	                                                 "subjectPublicKey", NULL), NULL, &bits);
+	g_return_if_fail (raw);
+	display = egg_hex_encode_full (raw, bits / 8, TRUE, ' ', 1);
 	_gcr_display_view_append_value (self->pv->view, _("Public Key"), display, TRUE);
 	g_free (display);
+	g_free (raw);
 
 	/* Fingerprints */
 	_gcr_display_view_append_heading (self->pv->view, _("Fingerprints"));
@@ -284,7 +314,7 @@ refresh_display (GcrCertificateWidget *self)
 			break;
 	}
 
-	asn1_delete_structure (&asn);
+	egg_asn1x_destroy (asn);
 }
 
 /* -----------------------------------------------------------------------------
@@ -340,19 +370,49 @@ gcr_certificate_widget_finalize (GObject *obj)
 
 	g_assert (!self->pv->certificate);
 
+	if (self->pv->attributes)
+		gp11_attributes_unref (self->pv->attributes);
+	self->pv->attributes = NULL;
+
+	g_free (self->pv->label);
+	self->pv->label = NULL;
+
 	G_OBJECT_CLASS (gcr_certificate_widget_parent_class)->finalize (obj);
 }
 
 static void
 gcr_certificate_widget_set_property (GObject *obj, guint prop_id, const GValue *value,
-                                             GParamSpec *pspec)
+                                     GParamSpec *pspec)
 {
 	GcrCertificateWidget *self = GCR_CERTIFICATE_WIDGET (obj);
+	GcrCertificate *cert;
+	GP11Attribute *attr;
 
 	switch (prop_id) {
 	case PROP_CERTIFICATE:
 		gcr_certificate_widget_set_certificate (self, g_value_get_object (value));
 		break;
+	case PROP_LABEL:
+		g_free (self->pv->label);
+		self->pv->label = g_value_dup_string (value);
+		g_object_notify (obj, "label");
+		break;
+	case PROP_ATTRIBUTES:
+		g_return_if_fail (!self->pv->attributes);
+		self->pv->attributes = g_value_dup_boxed (value);
+		if (self->pv->attributes) {
+			attr = gp11_attributes_find (self->pv->attributes, CKA_VALUE);
+			if (attr) {
+				/* Create a new certificate object refferring to same memory */
+				cert = gcr_simple_certificate_new_static (attr->value, attr->length);
+				g_object_set_data_full (G_OBJECT (cert), "attributes",
+				                        gp11_attributes_ref (self->pv->attributes),
+				                        (GDestroyNotify)gp11_attributes_unref);
+				gcr_certificate_widget_set_certificate (self, cert);
+				g_object_unref (cert);
+			}
+		}
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
 		break;
@@ -361,7 +421,7 @@ gcr_certificate_widget_set_property (GObject *obj, guint prop_id, const GValue *
 
 static void
 gcr_certificate_widget_get_property (GObject *obj, guint prop_id, GValue *value,
-                                             GParamSpec *pspec)
+                                     GParamSpec *pspec)
 {
 	GcrCertificateWidget *self = GCR_CERTIFICATE_WIDGET (obj);
 
@@ -369,6 +429,12 @@ gcr_certificate_widget_get_property (GObject *obj, guint prop_id, GValue *value,
 	case PROP_CERTIFICATE:
 		g_value_set_object (value, self->pv->certificate);
 		break;
+	case PROP_LABEL:
+		g_value_take_string (value, calculate_label (self, NULL));
+		break;
+	case PROP_ATTRIBUTES:
+		g_value_set_boxed (value, self->pv->attributes);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
 		break;
@@ -379,6 +445,7 @@ static void
 gcr_certificate_widget_class_init (GcrCertificateWidgetClass *klass)
 {
 	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+	GP11Attributes *registered;
 
 	gcr_certificate_widget_parent_class = g_type_class_peek_parent (klass);
 	g_type_class_add_private (klass, sizeof (GcrCertificateWidgetPrivate));
@@ -393,7 +460,22 @@ gcr_certificate_widget_class_init (GcrCertificateWidgetClass *klass)
 	           g_param_spec_object("certificate", "Certificate", "Certificate to display.",
 	                               GCR_TYPE_CERTIFICATE, G_PARAM_READWRITE));
 
+	g_object_class_override_property (gobject_class, PROP_LABEL, "label");
+	g_object_class_override_property (gobject_class, PROP_ATTRIBUTES, "attributes");
+
 	_gcr_icons_register ();
+
+	/* Register this as a view which can be loaded */
+	registered = gp11_attributes_new ();
+	gp11_attributes_add_ulong (registered, CKA_CLASS, CKO_CERTIFICATE);
+	gcr_view_register (GCR_TYPE_CERTIFICATE_WIDGET, registered);
+	gp11_attributes_unref (registered);
+}
+
+static void
+gcr_view_iface_init (GcrViewIface *iface)
+{
+	/* Nothing to do */
 }
 
 /* -----------------------------------------------------------------------------
diff --git a/gcr/gcr-simple-certificate.c b/gcr/gcr-simple-certificate.c
index d9bf516..b3dd691 100644
--- a/gcr/gcr-simple-certificate.c
+++ b/gcr/gcr-simple-certificate.c
@@ -30,8 +30,9 @@
 #include <string.h>
 
 struct _GcrSimpleCertificatePrivate {
-	guchar *owned_data;
-	gsize n_owned_data;
+	const guchar *data;
+	gsize n_data;
+	guchar *owned;
 };
 
 static void gcr_certificate_iface (GcrCertificateIface *iface); 
@@ -52,47 +53,21 @@ static void
 gcr_simple_certificate_finalize (GObject *obj)
 {
 	GcrSimpleCertificate *self = GCR_SIMPLE_CERTIFICATE (obj);
-	
-	g_free (self->pv->owned_data);
-	self->pv->owned_data = NULL;
-	self->pv->n_owned_data = 0;
-
-	G_OBJECT_CLASS (gcr_simple_certificate_parent_class)->finalize (obj);
-}
 
-static void
-gcr_simple_certificate_set_property (GObject *obj, guint prop_id, const GValue *value, 
-                                     GParamSpec *pspec)
-{
-	switch (prop_id) {
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
-		break;
-	}
-}
+	g_free (self->pv->owned);
+	self->pv->owned = NULL;
+	self->pv->data = NULL;
+	self->pv->n_data = 0;
 
-static void
-gcr_simple_certificate_get_property (GObject *obj, guint prop_id, GValue *value, 
-                                     GParamSpec *pspec)
-{
-	switch (prop_id) {
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
-		break;
-	}
+	G_OBJECT_CLASS (gcr_simple_certificate_parent_class)->finalize (obj);
 }
 
 static void
 gcr_simple_certificate_class_init (GcrSimpleCertificateClass *klass)
 {
 	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-    
 	gobject_class->finalize = gcr_simple_certificate_finalize;
-	gobject_class->set_property = gcr_simple_certificate_set_property;
-	gobject_class->get_property = gcr_simple_certificate_get_property;
-	
 	g_type_class_add_private (gobject_class, sizeof (GcrSimpleCertificatePrivate));
-
 	_gcr_initialize ();
 }
 
@@ -103,11 +78,11 @@ gcr_simple_certificate_real_get_der_data (GcrCertificate *base, gsize *n_data)
 	
 	g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
 	g_return_val_if_fail (n_data, NULL);
-	g_return_val_if_fail (self->pv->owned_data, NULL);
-	
+	g_return_val_if_fail (self->pv->data, NULL);
+
 	/* This is called when we're not a base class */
-	*n_data = self->pv->n_owned_data;
-	return self->pv->owned_data;
+	*n_data = self->pv->n_data;
+	return self->pv->data;
 }
 
 static void 
@@ -129,8 +104,24 @@ gcr_simple_certificate_new (const guchar *data, gsize n_data)
 	g_return_val_if_fail (n_data, NULL);
 	
 	cert = g_object_new (GCR_TYPE_SIMPLE_CERTIFICATE, NULL);
-	
-	cert->pv->owned_data = g_memdup (data, n_data);
-	cert->pv->n_owned_data = n_data;
+
+	cert->pv->data = cert->pv->owned = g_memdup (data, n_data);
+	cert->pv->n_data = n_data;
+	return GCR_CERTIFICATE (cert);
+}
+
+GcrCertificate*
+gcr_simple_certificate_new_static (const guchar *data, gsize n_data)
+{
+	GcrSimpleCertificate *cert;
+
+	g_return_val_if_fail (data, NULL);
+	g_return_val_if_fail (n_data, NULL);
+
+	cert = g_object_new (GCR_TYPE_SIMPLE_CERTIFICATE, NULL);
+
+	cert->pv->owned = NULL;
+	cert->pv->data = data;
+	cert->pv->n_data = n_data;
 	return GCR_CERTIFICATE (cert);
 }
diff --git a/gcr/gcr-simple-certificate.h b/gcr/gcr-simple-certificate.h
index 6548be4..7089af9 100644
--- a/gcr/gcr-simple-certificate.h
+++ b/gcr/gcr-simple-certificate.h
@@ -53,6 +53,9 @@ GType               gcr_simple_certificate_get_type               (void);
 GcrCertificate*     gcr_simple_certificate_new                    (const guchar *data,
                                                                    gsize n_data);
 
+GcrCertificate*     gcr_simple_certificate_new_static             (const guchar *data,
+                                                                   gsize n_data);
+
 G_END_DECLS
 
 #endif /* __GCR_SIMPLE_CERTIFICATE_H__ */
diff --git a/gcr/gcr-view.c b/gcr/gcr-view.c
new file mode 100644
index 0000000..ff6c763
--- /dev/null
+++ b/gcr/gcr-view.c
@@ -0,0 +1,144 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2010 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 "gcr-view.h"
+
+#include "gp11/gp11.h"
+
+#include <gtk/gtk.h>
+
+typedef struct _GcrRegisteredView {
+	GP11Attributes *attrs;
+	GType view_type;
+} GcrRegisteredView;
+
+static GArray *registered_views = NULL;
+static gboolean registered_sorted = FALSE;
+
+static void
+gcr_view_base_init (gpointer gobject_iface)
+{
+	static gboolean initialized = FALSE;
+	if (!initialized) {
+
+		g_object_interface_install_property (gobject_iface,
+		         g_param_spec_string ("label", "Label", "The label for the view",
+		                              "", G_PARAM_READWRITE));
+
+		g_object_interface_install_property (gobject_iface,
+		         g_param_spec_boxed ("attributes", "Attributes", "The data displayed in the view",
+		                             GP11_TYPE_ATTRIBUTES, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+
+		initialized = TRUE;
+	}
+}
+
+GType
+gcr_view_get_type (void)
+{
+	static GType type = 0;
+	if (!type) {
+		static const GTypeInfo info = {
+			sizeof (GcrViewIface),
+			gcr_view_base_init,  /* base init */
+			NULL,                /* base finalize */
+		};
+		type = g_type_register_static (G_TYPE_INTERFACE, "GcrViewIface", &info, 0);
+		g_type_interface_add_prerequisite (type, GTK_TYPE_WIDGET);
+	}
+
+	return type;
+}
+
+static gint
+sort_registered_by_n_attrs (gconstpointer a, gconstpointer b)
+{
+	const GcrRegisteredView *ra = a;
+	const GcrRegisteredView *rb = b;
+	gulong na, nb;
+
+	g_assert (a);
+	g_assert (b);
+
+	na = gp11_attributes_count (ra->attrs);
+	nb = gp11_attributes_count (rb->attrs);
+
+	/* Note we're sorting in reverse order */
+	if (na < nb)
+		return 1;
+	return (na == nb) ? 0 : -1;
+}
+
+GcrView*
+gcr_view_create (const gchar *label, GP11Attributes *attrs)
+{
+	GcrRegisteredView *registered;
+	gboolean matched;
+	gulong n_attrs;
+	gulong j;
+	gsize i;
+
+	g_return_val_if_fail (attrs, NULL);
+
+	if (!registered_views)
+		return NULL;
+
+	if (!registered_sorted) {
+		g_array_sort (registered_views, sort_registered_by_n_attrs);
+		registered_sorted = TRUE;
+	}
+
+	for (i = 0; i < registered_views->len; ++i) {
+		registered = &(g_array_index (registered_views, GcrRegisteredView, i));
+		n_attrs = gp11_attributes_count (registered->attrs);
+
+		matched = TRUE;
+
+		for (j = 0; j < n_attrs; ++j) {
+			if (!gp11_attributes_contains (attrs, gp11_attributes_at (registered->attrs, j))) {
+				matched = FALSE;
+				break;
+			}
+		}
+
+		if (matched)
+			return g_object_new (registered->view_type, "label", label,
+			                     "attributes", attrs, NULL);
+	}
+
+	return NULL;
+}
+
+void
+gcr_view_register (GType view_type, GP11Attributes *attrs)
+{
+	GcrRegisteredView registered;
+
+	if (!registered_views)
+		registered_views = g_array_new (FALSE, FALSE, sizeof (GcrRegisteredView));
+
+	registered.view_type = view_type;
+	registered.attrs = gp11_attributes_ref (attrs);
+	g_array_append_val (registered_views, registered);
+	registered_sorted = FALSE;
+}
diff --git a/gcr/gcr-view.h b/gcr/gcr-view.h
new file mode 100644
index 0000000..d630756
--- /dev/null
+++ b/gcr/gcr-view.h
@@ -0,0 +1,53 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2010 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 __GCR_VIEW_H__
+#define __GCR_VIEW_H__
+
+#include <glib-object.h>
+
+#include "gcr-types.h"
+
+G_BEGIN_DECLS
+
+#define GCR_TYPE_VIEW                 (gcr_view_get_type())
+#define GCR_VIEW(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_VIEW, GcrView))
+#define GCR_IS_VIEW(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_VIEW))
+#define GCR_VIEW_GET_INTERFACE(inst)  (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GCR_TYPE_VIEW, GcrViewIface))
+
+typedef struct _GcrView      GcrView;
+typedef struct _GcrViewIface GcrViewIface;
+
+struct _GcrViewIface {
+	GTypeInterface parent;
+};
+
+GType                  gcr_view_get_type                          (void) G_GNUC_CONST;
+
+GcrView*               gcr_view_create                            (const gchar *label,
+                                                                   struct _GP11Attributes *attrs);
+
+void                   gcr_view_register                          (GType view_type,
+                                                                   struct _GP11Attributes *attrs);
+
+G_END_DECLS
+
+#endif /* __GCR_VIEW_H__ */
diff --git a/gcr/template/gcr-zzz.c b/gcr/template/gcr-zzz.c
new file mode 100644
index 0000000..23c48fa
--- /dev/null
+++ b/gcr/template/gcr-zzz.c
@@ -0,0 +1,59 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2010 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 "gcr-zzz.h"
+
+static void
+gcr_zzz_base_init (gpointer gobject_class)
+{
+	static volatile gsize initialized = 0;
+	if (g_once_init_enter (&initialized)) {
+		/* Add properties and signals to the interface */
+
+
+		g_once_init_leave (&initialized, 1);
+	}
+}
+
+GType
+gcr_zzz_get_type (void)
+{
+	static GType type = 0;
+	if (!type) {
+		static const GTypeInfo info = {
+			sizeof (GcrZzzIface),
+			gcr_zzz_base_init,  /* base init */
+			NULL,               /* base finalize */
+			NULL,               /* class_init */
+			NULL,               /* class finalize */
+			NULL,               /* class data */
+			0,
+			0,                  /* n_preallocs */
+			NULL,               /* instance init */
+		};
+		type = g_type_register_static (G_TYPE_INTERFACE, "GcrZzzIface", &info, 0);
+		g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
+	}
+
+	return type;
+}
diff --git a/gcr/template/gcr-zzz.h b/gcr/template/gcr-zzz.h
new file mode 100644
index 0000000..37ab217
--- /dev/null
+++ b/gcr/template/gcr-zzz.h
@@ -0,0 +1,45 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2010 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 __GCR_ZZZ_H__
+#define __GCR_ZZZ_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GCR_TYPE_ZZZ                 (gcr_zzz_get_type())
+#define GCR_ZZZ(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_ZZZ, GcrZzz))
+#define GCR_IS_ZZZ(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_ZZZ))
+#define GCR_ZZZ_GET_INTERFACE(inst)  (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GCR_TYPE_ZZZ, GcrZzzIface))
+
+typedef struct _GcrZzz      GcrZzz;
+typedef struct _GcrZzzIface GcrZzzIface;
+
+struct _GcrZzzIface {
+	GTypeInterface parent;
+};
+
+GType                  gcr_zzz_get_type                          (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GCR_ZZZ_H__ */
diff --git a/gp11/gp11-attributes.c b/gp11/gp11-attributes.c
index afbd08c..7bb76cb 100644
--- a/gp11/gp11-attributes.c
+++ b/gp11/gp11-attributes.c
@@ -629,6 +629,28 @@ gp11_attribute_free (GP11Attribute *attr)
 	}
 }
 
+gboolean
+gp11_attribute_equal (gconstpointer a, gconstpointer b)
+{
+	const GP11Attribute *aa = a;
+	const GP11Attribute *ab = b;
+
+	if (!a && !b)
+		return TRUE;
+	if (!a || !b)
+		return FALSE;
+
+	if (aa->type != ab->type)
+		return FALSE;
+	if (aa->length != ab->length)
+		return FALSE;
+	if (!aa->value && !ab->value)
+		return TRUE;
+	if (!aa->value || !ab->value)
+		return FALSE;
+	return memcmp (aa->value, ab->value, aa->length) == 0;
+}
+
 /**
  * SECTION:gp11-attributes
  * @title: GP11Attributes
@@ -1337,6 +1359,23 @@ gp11_attributes_unref (GP11Attributes *attrs)
 	}
 }
 
+gboolean
+gp11_attributes_contains (GP11Attributes *attrs, GP11Attribute *match)
+{
+	GP11Attribute *attr;
+	guint i;
+
+	g_return_val_if_fail (attrs && attrs->array, FALSE);
+
+	for (i = 0; i < attrs->array->len; ++i) {
+		attr = gp11_attributes_at (attrs, i);
+		if (gp11_attribute_equal (attr, match))
+			return TRUE;
+	}
+
+	return FALSE;
+}
+
 /* -------------------------------------------------------------------------------------------
  * INTERNAL
  * 
diff --git a/gp11/gp11.h b/gp11/gp11.h
index b04d66e..ea40559 100644
--- a/gp11/gp11.h
+++ b/gp11/gp11.h
@@ -151,13 +151,15 @@ gchar*              gp11_attribute_get_string               (GP11Attribute *attr
 void                gp11_attribute_get_date                 (GP11Attribute *attr, 
                                                              GDate* value);
 
+gboolean            gp11_attribute_equal                    (gconstpointer a,
+                                                             gconstpointer b);
+
 GP11Attribute*      gp11_attribute_dup                      (GP11Attribute *attr);
 
 void                gp11_attribute_clear                    (GP11Attribute *attr);
 
 void                gp11_attribute_free                     (GP11Attribute *attr);
 
-
 typedef struct _GP11Attributes GP11Attributes;
 
 #define             GP11_TYPE_ATTRIBUTES                    (gp11_attributes_get_boxed_type ())
@@ -235,6 +237,9 @@ GP11Attributes*     gp11_attributes_ref                     (GP11Attributes *att
 
 void                gp11_attributes_unref                   (GP11Attributes *attrs);
 
+gboolean            gp11_attributes_contains                (GP11Attributes *attrs,
+                                                             GP11Attribute *match);
+
 /* -------------------------------------------------------------------------
  * FORWARDS
  */



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