[gnome-keyring/ui-widgets: 6/7] [gcr] Implement rudimentary key view.
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-keyring/ui-widgets: 6/7] [gcr] Implement rudimentary key view.
- Date: Fri, 27 Aug 2010 03:25:00 +0000 (UTC)
commit 9a806907aceba77ca9baa7da9566c9b116e2cf9c
Author: Stef Walter <stef memberwebs com>
Date: Tue Jul 13 03:45:37 2010 +0000
[gcr] Implement rudimentary key view.
gcr/Makefile.am | 2 +
gcr/gcr-certificate-widget.c | 1 -
gcr/gcr-key-widget.c | 325 ++++++++++++++++++++
gcr/gcr-key-widget.h | 57 ++++
gcr/tests/.gitignore | 3 +-
gcr/tests/Makefile.am | 29 ++-
.../{ui-test-details.c => ui-test-certificate.c} | 20 +-
gcr/tests/{ui-test-details.c => ui-test-key.c} | 62 +++--
8 files changed, 453 insertions(+), 46 deletions(-)
---
diff --git a/gcr/Makefile.am b/gcr/Makefile.am
index c4b205f..f56900a 100644
--- a/gcr/Makefile.am
+++ b/gcr/Makefile.am
@@ -20,6 +20,7 @@ inc_HEADERS = \
gcr-certificate-basics-widget.h \
gcr-certificate-details-widget.h \
gcr-certificate-widget.h \
+ gcr-key-widget.h \
gcr-importer.h \
gcr-parser.h \
gcr-types.h \
@@ -48,6 +49,7 @@ libgcr_la_SOURCES = \
gcr-certificate-widget.c gcr-certificate-widget.h \
gcr-certificate-basics-widget.c gcr-certificate-basics-widget.h \
gcr-certificate-details-widget.c gcr-certificate-details-widget.h \
+ gcr-key-widget.c gcr-key-widget.h \
gcr-display-view.c gcr-display-view.h \
gcr-icons.c gcr-icons.h \
gcr-import-dialog.c gcr-import-dialog.h \
diff --git a/gcr/gcr-certificate-widget.c b/gcr/gcr-certificate-widget.c
index 7d178a6..7a55a6e 100644
--- a/gcr/gcr-certificate-widget.c
+++ b/gcr/gcr-certificate-widget.c
@@ -507,6 +507,5 @@ gcr_certificate_widget_set_certificate (GcrCertificateWidget *self, GcrCertifica
g_object_ref (self->pv->certificate);
refresh_display (self);
- refresh_display (self);
g_object_notify (G_OBJECT (self), "certificate");
}
diff --git a/gcr/gcr-key-widget.c b/gcr/gcr-key-widget.c
new file mode 100644
index 0000000..60b1ddc
--- /dev/null
+++ b/gcr/gcr-key-widget.c
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 2008 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-key-widget.h"
+#include "gcr-display-view.h"
+#include "gcr-icons.h"
+#include "gcr-view.h"
+
+#include "egg/egg-asn1x.h"
+#include "egg/egg-oid.h"
+#include "egg/egg-hex.h"
+
+#include "gp11/gp11.h"
+
+#include <gdk/gdk.h>
+#include <glib/gi18n-lib.h>
+
+enum {
+ PROP_0,
+ PROP_LABEL,
+ PROP_ATTRIBUTES
+};
+
+struct _GcrKeyWidgetPrivate {
+ GcrDisplayView *view;
+ guint key_size;
+ gchar *label;
+ GP11Attributes *attributes;
+};
+
+static void gcr_view_iface_init (GcrViewIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GcrKeyWidget, gcr_key_widget, GTK_TYPE_ALIGNMENT,
+ G_IMPLEMENT_INTERFACE (GCR_TYPE_VIEW, gcr_view_iface_init));
+
+/* -----------------------------------------------------------------------------
+ * INTERNAL
+ */
+
+static gchar*
+calculate_label (GcrKeyWidget *self)
+{
+ 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;
+ }
+
+ return g_strdup (_("Key"));
+}
+
+static gint
+calculate_rsa_key_size (GP11Attributes *attrs)
+{
+ GP11Attribute *attr;
+ gulong bits;
+
+ attr = gp11_attributes_find (attrs, CKA_MODULUS);
+
+ /* Calculate the bit length, and remove the complement */
+ if (attr != NULL)
+ return (attr->length / 2) * 2 * 8;
+
+ if (gp11_attributes_find_ulong (attrs, CKA_MODULUS_BITS, &bits))
+ return (gint)bits;
+
+ return -1;
+}
+
+static guint
+calculate_dsa_key_size (GP11Attributes *attrs)
+{
+ GP11Attribute *attr;
+ gulong bits;
+
+ attr = gp11_attributes_find (attrs, CKA_PRIME);
+
+ /* Calculate the bit length, and remove the complement */
+ if (attr != NULL)
+ return (attr->length / 2) * 2 * 8;
+
+ if (gp11_attributes_find_ulong (attrs, CKA_PRIME_BITS, &bits))
+ return (gint)bits;
+
+ return -1;
+}
+
+static gint
+calculate_key_size (GP11Attributes *attrs, gulong key_type)
+{
+ if (key_type == CKK_RSA)
+ return calculate_rsa_key_size (attrs);
+ else if (key_type == CKK_DSA)
+ return calculate_dsa_key_size (attrs);
+ else
+ return -1;
+}
+
+static void
+refresh_display (GcrKeyWidget *self)
+{
+ const gchar *text;
+ gchar *display;
+ gulong klass;
+ gulong key_type;
+ gint size;
+
+ _gcr_display_view_clear (self->pv->view);
+
+ if (!self->pv->attributes)
+ return;
+
+ if (!gp11_attributes_find_ulong (self->pv->attributes, CKA_CLASS, &klass) ||
+ !gp11_attributes_find_ulong (self->pv->attributes, CKA_KEY_TYPE, &key_type)) {
+ g_warning ("private key does not have the CKA_CLASS and CKA_KEY_TYPE attributes");
+ return;
+ }
+
+ display = calculate_label (self);
+ _gcr_display_view_append_title (self->pv->view, display);
+ g_free (display);
+
+ if (klass == CKO_PRIVATE_KEY) {
+ if (key_type == CKK_RSA)
+ text = _("Private RSA Key");
+ else if (key_type == CKK_DSA)
+ text = _("Private DSA Key");
+ else
+ text = _("Private Key");
+ } else if (klass == CKO_PUBLIC_KEY) {
+ if (key_type == CKK_RSA)
+ text = _("Public DSA Key");
+ else if (key_type == CKK_DSA)
+ text = _("Public DSA Key");
+ else
+ text = _("Public Key");
+ }
+
+ _gcr_display_view_append_content (self->pv->view, text, NULL);
+
+ _gcr_display_view_start_details (self->pv->view);
+
+
+ if (key_type == CKK_RSA)
+ text = _("RSA");
+ else if (key_type == CKK_DSA)
+ text = _("DSA");
+ else
+ text = _("Unknown");
+ _gcr_display_view_append_value (self->pv->view, _("Algorithm"), text, FALSE);
+
+ size = calculate_key_size (self->pv->attributes, key_type);
+ if (size < 0)
+ display = g_strdup (_("Unknown"));
+ else
+ display = g_strdup_printf ("%d", size);
+ _gcr_display_view_append_value (self->pv->view, _("Size"), display, FALSE);
+ g_free (display);
+
+ /* TODO: We need to have consistent key fingerprints. */
+ _gcr_display_view_append_value (self->pv->view, _("Fingerprint"), "XX XX XX XX XX XX XX XX XX XX", TRUE);
+}
+
+/* -----------------------------------------------------------------------------
+ * OBJECT
+ */
+
+static GObject*
+gcr_key_widget_constructor (GType type, guint n_props, GObjectConstructParam *props)
+{
+ GObject *obj = G_OBJECT_CLASS (gcr_key_widget_parent_class)->constructor (type, n_props, props);
+ GcrKeyWidget *self = NULL;
+ GtkWidget *scroll;
+
+ g_return_val_if_fail (obj, NULL);
+
+ self = GCR_KEY_WIDGET (obj);
+
+ self->pv->view = _gcr_display_view_new ();
+ _gcr_display_view_set_stock_image (self->pv->view, GTK_STOCK_DIALOG_AUTHENTICATION);
+
+ scroll = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_container_add (GTK_CONTAINER (scroll), GTK_WIDGET (self->pv->view));
+
+ gtk_container_add (GTK_CONTAINER (self), scroll);
+ gtk_widget_show_all (scroll);
+
+ refresh_display (self);
+
+ return obj;
+}
+
+static void
+gcr_key_widget_init (GcrKeyWidget *self)
+{
+ self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_KEY_WIDGET, GcrKeyWidgetPrivate));
+}
+
+static void
+gcr_key_widget_dispose (GObject *obj)
+{
+ G_OBJECT_CLASS (gcr_key_widget_parent_class)->dispose (obj);
+}
+
+static void
+gcr_key_widget_finalize (GObject *obj)
+{
+ GcrKeyWidget *self = GCR_KEY_WIDGET (obj);
+
+ 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_key_widget_parent_class)->finalize (obj);
+}
+
+static void
+gcr_key_widget_set_property (GObject *obj, guint prop_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ GcrKeyWidget *self = GCR_KEY_WIDGET (obj);
+
+ switch (prop_id) {
+ 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);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gcr_key_widget_get_property (GObject *obj, guint prop_id, GValue *value,
+ GParamSpec *pspec)
+{
+ GcrKeyWidget *self = GCR_KEY_WIDGET (obj);
+
+ switch (prop_id) {
+ case PROP_LABEL:
+ g_value_take_string (value, calculate_label (self));
+ 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;
+ }
+}
+
+static void
+gcr_key_widget_class_init (GcrKeyWidgetClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GP11Attributes *registered;
+
+ gcr_key_widget_parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (GcrKeyWidgetPrivate));
+
+ gobject_class->constructor = gcr_key_widget_constructor;
+ gobject_class->dispose = gcr_key_widget_dispose;
+ gobject_class->finalize = gcr_key_widget_finalize;
+ gobject_class->set_property = gcr_key_widget_set_property;
+ gobject_class->get_property = gcr_key_widget_get_property;
+
+ 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_PRIVATE_KEY);
+ gcr_view_register (GCR_TYPE_KEY_WIDGET, registered);
+ gp11_attributes_unref (registered);
+}
+
+static void
+gcr_view_iface_init (GcrViewIface *iface)
+{
+ /* Nothing to do */
+}
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC
+ */
+
+GcrKeyWidget*
+gcr_key_widget_new (const gchar *label, GP11Attributes *attrs)
+{
+ return g_object_new (GCR_TYPE_KEY_WIDGET, "label", label, "attributes", attrs, NULL);
+}
diff --git a/gcr/gcr-key-widget.h b/gcr/gcr-key-widget.h
new file mode 100644
index 0000000..0aeffac
--- /dev/null
+++ b/gcr/gcr-key-widget.h
@@ -0,0 +1,57 @@
+/*
+ * 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_KEY_WIDGET_H__
+#define __GCR_KEY_WIDGET_H__
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "gcr-types.h"
+
+G_BEGIN_DECLS
+
+#define GCR_TYPE_KEY_WIDGET (gcr_key_widget_get_type ())
+#define GCR_KEY_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_KEY_WIDGET, GcrKeyWidget))
+#define GCR_KEY_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_KEY_WIDGET, GcrKeyWidgetClass))
+#define GCR_IS_KEY_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_KEY_WIDGET))
+#define GCR_IS_KEY_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_KEY_WIDGET))
+#define GCR_KEY_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_KEY_WIDGET, GcrKeyWidgetClass))
+
+typedef struct _GcrKeyWidget GcrKeyWidget;
+typedef struct _GcrKeyWidgetClass GcrKeyWidgetClass;
+typedef struct _GcrKeyWidgetPrivate GcrKeyWidgetPrivate;
+
+struct _GcrKeyWidget {
+ GtkAlignment parent;
+ GcrKeyWidgetPrivate *pv;
+};
+
+struct _GcrKeyWidgetClass {
+ GtkAlignmentClass parent_class;
+};
+
+GType gcr_key_widget_get_type (void);
+
+GcrKeyWidget* gcr_key_widget_new (const gchar *label,
+ struct _GP11Attributes *attrs);
+
+G_END_DECLS
+
+#endif /* __GCR_KEY_WIDGET_H__ */
diff --git a/gcr/tests/.gitignore b/gcr/tests/.gitignore
index b3085f5..48d49ed 100644
--- a/gcr/tests/.gitignore
+++ b/gcr/tests/.gitignore
@@ -1 +1,2 @@
-/ui-test-details
+/ui-test-key
+/ui-test-certificate
diff --git a/gcr/tests/Makefile.am b/gcr/tests/Makefile.am
index d100859..77e039e 100644
--- a/gcr/tests/Makefile.am
+++ b/gcr/tests/Makefile.am
@@ -15,22 +15,35 @@ TESTING_FLAGS = \
include $(top_srcdir)/testing/testing.make
+EXTRA_DIST = \
+ test-data
+
# ------------------------------------------------------------------
noinst_PROGRAMS += \
- ui-test-details
+ ui-test-certificate \
+ ui-test-key
-ui_test_details_SOURCES = \
- ui-test-details.c
+ui_test_certificate_SOURCES = \
+ ui-test-certificate.c
-ui_test_details_CFLAGS = \
+ui_test_certificate_CFLAGS = \
-DGCR_API_SUBJECT_TO_CHANGE \
$(GTK_CFLAGS)
-
-ui_test_details_LDADD = \
+
+ui_test_certificate_LDADD = \
$(top_builddir)/gcr/libgcr.la \
$(GTK_LIBS) \
$(LIBGCRYPT_LIBS)
-EXTRA_DIST = \
- test-data
+ui_test_key_SOURCES = \
+ ui-test-key.c
+
+ui_test_key_CFLAGS = \
+ -DGCR_API_SUBJECT_TO_CHANGE \
+ $(GTK_CFLAGS)
+
+ui_test_key_LDADD = \
+ $(top_builddir)/gcr/libgcr.la \
+ $(GTK_LIBS) \
+ $(LIBGCRYPT_LIBS)
diff --git a/gcr/tests/ui-test-details.c b/gcr/tests/ui-test-certificate.c
similarity index 94%
copy from gcr/tests/ui-test-details.c
copy to gcr/tests/ui-test-certificate.c
index fdfb6b1..8711e7f 100644
--- a/gcr/tests/ui-test-details.c
+++ b/gcr/tests/ui-test-certificate.c
@@ -10,16 +10,16 @@
#include <string.h>
#include <errno.h>
-static void
+static void
chdir_base_dir (char* argv0)
{
gchar *dir, *base;
dir = g_path_get_dirname (argv0);
if (chdir (dir) < 0)
- g_warning ("couldn't change directory to: %s: %s",
+ g_warning ("couldn't change directory to: %s: %s",
dir, g_strerror (errno));
-
+
base = g_path_get_basename (dir);
if (strcmp (base, ".libs") == 0) {
if (chdir ("..") < 0)
@@ -39,24 +39,24 @@ test_details (const gchar *path)
GtkDialog *dialog;
guchar *data;
gsize n_data;
-
+
if (!g_file_get_contents (path, (gchar**)&data, &n_data, NULL))
g_error ("couldn't read file: %s", path);
-
+
certificate = gcr_simple_certificate_new (data, n_data);
g_assert (certificate);
g_free (data);
-
+
dialog = GTK_DIALOG (gtk_dialog_new ());
g_object_ref_sink (dialog);
-
+
details = gcr_certificate_widget_new (certificate);
gtk_widget_show (GTK_WIDGET (details));
gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (dialog)), GTK_WIDGET (details));
gtk_window_set_default_size (GTK_WINDOW (dialog), 550, 400);
gtk_dialog_run (dialog);
-
+
g_object_unref (dialog);
g_object_unref (certificate);
g_object_unref (details);
@@ -66,13 +66,13 @@ int
main(int argc, char *argv[])
{
gtk_init (&argc, &argv);
-
+
if (argc > 1) {
test_details (argv[1]);
} else {
chdir_base_dir (argv[0]);
test_details ("test-data/der-certificate.crt");
}
-
+
return 0;
}
diff --git a/gcr/tests/ui-test-details.c b/gcr/tests/ui-test-key.c
similarity index 60%
rename from gcr/tests/ui-test-details.c
rename to gcr/tests/ui-test-key.c
index fdfb6b1..2d2403d 100644
--- a/gcr/tests/ui-test-details.c
+++ b/gcr/tests/ui-test-key.c
@@ -1,8 +1,8 @@
#include "config.h"
-#include "gcr-certificate-widget.h"
-#include "gcr-simple-certificate.h"
+#include "gcr-key-widget.h"
+#include "gcr-parser.h"
#include <gtk/gtk.h>
@@ -10,16 +10,16 @@
#include <string.h>
#include <errno.h>
-static void
+static void
chdir_base_dir (char* argv0)
{
gchar *dir, *base;
dir = g_path_get_dirname (argv0);
if (chdir (dir) < 0)
- g_warning ("couldn't change directory to: %s: %s",
+ g_warning ("couldn't change directory to: %s: %s",
dir, g_strerror (errno));
-
+
base = g_path_get_basename (dir);
if (strcmp (base, ".libs") == 0) {
if (chdir ("..") < 0)
@@ -32,47 +32,57 @@ chdir_base_dir (char* argv0)
}
static void
-test_details (const gchar *path)
+on_parser_parsed (GcrParser *parser, gpointer unused)
{
- GcrCertificateWidget *details;
- GcrCertificate *certificate;
+ GcrKeyWidget *details;
GtkDialog *dialog;
- guchar *data;
- gsize n_data;
-
- if (!g_file_get_contents (path, (gchar**)&data, &n_data, NULL))
- g_error ("couldn't read file: %s", path);
-
- certificate = gcr_simple_certificate_new (data, n_data);
- g_assert (certificate);
- g_free (data);
-
+
dialog = GTK_DIALOG (gtk_dialog_new ());
g_object_ref_sink (dialog);
-
- details = gcr_certificate_widget_new (certificate);
+
+ details = gcr_key_widget_new (gcr_parser_get_parsed_label (parser),
+ gcr_parser_get_parsed_attributes (parser));
gtk_widget_show (GTK_WIDGET (details));
gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (dialog)), GTK_WIDGET (details));
gtk_window_set_default_size (GTK_WINDOW (dialog), 550, 400);
gtk_dialog_run (dialog);
-
+
g_object_unref (dialog);
- g_object_unref (certificate);
g_object_unref (details);
}
+static void
+test_key (const gchar *path)
+{
+ GcrParser *parser;
+ GError *err = NULL;
+ guchar *data;
+ gsize n_data;
+
+ if (!g_file_get_contents (path, (gchar**)&data, &n_data, NULL))
+ g_error ("couldn't read file: %s", path);
+
+ parser = gcr_parser_new ();
+ g_signal_connect (parser, "parsed", G_CALLBACK (on_parser_parsed), NULL);
+ if (!gcr_parser_parse_data (parser, data, n_data, &err))
+ g_error ("couldn't parse data: %s", err->message);
+
+ g_object_unref (parser);
+ g_free (data);
+}
+
int
main(int argc, char *argv[])
{
gtk_init (&argc, &argv);
-
+
if (argc > 1) {
- test_details (argv[1]);
+ test_key (argv[1]);
} else {
chdir_base_dir (argv[0]);
- test_details ("test-data/der-certificate.crt");
+ test_key ("test-data/pem-dsa-1024.key");
}
-
+
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]